summaryrefslogtreecommitdiff
path: root/Source/WebCore/html
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2015-05-20 09:56:07 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2015-05-20 09:56:07 +0000
commit41386e9cb918eed93b3f13648cbef387e371e451 (patch)
treea97f9d7bd1d9d091833286085f72da9d83fd0606 /Source/WebCore/html
parente15dd966d523731101f70ccf768bba12435a0208 (diff)
downloadWebKitGtk-tarball-41386e9cb918eed93b3f13648cbef387e371e451.tar.gz
webkitgtk-2.4.9webkitgtk-2.4.9
Diffstat (limited to 'Source/WebCore/html')
-rw-r--r--Source/WebCore/html/Autocapitalize.cpp107
-rw-r--r--Source/WebCore/html/BaseButtonInputType.cpp4
-rw-r--r--Source/WebCore/html/BaseButtonInputType.h2
-rw-r--r--Source/WebCore/html/BaseChooserOnlyDateAndTimeInputType.cpp12
-rw-r--r--Source/WebCore/html/BaseDateAndTimeInputType.cpp3
-rw-r--r--Source/WebCore/html/ButtonInputType.h2
-rw-r--r--Source/WebCore/html/CheckboxInputType.h2
-rw-r--r--Source/WebCore/html/ColorInputType.cpp17
-rw-r--r--Source/WebCore/html/ColorInputType.h5
-rw-r--r--Source/WebCore/html/DOMFormData.h4
-rw-r--r--Source/WebCore/html/DOMSettableTokenList.cpp5
-rw-r--r--Source/WebCore/html/DOMSettableTokenList.h21
-rw-r--r--Source/WebCore/html/DOMURL.cpp98
-rw-r--r--Source/WebCore/html/DOMURL.h23
-rw-r--r--Source/WebCore/html/DOMURL.idl12
-rw-r--r--Source/WebCore/html/DateInputType.cpp7
-rw-r--r--Source/WebCore/html/DateInputType.h3
-rw-r--r--Source/WebCore/html/DateTimeInputType.cpp7
-rw-r--r--Source/WebCore/html/DateTimeInputType.h3
-rw-r--r--Source/WebCore/html/DateTimeLocalInputType.cpp7
-rw-r--r--Source/WebCore/html/DateTimeLocalInputType.h5
-rw-r--r--Source/WebCore/html/EmailInputType.cpp10
-rw-r--r--Source/WebCore/html/EmailInputType.h3
-rw-r--r--Source/WebCore/html/FTPDirectoryDocument.cpp102
-rw-r--r--Source/WebCore/html/FTPDirectoryDocument.h12
-rw-r--r--Source/WebCore/html/FileInputType.cpp107
-rw-r--r--Source/WebCore/html/FileInputType.h7
-rw-r--r--Source/WebCore/html/FormAssociatedElement.cpp9
-rw-r--r--Source/WebCore/html/FormAssociatedElement.h4
-rw-r--r--Source/WebCore/html/FormController.cpp59
-rw-r--r--Source/WebCore/html/FormController.h16
-rw-r--r--Source/WebCore/html/FormDataList.cpp3
-rw-r--r--Source/WebCore/html/HTMLAllCollection.cpp29
-rw-r--r--Source/WebCore/html/HTMLAllCollection.h7
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.cpp97
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.h27
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.idl7
-rw-r--r--Source/WebCore/html/HTMLAppletElement.cpp36
-rw-r--r--Source/WebCore/html/HTMLAppletElement.h6
-rw-r--r--Source/WebCore/html/HTMLAreaElement.cpp36
-rw-r--r--Source/WebCore/html/HTMLAreaElement.h6
-rw-r--r--Source/WebCore/html/HTMLAreaElement.idl3
-rw-r--r--Source/WebCore/html/HTMLAttachmentElement.cpp95
-rw-r--r--Source/WebCore/html/HTMLAttachmentElement.h61
-rw-r--r--Source/WebCore/html/HTMLAttachmentElement.idl30
-rw-r--r--Source/WebCore/html/HTMLAttributeNames.in24
-rw-r--r--Source/WebCore/html/HTMLAudioElement.cpp16
-rw-r--r--Source/WebCore/html/HTMLAudioElement.h22
-rw-r--r--Source/WebCore/html/HTMLAudioElement.idl4
-rw-r--r--Source/WebCore/html/HTMLBDIElement.h4
-rw-r--r--Source/WebCore/html/HTMLBRElement.cpp15
-rw-r--r--Source/WebCore/html/HTMLBRElement.h6
-rw-r--r--Source/WebCore/html/HTMLBaseElement.cpp5
-rw-r--r--Source/WebCore/html/HTMLBaseElement.h4
-rw-r--r--Source/WebCore/html/HTMLBaseFontElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLBaseFontElement.h2
-rw-r--r--Source/WebCore/html/HTMLBodyElement.cpp251
-rw-r--r--Source/WebCore/html/HTMLBodyElement.h38
-rw-r--r--Source/WebCore/html/HTMLBodyElement.idl43
-rw-r--r--Source/WebCore/html/HTMLButtonElement.cpp48
-rw-r--r--Source/WebCore/html/HTMLButtonElement.h8
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.cpp162
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.h47
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.idl7
-rw-r--r--Source/WebCore/html/HTMLCollection.cpp311
-rw-r--r--Source/WebCore/html/HTMLCollection.h251
-rw-r--r--Source/WebCore/html/HTMLCollection.idl1
-rw-r--r--Source/WebCore/html/HTMLDListElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLDListElement.h2
-rw-r--r--Source/WebCore/html/HTMLDataListElement.cpp8
-rw-r--r--Source/WebCore/html/HTMLDataListElement.h6
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.cpp46
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.h11
-rw-r--r--Source/WebCore/html/HTMLDirectoryElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLDirectoryElement.h2
-rw-r--r--Source/WebCore/html/HTMLDivElement.cpp9
-rw-r--r--Source/WebCore/html/HTMLDivElement.h4
-rw-r--r--Source/WebCore/html/HTMLDocument.cpp103
-rw-r--r--Source/WebCore/html/HTMLDocument.h32
-rw-r--r--Source/WebCore/html/HTMLDocument.idl6
-rw-r--r--Source/WebCore/html/HTMLElement.cpp486
-rw-r--r--Source/WebCore/html/HTMLElement.h53
-rw-r--r--Source/WebCore/html/HTMLElement.idl12
-rw-r--r--Source/WebCore/html/HTMLElementsAllInOne.cpp115
-rw-r--r--Source/WebCore/html/HTMLEmbedElement.cpp61
-rw-r--r--Source/WebCore/html/HTMLEmbedElement.h6
-rw-r--r--Source/WebCore/html/HTMLEmbedElement.idl2
-rw-r--r--Source/WebCore/html/HTMLFieldSetElement.cpp123
-rw-r--r--Source/WebCore/html/HTMLFieldSetElement.h25
-rw-r--r--Source/WebCore/html/HTMLFieldSetElement.idl2
-rw-r--r--Source/WebCore/html/HTMLFontElement.cpp5
-rw-r--r--Source/WebCore/html/HTMLFontElement.h2
-rw-r--r--Source/WebCore/html/HTMLFormControlElement.cpp255
-rw-r--r--Source/WebCore/html/HTMLFormControlElement.h58
-rw-r--r--Source/WebCore/html/HTMLFormControlElementWithState.cpp10
-rw-r--r--Source/WebCore/html/HTMLFormControlElementWithState.h1
-rw-r--r--Source/WebCore/html/HTMLFormControlsCollection.cpp84
-rw-r--r--Source/WebCore/html/HTMLFormControlsCollection.h21
-rw-r--r--Source/WebCore/html/HTMLFormElement.cpp223
-rw-r--r--Source/WebCore/html/HTMLFormElement.h46
-rw-r--r--Source/WebCore/html/HTMLFormElement.idl2
-rw-r--r--Source/WebCore/html/HTMLFrameElement.cpp11
-rw-r--r--Source/WebCore/html/HTMLFrameElement.h10
-rw-r--r--Source/WebCore/html/HTMLFrameElement.idl2
-rw-r--r--Source/WebCore/html/HTMLFrameElementBase.cpp22
-rw-r--r--Source/WebCore/html/HTMLFrameElementBase.h38
-rw-r--r--Source/WebCore/html/HTMLFrameOwnerElement.cpp39
-rw-r--r--Source/WebCore/html/HTMLFrameOwnerElement.h16
-rw-r--r--Source/WebCore/html/HTMLFrameSetElement.cpp103
-rw-r--r--Source/WebCore/html/HTMLFrameSetElement.h25
-rw-r--r--Source/WebCore/html/HTMLFrameSetElement.idl38
-rw-r--r--Source/WebCore/html/HTMLHRElement.cpp16
-rw-r--r--Source/WebCore/html/HTMLHRElement.h7
-rw-r--r--Source/WebCore/html/HTMLHeadElement.cpp8
-rw-r--r--Source/WebCore/html/HTMLHeadElement.h4
-rw-r--r--Source/WebCore/html/HTMLHeadingElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLHeadingElement.h2
-rw-r--r--Source/WebCore/html/HTMLHtmlElement.cpp10
-rw-r--r--Source/WebCore/html/HTMLHtmlElement.h6
-rw-r--r--Source/WebCore/html/HTMLIFrameElement.cpp32
-rw-r--r--Source/WebCore/html/HTMLIFrameElement.h10
-rw-r--r--Source/WebCore/html/HTMLIFrameElement.idl3
-rw-r--r--Source/WebCore/html/HTMLImageElement.cpp215
-rw-r--r--Source/WebCore/html/HTMLImageElement.h38
-rw-r--r--Source/WebCore/html/HTMLImageElement.idl6
-rw-r--r--Source/WebCore/html/HTMLImageLoader.cpp34
-rw-r--r--Source/WebCore/html/HTMLImageLoader.h6
-rw-r--r--Source/WebCore/html/HTMLInputElement.cpp411
-rw-r--r--Source/WebCore/html/HTMLInputElement.h245
-rw-r--r--Source/WebCore/html/HTMLInputElement.idl12
-rw-r--r--Source/WebCore/html/HTMLKeygenElement.cpp18
-rw-r--r--Source/WebCore/html/HTMLKeygenElement.h9
-rw-r--r--Source/WebCore/html/HTMLLIElement.cpp39
-rw-r--r--Source/WebCore/html/HTMLLIElement.h4
-rw-r--r--Source/WebCore/html/HTMLLabelElement.cpp10
-rw-r--r--Source/WebCore/html/HTMLLabelElement.h4
-rw-r--r--Source/WebCore/html/HTMLLegendElement.cpp10
-rw-r--r--Source/WebCore/html/HTMLLegendElement.h4
-rw-r--r--Source/WebCore/html/HTMLLinkElement.cpp143
-rw-r--r--Source/WebCore/html/HTMLLinkElement.h24
-rw-r--r--Source/WebCore/html/HTMLLinkElement.idl6
-rw-r--r--Source/WebCore/html/HTMLMapElement.cpp14
-rw-r--r--Source/WebCore/html/HTMLMapElement.h8
-rw-r--r--Source/WebCore/html/HTMLMarqueeElement.cpp10
-rw-r--r--Source/WebCore/html/HTMLMarqueeElement.h9
-rw-r--r--Source/WebCore/html/HTMLMarqueeElement.idl6
-rw-r--r--Source/WebCore/html/HTMLMediaElement.cpp2936
-rw-r--r--Source/WebCore/html/HTMLMediaElement.h545
-rw-r--r--Source/WebCore/html/HTMLMediaElement.idl51
-rw-r--r--Source/WebCore/html/HTMLMediaElementEnums.h56
-rw-r--r--Source/WebCore/html/HTMLMediaSession.cpp189
-rw-r--r--Source/WebCore/html/HTMLMediaSession.h83
-rw-r--r--Source/WebCore/html/HTMLMediaSource.cpp (renamed from Source/WebCore/html/parser/ParsingUtilities.h)53
-rw-r--r--Source/WebCore/html/HTMLMediaSource.h76
-rw-r--r--Source/WebCore/html/HTMLMenuElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLMenuElement.h2
-rw-r--r--Source/WebCore/html/HTMLMetaElement.cpp20
-rw-r--r--Source/WebCore/html/HTMLMetaElement.h10
-rw-r--r--Source/WebCore/html/HTMLMeterElement.cpp18
-rw-r--r--Source/WebCore/html/HTMLMeterElement.h8
-rw-r--r--Source/WebCore/html/HTMLMeterElement.idl12
-rw-r--r--Source/WebCore/html/HTMLModElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLModElement.h2
-rw-r--r--Source/WebCore/html/HTMLNameCollection.cpp44
-rw-r--r--Source/WebCore/html/HTMLNameCollection.h32
-rw-r--r--Source/WebCore/html/HTMLOListElement.cpp13
-rw-r--r--Source/WebCore/html/HTMLOListElement.h6
-rw-r--r--Source/WebCore/html/HTMLObjectElement.cpp139
-rw-r--r--Source/WebCore/html/HTMLObjectElement.h48
-rw-r--r--Source/WebCore/html/HTMLObjectElement.idl2
-rw-r--r--Source/WebCore/html/HTMLOptGroupElement.cpp60
-rw-r--r--Source/WebCore/html/HTMLOptGroupElement.h17
-rw-r--r--Source/WebCore/html/HTMLOptionElement.cpp91
-rw-r--r--Source/WebCore/html/HTMLOptionElement.h22
-rw-r--r--Source/WebCore/html/HTMLOptionsCollection.cpp31
-rw-r--r--Source/WebCore/html/HTMLOptionsCollection.h16
-rw-r--r--Source/WebCore/html/HTMLOptionsCollection.idl8
-rw-r--r--Source/WebCore/html/HTMLOutputElement.cpp11
-rw-r--r--Source/WebCore/html/HTMLOutputElement.h9
-rw-r--r--Source/WebCore/html/HTMLParagraphElement.cpp9
-rw-r--r--Source/WebCore/html/HTMLParagraphElement.h4
-rw-r--r--Source/WebCore/html/HTMLParamElement.cpp5
-rw-r--r--Source/WebCore/html/HTMLParamElement.h4
-rw-r--r--Source/WebCore/html/HTMLParserErrorCodes.cpp (renamed from Source/WebCore/html/canvas/WebGLSync.idl)13
-rw-r--r--Source/WebCore/html/HTMLParserErrorCodes.h (renamed from Source/WebCore/html/canvas/WebGLQuery.idl)11
-rw-r--r--Source/WebCore/html/HTMLParserQuirks.h (renamed from Source/WebCore/html/canvas/EXTShaderTextureLOD.idl)13
-rw-r--r--Source/WebCore/html/HTMLPlugInElement.cpp92
-rw-r--r--Source/WebCore/html/HTMLPlugInElement.h26
-rw-r--r--Source/WebCore/html/HTMLPlugInImageElement.cpp282
-rw-r--r--Source/WebCore/html/HTMLPlugInImageElement.h101
-rw-r--r--Source/WebCore/html/HTMLPreElement.cpp5
-rw-r--r--Source/WebCore/html/HTMLPreElement.h2
-rw-r--r--Source/WebCore/html/HTMLProgressElement.cpp27
-rw-r--r--Source/WebCore/html/HTMLProgressElement.h9
-rw-r--r--Source/WebCore/html/HTMLProgressElement.idl10
-rw-r--r--Source/WebCore/html/HTMLQuoteElement.cpp12
-rw-r--r--Source/WebCore/html/HTMLQuoteElement.h3
-rw-r--r--Source/WebCore/html/HTMLScriptElement.cpp39
-rw-r--r--Source/WebCore/html/HTMLScriptElement.h7
-rw-r--r--Source/WebCore/html/HTMLSelectElement.cpp455
-rw-r--r--Source/WebCore/html/HTMLSelectElement.h32
-rw-r--r--Source/WebCore/html/HTMLSelectElement.idl4
-rw-r--r--Source/WebCore/html/HTMLSelectElementWin.cpp61
-rw-r--r--Source/WebCore/html/HTMLSourceElement.cpp58
-rw-r--r--Source/WebCore/html/HTMLSourceElement.h22
-rw-r--r--Source/WebCore/html/HTMLSourceElement.idl4
-rw-r--r--Source/WebCore/html/HTMLSpanElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLSpanElement.h4
-rw-r--r--Source/WebCore/html/HTMLStyleElement.cpp11
-rw-r--r--Source/WebCore/html/HTMLStyleElement.h6
-rw-r--r--Source/WebCore/html/HTMLSummaryElement.cpp51
-rw-r--r--Source/WebCore/html/HTMLSummaryElement.h9
-rw-r--r--Source/WebCore/html/HTMLTableCaptionElement.cpp5
-rw-r--r--Source/WebCore/html/HTMLTableCaptionElement.h4
-rw-r--r--Source/WebCore/html/HTMLTableCellElement.cpp25
-rw-r--r--Source/WebCore/html/HTMLTableCellElement.h13
-rw-r--r--Source/WebCore/html/HTMLTableColElement.cpp26
-rw-r--r--Source/WebCore/html/HTMLTableColElement.h2
-rw-r--r--Source/WebCore/html/HTMLTableElement.cpp77
-rw-r--r--Source/WebCore/html/HTMLTableElement.h27
-rw-r--r--Source/WebCore/html/HTMLTableElement.idl2
-rw-r--r--Source/WebCore/html/HTMLTablePartElement.cpp7
-rw-r--r--Source/WebCore/html/HTMLTableRowElement.cpp32
-rw-r--r--Source/WebCore/html/HTMLTableRowElement.h11
-rw-r--r--Source/WebCore/html/HTMLTableRowElement.idl2
-rw-r--r--Source/WebCore/html/HTMLTableRowsCollection.cpp71
-rw-r--r--Source/WebCore/html/HTMLTableRowsCollection.h18
-rw-r--r--Source/WebCore/html/HTMLTableSectionElement.cpp40
-rw-r--r--Source/WebCore/html/HTMLTableSectionElement.h35
-rw-r--r--Source/WebCore/html/HTMLTableSectionElement.idl2
-rw-r--r--Source/WebCore/html/HTMLTagNames.in102
-rw-r--r--Source/WebCore/html/HTMLTemplateElement.cpp27
-rw-r--r--Source/WebCore/html/HTMLTemplateElement.h6
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.cpp53
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.h12
-rw-r--r--Source/WebCore/html/HTMLTextFormControlElement.cpp350
-rw-r--r--Source/WebCore/html/HTMLTextFormControlElement.h62
-rw-r--r--Source/WebCore/html/HTMLTitleElement.cpp53
-rw-r--r--Source/WebCore/html/HTMLTitleElement.h8
-rw-r--r--Source/WebCore/html/HTMLTitleElement.idl2
-rw-r--r--Source/WebCore/html/HTMLTrackElement.cpp24
-rw-r--r--Source/WebCore/html/HTMLTrackElement.h12
-rw-r--r--Source/WebCore/html/HTMLTrackElement.idl4
-rw-r--r--Source/WebCore/html/HTMLUListElement.cpp9
-rw-r--r--Source/WebCore/html/HTMLUListElement.h4
-rw-r--r--Source/WebCore/html/HTMLUnknownElement.h16
-rw-r--r--Source/WebCore/html/HTMLVideoElement.cpp184
-rw-r--r--Source/WebCore/html/HTMLVideoElement.h43
-rw-r--r--Source/WebCore/html/HTMLVideoElement.idl21
-rw-r--r--Source/WebCore/html/HTMLViewSourceDocument.cpp294
-rw-r--r--Source/WebCore/html/HTMLViewSourceDocument.h73
-rw-r--r--Source/WebCore/html/HTMLWBRElement.cpp52
-rw-r--r--Source/WebCore/html/HTMLWBRElement.h46
-rw-r--r--Source/WebCore/html/HiddenInputType.cpp2
-rw-r--r--Source/WebCore/html/HiddenInputType.h4
-rw-r--r--Source/WebCore/html/ImageData.cpp56
-rw-r--r--Source/WebCore/html/ImageData.h6
-rw-r--r--Source/WebCore/html/ImageData.idl9
-rw-r--r--Source/WebCore/html/ImageDocument.cpp366
-rw-r--r--Source/WebCore/html/ImageDocument.h69
-rw-r--r--Source/WebCore/html/ImageInputType.cpp48
-rw-r--r--Source/WebCore/html/ImageInputType.h4
-rw-r--r--Source/WebCore/html/InputType.cpp45
-rw-r--r--Source/WebCore/html/InputType.h22
-rw-r--r--Source/WebCore/html/InputTypeNames.cpp46
-rw-r--r--Source/WebCore/html/LabelableElement.cpp2
-rw-r--r--Source/WebCore/html/LabelableElement.h12
-rw-r--r--Source/WebCore/html/LabelsNodeList.cpp8
-rw-r--r--Source/WebCore/html/LabelsNodeList.h14
-rw-r--r--Source/WebCore/html/LinkRelAttribute.cpp63
-rw-r--r--Source/WebCore/html/LinkRelAttribute.h17
-rw-r--r--Source/WebCore/html/MediaController.cpp57
-rw-r--r--Source/WebCore/html/MediaController.h20
-rw-r--r--Source/WebCore/html/MediaController.idl24
-rw-r--r--Source/WebCore/html/MediaControllerInterface.h18
-rw-r--r--Source/WebCore/html/MediaDocument.cpp102
-rw-r--r--Source/WebCore/html/MediaDocument.h23
-rw-r--r--Source/WebCore/html/MediaElementSession.cpp457
-rw-r--r--Source/WebCore/html/MediaElementSession.h135
-rw-r--r--Source/WebCore/html/MediaError.h6
-rw-r--r--Source/WebCore/html/MediaError.idl4
-rw-r--r--Source/WebCore/html/MediaFragmentURIParser.cpp49
-rw-r--r--Source/WebCore/html/MediaFragmentURIParser.h19
-rw-r--r--Source/WebCore/html/MediaKeyError.h6
-rw-r--r--Source/WebCore/html/MediaKeyError.idl4
-rw-r--r--Source/WebCore/html/MediaKeyEvent.cpp4
-rw-r--r--Source/WebCore/html/MediaKeyEvent.h14
-rw-r--r--Source/WebCore/html/MediaKeyEvent.idl4
-rw-r--r--Source/WebCore/html/MonthInputType.cpp7
-rw-r--r--Source/WebCore/html/MonthInputType.h3
-rw-r--r--Source/WebCore/html/NumberInputType.cpp13
-rw-r--r--Source/WebCore/html/NumberInputType.h4
-rw-r--r--Source/WebCore/html/PasswordInputType.cpp5
-rw-r--r--Source/WebCore/html/PasswordInputType.h3
-rw-r--r--Source/WebCore/html/PluginDocument.cpp30
-rw-r--r--Source/WebCore/html/PluginDocument.h22
-rw-r--r--Source/WebCore/html/PublicURLManager.cpp36
-rw-r--r--Source/WebCore/html/PublicURLManager.h19
-rw-r--r--Source/WebCore/html/RadioInputType.cpp14
-rw-r--r--Source/WebCore/html/RadioInputType.h2
-rw-r--r--Source/WebCore/html/RadioNodeList.cpp26
-rw-r--r--Source/WebCore/html/RadioNodeList.h15
-rw-r--r--Source/WebCore/html/RangeInputType.cpp28
-rw-r--r--Source/WebCore/html/RangeInputType.h3
-rw-r--r--Source/WebCore/html/RelList.cpp87
-rw-r--r--Source/WebCore/html/RelList.h57
-rw-r--r--Source/WebCore/html/ResetInputType.h2
-rw-r--r--Source/WebCore/html/RubyElement.cpp55
-rw-r--r--Source/WebCore/html/RubyElement.h44
-rw-r--r--Source/WebCore/html/RubyTextElement.cpp56
-rw-r--r--Source/WebCore/html/RubyTextElement.h44
-rw-r--r--Source/WebCore/html/SearchInputType.cpp55
-rw-r--r--Source/WebCore/html/SearchInputType.h17
-rw-r--r--Source/WebCore/html/StepRange.cpp6
-rw-r--r--Source/WebCore/html/SubmitInputType.h2
-rw-r--r--Source/WebCore/html/TelephoneInputType.cpp11
-rw-r--r--Source/WebCore/html/TelephoneInputType.h4
-rw-r--r--Source/WebCore/html/TextDocument.cpp10
-rw-r--r--Source/WebCore/html/TextDocument.h10
-rw-r--r--Source/WebCore/html/TextFieldInputType.cpp265
-rw-r--r--Source/WebCore/html/TextFieldInputType.h90
-rw-r--r--Source/WebCore/html/TextInputType.cpp15
-rw-r--r--Source/WebCore/html/TextInputType.h4
-rw-r--r--Source/WebCore/html/TextMetrics.h4
-rw-r--r--Source/WebCore/html/TextMetrics.idl2
-rw-r--r--Source/WebCore/html/TimeInputType.cpp7
-rw-r--r--Source/WebCore/html/TimeInputType.h3
-rw-r--r--Source/WebCore/html/TimeRanges.cpp190
-rw-r--r--Source/WebCore/html/TimeRanges.h92
-rw-r--r--Source/WebCore/html/TimeRanges.idl8
-rw-r--r--Source/WebCore/html/URLInputType.cpp6
-rw-r--r--Source/WebCore/html/URLInputType.h3
-rw-r--r--Source/WebCore/html/URLUtils.h296
-rw-r--r--Source/WebCore/html/URLUtils.idl45
-rw-r--r--Source/WebCore/html/ValidationMessage.cpp44
-rw-r--r--Source/WebCore/html/ValidationMessage.h14
-rw-r--r--Source/WebCore/html/VoidCallback.h4
-rw-r--r--Source/WebCore/html/VoidCallback.idl4
-rw-r--r--Source/WebCore/html/WeekInputType.cpp7
-rw-r--r--Source/WebCore/html/WeekInputType.h3
-rw-r--r--Source/WebCore/html/canvas/ANGLEInstancedArrays.cpp20
-rw-r--r--Source/WebCore/html/canvas/ANGLEInstancedArrays.h13
-rw-r--r--Source/WebCore/html/canvas/CanvasGradient.cpp4
-rw-r--r--Source/WebCore/html/canvas/CanvasGradient.h20
-rw-r--r--Source/WebCore/html/canvas/CanvasGradient.idl6
-rw-r--r--Source/WebCore/html/canvas/CanvasPathMethods.cpp84
-rw-r--r--Source/WebCore/html/canvas/CanvasPathMethods.h3
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.cpp8
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.h13
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.idl6
-rw-r--r--Source/WebCore/html/canvas/CanvasProxy.cpp4
-rw-r--r--Source/WebCore/html/canvas/CanvasProxy.h2
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.cpp9
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.h12
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.idl4
-rwxr-xr-x[-rw-r--r--]Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp677
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.h129
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.idl166
-rw-r--r--Source/WebCore/html/canvas/CanvasStyle.cpp4
-rw-r--r--Source/WebCore/html/canvas/CanvasStyle.h4
-rw-r--r--Source/WebCore/html/canvas/DOMPath.cpp37
-rw-r--r--Source/WebCore/html/canvas/DOMPath.h34
-rw-r--r--Source/WebCore/html/canvas/DOMPath.idl23
-rw-r--r--Source/WebCore/html/canvas/EXTBlendMinMax.cpp49
-rw-r--r--Source/WebCore/html/canvas/EXTBlendMinMax.h43
-rw-r--r--Source/WebCore/html/canvas/EXTBlendMinMax.idl33
-rw-r--r--Source/WebCore/html/canvas/EXTDrawBuffers.cpp (renamed from Source/WebCore/html/canvas/WebGLDrawBuffers.cpp)44
-rw-r--r--Source/WebCore/html/canvas/EXTDrawBuffers.h (renamed from Source/WebCore/html/canvas/WebGLDrawBuffers.h)21
-rw-r--r--Source/WebCore/html/canvas/EXTDrawBuffers.idl72
-rw-r--r--Source/WebCore/html/canvas/EXTFragDepth.cpp49
-rw-r--r--Source/WebCore/html/canvas/EXTFragDepth.h43
-rw-r--r--Source/WebCore/html/canvas/EXTFragDepth.idl31
-rw-r--r--Source/WebCore/html/canvas/EXTShaderTextureLOD.cpp49
-rw-r--r--Source/WebCore/html/canvas/EXTShaderTextureLOD.h43
-rw-r--r--Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.cpp7
-rw-r--r--Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.h10
-rw-r--r--Source/WebCore/html/canvas/EXTsRGB.cpp49
-rw-r--r--Source/WebCore/html/canvas/EXTsRGB.h43
-rw-r--r--Source/WebCore/html/canvas/EXTsRGB.idl35
-rw-r--r--Source/WebCore/html/canvas/OESElementIndexUint.cpp7
-rw-r--r--Source/WebCore/html/canvas/OESElementIndexUint.h10
-rw-r--r--Source/WebCore/html/canvas/OESStandardDerivatives.cpp7
-rw-r--r--Source/WebCore/html/canvas/OESStandardDerivatives.h10
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloat.cpp7
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloat.h10
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloatLinear.cpp7
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloatLinear.h10
-rw-r--r--Source/WebCore/html/canvas/OESTextureHalfFloat.cpp7
-rw-r--r--Source/WebCore/html/canvas/OESTextureHalfFloat.h10
-rw-r--r--Source/WebCore/html/canvas/OESTextureHalfFloatLinear.cpp7
-rw-r--r--Source/WebCore/html/canvas/OESTextureHalfFloatLinear.h10
-rw-r--r--Source/WebCore/html/canvas/OESVertexArrayObject.cpp24
-rw-r--r--Source/WebCore/html/canvas/OESVertexArrayObject.h16
-rw-r--r--Source/WebCore/html/canvas/OESVertexArrayObject.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGL2RenderingContext.cpp2510
-rw-r--r--Source/WebCore/html/canvas/WebGL2RenderingContext.h225
-rw-r--r--Source/WebCore/html/canvas/WebGL2RenderingContext.idl456
-rw-r--r--Source/WebCore/html/canvas/WebGLActiveInfo.h4
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.cpp20
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.h12
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextureATC.cpp9
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextureATC.h12
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.cpp11
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.h13
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.cpp11
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.h12
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.cpp8
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.h7
-rw-r--r--Source/WebCore/html/canvas/WebGLContextEvent.h14
-rw-r--r--Source/WebCore/html/canvas/WebGLContextGroup.cpp21
-rw-r--r--Source/WebCore/html/canvas/WebGLContextGroup.h23
-rw-r--r--Source/WebCore/html/canvas/WebGLContextObject.cpp8
-rw-r--r--Source/WebCore/html/canvas/WebGLContextObject.h14
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp9
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugRendererInfo.h10
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugShaders.cpp9
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugShaders.h10
-rw-r--r--Source/WebCore/html/canvas/WebGLDepthTexture.cpp7
-rw-r--r--Source/WebCore/html/canvas/WebGLDepthTexture.h10
-rw-r--r--Source/WebCore/html/canvas/WebGLDrawBuffers.idl72
-rw-r--r--Source/WebCore/html/canvas/WebGLExtension.cpp2
-rw-r--r--Source/WebCore/html/canvas/WebGLExtension.h14
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.cpp42
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.h12
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLGetInfo.cpp61
-rw-r--r--Source/WebCore/html/canvas/WebGLGetInfo.h23
-rw-r--r--Source/WebCore/html/canvas/WebGLLoseContext.cpp11
-rw-r--r--Source/WebCore/html/canvas/WebGLLoseContext.h12
-rw-r--r--Source/WebCore/html/canvas/WebGLObject.cpp9
-rw-r--r--Source/WebCore/html/canvas/WebGLObject.h10
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.cpp22
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.h11
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLQuery.cpp61
-rw-r--r--Source/WebCore/html/canvas/WebGLQuery.h52
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.cpp12
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.h11
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.cpp6194
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.h816
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.idl646
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp5093
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContextBase.h842
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContextBase.idl674
-rw-r--r--Source/WebCore/html/canvas/WebGLSampler.cpp61
-rw-r--r--Source/WebCore/html/canvas/WebGLSampler.h52
-rw-r--r--Source/WebCore/html/canvas/WebGLSampler.idl29
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.cpp12
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.h12
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.cpp4
-rw-r--r--Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.h3
-rw-r--r--Source/WebCore/html/canvas/WebGLSharedObject.cpp8
-rw-r--r--Source/WebCore/html/canvas/WebGLSharedObject.h16
-rw-r--r--Source/WebCore/html/canvas/WebGLSync.cpp61
-rw-r--r--Source/WebCore/html/canvas/WebGLSync.h52
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.cpp21
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.h15
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.idl4
-rw-r--r--Source/WebCore/html/canvas/WebGLTransformFeedback.cpp61
-rw-r--r--Source/WebCore/html/canvas/WebGLTransformFeedback.h52
-rw-r--r--Source/WebCore/html/canvas/WebGLTransformFeedback.idl29
-rw-r--r--Source/WebCore/html/canvas/WebGLUniformLocation.cpp8
-rw-r--r--Source/WebCore/html/canvas/WebGLUniformLocation.h11
-rw-r--r--Source/WebCore/html/canvas/WebGLUniformLocation.idl7
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObject.cpp80
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObject.h56
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObject.idl29
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.cpp111
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.h101
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp90
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h72
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl4
-rw-r--r--Source/WebCore/html/forms/FileIconLoader.cpp2
-rw-r--r--Source/WebCore/html/forms/FileIconLoader.h4
-rw-r--r--Source/WebCore/html/parser/AtomicHTMLToken.h330
-rw-r--r--Source/WebCore/html/parser/HTMLConstructionSite.cpp192
-rw-r--r--Source/WebCore/html/parser/HTMLConstructionSite.h22
-rw-r--r--Source/WebCore/html/parser/HTMLDocumentParser.cpp213
-rw-r--r--Source/WebCore/html/parser/HTMLDocumentParser.h127
-rw-r--r--Source/WebCore/html/parser/HTMLElementStack.cpp256
-rw-r--r--Source/WebCore/html/parser/HTMLElementStack.h40
-rw-r--r--Source/WebCore/html/parser/HTMLEntityParser.cpp34
-rw-r--r--Source/WebCore/html/parser/HTMLFormattingElementList.cpp22
-rw-r--r--Source/WebCore/html/parser/HTMLFormattingElementList.h10
-rw-r--r--Source/WebCore/html/parser/HTMLInputStream.h1
-rw-r--r--Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp93
-rw-r--r--Source/WebCore/html/parser/HTMLMetaCharsetParser.h29
-rw-r--r--Source/WebCore/html/parser/HTMLParserIdioms.cpp150
-rw-r--r--Source/WebCore/html/parser/HTMLParserIdioms.h26
-rw-r--r--Source/WebCore/html/parser/HTMLParserOptions.cpp2
-rw-r--r--Source/WebCore/html/parser/HTMLParserScheduler.cpp17
-rw-r--r--Source/WebCore/html/parser/HTMLParserScheduler.h5
-rw-r--r--Source/WebCore/html/parser/HTMLPreloadScanner.cpp169
-rw-r--r--Source/WebCore/html/parser/HTMLPreloadScanner.h70
-rw-r--r--Source/WebCore/html/parser/HTMLResourcePreloader.cpp13
-rw-r--r--Source/WebCore/html/parser/HTMLResourcePreloader.h9
-rw-r--r--Source/WebCore/html/parser/HTMLScriptRunner.cpp12
-rw-r--r--Source/WebCore/html/parser/HTMLSourceTracker.cpp39
-rw-r--r--Source/WebCore/html/parser/HTMLSourceTracker.h18
-rw-r--r--Source/WebCore/html/parser/HTMLSrcsetParser.cpp278
-rw-r--r--Source/WebCore/html/parser/HTMLSrcsetParser.h107
-rw-r--r--Source/WebCore/html/parser/HTMLStackItem.h280
-rw-r--r--Source/WebCore/html/parser/HTMLToken.h671
-rw-r--r--Source/WebCore/html/parser/HTMLTokenizer.cpp2233
-rw-r--r--Source/WebCore/html/parser/HTMLTokenizer.h328
-rw-r--r--Source/WebCore/html/parser/HTMLTreeBuilder.cpp2145
-rw-r--r--Source/WebCore/html/parser/HTMLTreeBuilder.h216
-rw-r--r--Source/WebCore/html/parser/HTMLViewSourceParser.cpp90
-rw-r--r--Source/WebCore/html/parser/HTMLViewSourceParser.h79
-rw-r--r--Source/WebCore/html/parser/InputStreamPreprocessor.h24
-rw-r--r--Source/WebCore/html/parser/TextDocumentParser.cpp18
-rw-r--r--Source/WebCore/html/parser/TextDocumentParser.h13
-rw-r--r--Source/WebCore/html/parser/TextViewSourceParser.cpp (renamed from Source/WebCore/html/WebAutocapitalize.h)28
-rw-r--r--Source/WebCore/html/parser/TextViewSourceParser.h (renamed from Source/WebCore/html/Autocapitalize.h)26
-rw-r--r--Source/WebCore/html/parser/XSSAuditor.cpp105
-rw-r--r--Source/WebCore/html/parser/XSSAuditor.h4
-rw-r--r--Source/WebCore/html/parser/XSSAuditorDelegate.cpp36
-rw-r--r--Source/WebCore/html/parser/XSSAuditorDelegate.h11
-rw-r--r--Source/WebCore/html/shadow/AutoFillButtonElement.cpp69
-rw-r--r--Source/WebCore/html/shadow/AutoFillButtonElement.h55
-rw-r--r--Source/WebCore/html/shadow/ContentDistributor.cpp6
-rw-r--r--Source/WebCore/html/shadow/DetailsMarkerControl.cpp26
-rw-r--r--Source/WebCore/html/shadow/DetailsMarkerControl.h16
-rw-r--r--Source/WebCore/html/shadow/ImageControlsRootElement.cpp51
-rw-r--r--Source/WebCore/html/shadow/ImageControlsRootElement.h53
-rw-r--r--Source/WebCore/html/shadow/InsertionPoint.h26
-rw-r--r--Source/WebCore/html/shadow/MediaControlElementTypes.cpp77
-rw-r--r--Source/WebCore/html/shadow/MediaControlElementTypes.h22
-rw-r--r--Source/WebCore/html/shadow/MediaControlElements.cpp599
-rw-r--r--Source/WebCore/html/shadow/MediaControlElements.h127
-rw-r--r--Source/WebCore/html/shadow/MediaControls.cpp19
-rw-r--r--Source/WebCore/html/shadow/MediaControls.h12
-rw-r--r--Source/WebCore/html/shadow/MediaControlsApple.cpp607
-rw-r--r--Source/WebCore/html/shadow/MediaControlsApple.h124
-rw-r--r--Source/WebCore/html/shadow/MediaControlsGtk.cpp378
-rw-r--r--Source/WebCore/html/shadow/MediaControlsGtk.h83
-rw-r--r--Source/WebCore/html/shadow/MeterShadowElement.cpp17
-rw-r--r--Source/WebCore/html/shadow/MeterShadowElement.h22
-rw-r--r--Source/WebCore/html/shadow/ProgressShadowElement.cpp11
-rw-r--r--Source/WebCore/html/shadow/ProgressShadowElement.h22
-rw-r--r--Source/WebCore/html/shadow/SliderThumbElement.cpp114
-rw-r--r--Source/WebCore/html/shadow/SliderThumbElement.h27
-rw-r--r--Source/WebCore/html/shadow/SpinButtonElement.cpp46
-rw-r--r--Source/WebCore/html/shadow/SpinButtonElement.h23
-rw-r--r--Source/WebCore/html/shadow/TextControlInnerElements.cpp337
-rw-r--r--Source/WebCore/html/shadow/TextControlInnerElements.h94
-rw-r--r--Source/WebCore/html/shadow/YouTubeEmbedShadowElement.cpp49
-rw-r--r--Source/WebCore/html/shadow/YouTubeEmbedShadowElement.h44
-rw-r--r--Source/WebCore/html/track/AudioTrack.cpp97
-rw-r--r--Source/WebCore/html/track/AudioTrack.h27
-rw-r--r--Source/WebCore/html/track/AudioTrack.idl4
-rw-r--r--Source/WebCore/html/track/AudioTrackList.cpp13
-rw-r--r--Source/WebCore/html/track/AudioTrackList.h10
-rw-r--r--Source/WebCore/html/track/AudioTrackList.idl20
-rw-r--r--Source/WebCore/html/track/BufferedLineReader.cpp104
-rw-r--r--Source/WebCore/html/track/BufferedLineReader.h90
-rw-r--r--Source/WebCore/html/track/DataCue.cpp195
-rw-r--r--Source/WebCore/html/track/DataCue.h118
-rw-r--r--Source/WebCore/html/track/DataCue.idl43
-rw-r--r--Source/WebCore/html/track/InbandDataTextTrack.cpp140
-rw-r--r--Source/WebCore/html/track/InbandDataTextTrack.h68
-rw-r--r--Source/WebCore/html/track/InbandGenericTextTrack.cpp89
-rw-r--r--Source/WebCore/html/track/InbandGenericTextTrack.h28
-rw-r--r--Source/WebCore/html/track/InbandTextTrack.cpp103
-rw-r--r--Source/WebCore/html/track/InbandTextTrack.h47
-rw-r--r--Source/WebCore/html/track/InbandWebVTTTextTrack.cpp65
-rw-r--r--Source/WebCore/html/track/InbandWebVTTTextTrack.h17
-rw-r--r--Source/WebCore/html/track/LoadableTextTrack.cpp28
-rw-r--r--Source/WebCore/html/track/LoadableTextTrack.h28
-rw-r--r--Source/WebCore/html/track/TextTrack.cpp133
-rw-r--r--Source/WebCore/html/track/TextTrack.h39
-rw-r--r--Source/WebCore/html/track/TextTrack.idl35
-rw-r--r--Source/WebCore/html/track/TextTrackCue.cpp1040
-rw-r--r--Source/WebCore/html/track/TextTrackCue.h200
-rw-r--r--Source/WebCore/html/track/TextTrackCue.idl39
-rw-r--r--Source/WebCore/html/track/TextTrackCueGeneric.cpp141
-rw-r--r--Source/WebCore/html/track/TextTrackCueGeneric.h25
-rw-r--r--Source/WebCore/html/track/TextTrackCueList.cpp8
-rw-r--r--Source/WebCore/html/track/TextTrackCueList.h8
-rw-r--r--Source/WebCore/html/track/TextTrackCueList.idl4
-rw-r--r--Source/WebCore/html/track/TextTrackList.cpp20
-rw-r--r--Source/WebCore/html/track/TextTrackList.h12
-rw-r--r--Source/WebCore/html/track/TextTrackList.idl20
-rw-r--r--Source/WebCore/html/track/TextTrackRegion.h (renamed from Source/WebCore/html/track/VTTRegion.h)65
-rw-r--r--Source/WebCore/html/track/TextTrackRegion.idl (renamed from Source/WebCore/html/track/VTTRegion.idl)20
-rw-r--r--Source/WebCore/html/track/TextTrackRegionList.h (renamed from Source/WebCore/html/track/VTTRegionList.h)31
-rw-r--r--Source/WebCore/html/track/TextTrackRegionList.idl (renamed from Source/WebCore/html/track/VTTRegionList.idl)10
-rw-r--r--Source/WebCore/html/track/TrackBase.cpp7
-rw-r--r--Source/WebCore/html/track/TrackBase.h7
-rw-r--r--Source/WebCore/html/track/TrackEvent.cpp4
-rw-r--r--Source/WebCore/html/track/TrackEvent.h14
-rw-r--r--Source/WebCore/html/track/TrackEvent.idl4
-rw-r--r--Source/WebCore/html/track/TrackListBase.cpp9
-rw-r--r--Source/WebCore/html/track/TrackListBase.h12
-rw-r--r--Source/WebCore/html/track/VTTCue.cpp1175
-rw-r--r--Source/WebCore/html/track/VTTCue.h240
-rw-r--r--Source/WebCore/html/track/VTTCue.idl44
-rw-r--r--Source/WebCore/html/track/VTTRegion.cpp491
-rw-r--r--Source/WebCore/html/track/VTTRegionList.cpp87
-rw-r--r--Source/WebCore/html/track/VTTScanner.cpp180
-rw-r--r--Source/WebCore/html/track/VTTScanner.h233
-rw-r--r--Source/WebCore/html/track/VideoTrack.cpp95
-rw-r--r--Source/WebCore/html/track/VideoTrack.h21
-rw-r--r--Source/WebCore/html/track/VideoTrack.idl4
-rw-r--r--Source/WebCore/html/track/VideoTrackList.cpp12
-rw-r--r--Source/WebCore/html/track/VideoTrackList.h12
-rw-r--r--Source/WebCore/html/track/VideoTrackList.idl21
-rw-r--r--Source/WebCore/html/track/WebVTTElement.cpp28
-rw-r--r--Source/WebCore/html/track/WebVTTElement.h25
-rw-r--r--Source/WebCore/html/track/WebVTTParser.cpp579
-rw-r--r--Source/WebCore/html/track/WebVTTParser.h113
-rw-r--r--Source/WebCore/html/track/WebVTTToken.h164
-rw-r--r--Source/WebCore/html/track/WebVTTTokenizer.cpp321
-rw-r--r--Source/WebCore/html/track/WebVTTTokenizer.h75
617 files changed, 23701 insertions, 33808 deletions
diff --git a/Source/WebCore/html/Autocapitalize.cpp b/Source/WebCore/html/Autocapitalize.cpp
deleted file mode 100644
index 5d2cf9963..000000000
--- a/Source/WebCore/html/Autocapitalize.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "Autocapitalize.h"
-
-#include <wtf/NeverDestroyed.h>
-
-namespace WebCore {
-
-static const AtomicString& valueOn()
-{
- static NeverDestroyed<const AtomicString> valueOn("on", AtomicString::ConstructFromLiteral);
- return valueOn;
-}
-
-static const AtomicString& valueOff()
-{
- static NeverDestroyed<const AtomicString> valueOff("off", AtomicString::ConstructFromLiteral);
- return valueOff;
-}
-
-static const AtomicString& valueNone()
-{
- static NeverDestroyed<const AtomicString> valueNone("none", AtomicString::ConstructFromLiteral);
- return valueNone;
-}
-
-static const AtomicString& valueWords()
-{
- static NeverDestroyed<const AtomicString> valueWords("words", AtomicString::ConstructFromLiteral);
- return valueWords;
-}
-
-static const AtomicString& valueSentences()
-{
- static NeverDestroyed<const AtomicString> valueSentences("sentences", AtomicString::ConstructFromLiteral);
- return valueSentences;
-}
-
-static const AtomicString& valueAllCharacters()
-{
- static NeverDestroyed<const AtomicString> valueAllCharacters("characters", AtomicString::ConstructFromLiteral);
- return valueAllCharacters;
-}
-
-WebAutocapitalizeType autocapitalizeTypeForAttributeValue(const AtomicString& attributeValue)
-{
- // Omitted / missing values are the Default state.
- if (attributeValue.isNull() || attributeValue.isEmpty())
- return WebAutocapitalizeTypeDefault;
-
- if (equalIgnoringCase(attributeValue, valueOn()) || equalIgnoringCase(attributeValue, valueSentences()))
- return WebAutocapitalizeTypeSentences;
- if (equalIgnoringCase(attributeValue, valueOff()) || equalIgnoringCase(attributeValue, valueNone()))
- return WebAutocapitalizeTypeNone;
- if (equalIgnoringCase(attributeValue, valueWords()))
- return WebAutocapitalizeTypeWords;
- if (equalIgnoringCase(attributeValue, valueAllCharacters()))
- return WebAutocapitalizeTypeAllCharacters;
-
- // Unrecognized values fall back to "on".
- return WebAutocapitalizeTypeSentences;
-}
-
-const AtomicString& stringForAutocapitalizeType(WebAutocapitalizeType type)
-{
- switch (type) {
- case WebAutocapitalizeTypeDefault:
- return nullAtom;
- case WebAutocapitalizeTypeNone:
- return valueNone();
- case WebAutocapitalizeTypeSentences:
- return valueSentences();
- case WebAutocapitalizeTypeWords:
- return valueWords();
- case WebAutocapitalizeTypeAllCharacters:
- return valueAllCharacters();
- }
-
- ASSERT_NOT_REACHED();
- return nullAtom;
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/html/BaseButtonInputType.cpp b/Source/WebCore/html/BaseButtonInputType.cpp
index 364221904..0b18b4f07 100644
--- a/Source/WebCore/html/BaseButtonInputType.cpp
+++ b/Source/WebCore/html/BaseButtonInputType.cpp
@@ -52,9 +52,9 @@ bool BaseButtonInputType::appendFormData(FormDataList&, bool) const
return false;
}
-RenderPtr<RenderElement> BaseButtonInputType::createInputRenderer(Ref<RenderStyle>&& style)
+RenderPtr<RenderElement> BaseButtonInputType::createInputRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderButton>(element(), WTF::move(style));
+ return createRenderer<RenderButton>(element(), std::move(style));
}
bool BaseButtonInputType::storesValueSeparateFromAttribute()
diff --git a/Source/WebCore/html/BaseButtonInputType.h b/Source/WebCore/html/BaseButtonInputType.h
index fe0a918e4..46571c30f 100644
--- a/Source/WebCore/html/BaseButtonInputType.h
+++ b/Source/WebCore/html/BaseButtonInputType.h
@@ -43,7 +43,7 @@ protected:
private:
virtual bool shouldSaveAndRestoreFormControlState() const override;
virtual bool appendFormData(FormDataList&, bool) const override;
- virtual RenderPtr<RenderElement> createInputRenderer(Ref<RenderStyle>&&) override;
+ virtual RenderPtr<RenderElement> createInputRenderer(PassRef<RenderStyle>) override;
virtual bool storesValueSeparateFromAttribute() override;
virtual void setValue(const String&, bool, TextFieldEventBehavior) override;
};
diff --git a/Source/WebCore/html/BaseChooserOnlyDateAndTimeInputType.cpp b/Source/WebCore/html/BaseChooserOnlyDateAndTimeInputType.cpp
index dbea0e99b..732e83e74 100644
--- a/Source/WebCore/html/BaseChooserOnlyDateAndTimeInputType.cpp
+++ b/Source/WebCore/html/BaseChooserOnlyDateAndTimeInputType.cpp
@@ -54,11 +54,15 @@ void BaseChooserOnlyDateAndTimeInputType::handleDOMActivateEvent(Event*)
DateTimeChooserParameters parameters;
if (!element().setupDateTimeChooserParameters(parameters))
return;
+#if !PLATFORM(IOS)
+ // FIXME: Is this correct? Why don't we do this on iOS?
+ m_dateTimeChooser = element().document().page()->chrome().openDateTimeChooser(this, parameters);
+#endif
}
void BaseChooserOnlyDateAndTimeInputType::createShadowSubtree()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, valueContainerPseudo, ("-webkit-date-and-time-value", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, valueContainerPseudo, ("-webkit-date-and-time-value", AtomicString::ConstructFromLiteral));
RefPtr<HTMLDivElement> valueContainer = HTMLDivElement::create(element().document());
valueContainer->setPseudo(valueContainerPseudo);
@@ -69,14 +73,14 @@ void BaseChooserOnlyDateAndTimeInputType::createShadowSubtree()
void BaseChooserOnlyDateAndTimeInputType::updateAppearance()
{
Node* node = element().userAgentShadowRoot()->firstChild();
- if (!is<HTMLElement>(node))
+ if (!node || !node->isHTMLElement())
return;
String displayValue = visibleValue();
if (displayValue.isEmpty()) {
// Need to put something to keep text baseline.
displayValue = ASCIILiteral(" ");
}
- downcast<HTMLElement>(*node).setInnerText(displayValue, ASSERT_NO_EXCEPTION);
+ toHTMLElement(node)->setInnerText(displayValue, ASSERT_NO_EXCEPTION);
}
void BaseChooserOnlyDateAndTimeInputType::setValue(const String& value, bool valueChanged, TextFieldEventBehavior eventBehavior)
@@ -98,7 +102,7 @@ void BaseChooserOnlyDateAndTimeInputType::didChooseValue(const String& value)
void BaseChooserOnlyDateAndTimeInputType::didEndChooser()
{
- m_dateTimeChooser = nullptr;
+ m_dateTimeChooser.clear();
}
void BaseChooserOnlyDateAndTimeInputType::closeDateTimeChooser()
diff --git a/Source/WebCore/html/BaseDateAndTimeInputType.cpp b/Source/WebCore/html/BaseDateAndTimeInputType.cpp
index d7cae525e..16f5df7e0 100644
--- a/Source/WebCore/html/BaseDateAndTimeInputType.cpp
+++ b/Source/WebCore/html/BaseDateAndTimeInputType.cpp
@@ -40,7 +40,6 @@
#include <wtf/CurrentTime.h>
#include <wtf/DateMath.h>
#include <wtf/MathExtras.h>
-#include <wtf/text/StringView.h>
namespace WebCore {
@@ -109,7 +108,7 @@ bool BaseDateAndTimeInputType::parseToDateComponents(const String& source, DateC
DateComponents ignoredResult;
if (!out)
out = &ignoredResult;
- return parseToDateComponentsInternal(StringView(source).upconvertedCharacters(), source.length(), out);
+ return parseToDateComponentsInternal(source.characters(), source.length(), out);
}
String BaseDateAndTimeInputType::serialize(const Decimal& value) const
diff --git a/Source/WebCore/html/ButtonInputType.h b/Source/WebCore/html/ButtonInputType.h
index 1dea03344..bd405bae9 100644
--- a/Source/WebCore/html/ButtonInputType.h
+++ b/Source/WebCore/html/ButtonInputType.h
@@ -35,7 +35,7 @@
namespace WebCore {
-class ButtonInputType final : public BaseButtonInputType {
+class ButtonInputType : public BaseButtonInputType {
public:
explicit ButtonInputType(HTMLInputElement& element) : BaseButtonInputType(element) { }
diff --git a/Source/WebCore/html/CheckboxInputType.h b/Source/WebCore/html/CheckboxInputType.h
index 854ce3e1b..5a9a20650 100644
--- a/Source/WebCore/html/CheckboxInputType.h
+++ b/Source/WebCore/html/CheckboxInputType.h
@@ -35,7 +35,7 @@
namespace WebCore {
-class CheckboxInputType final : public BaseCheckableInputType {
+class CheckboxInputType : public BaseCheckableInputType {
public:
explicit CheckboxInputType(HTMLInputElement& element) : BaseCheckableInputType(element) { }
diff --git a/Source/WebCore/html/ColorInputType.cpp b/Source/WebCore/html/ColorInputType.cpp
index 8bbdb97c2..97cd43599 100644
--- a/Source/WebCore/html/ColorInputType.cpp
+++ b/Source/WebCore/html/ColorInputType.cpp
@@ -69,6 +69,11 @@ ColorInputType::~ColorInputType()
endColorChooser();
}
+void ColorInputType::attach()
+{
+ observeFeatureIfVisible(FeatureObserver::InputTypeColor);
+}
+
bool ColorInputType::isColorControl() const
{
return true;
@@ -178,7 +183,7 @@ void ColorInputType::didChooseColor(const Color& color)
void ColorInputType::didEndChooser()
{
- m_chooser = nullptr;
+ m_chooser.clear();
}
void ColorInputType::endColorChooser()
@@ -199,14 +204,12 @@ void ColorInputType::updateColorSwatch()
HTMLElement* ColorInputType::shadowColorSwatch() const
{
ShadowRoot* shadow = element().userAgentShadowRoot();
- return shadow ? downcast<HTMLElement>(shadow->firstChild()->firstChild()) : nullptr;
+ return shadow ? toHTMLElement(shadow->firstChild()->firstChild()) : 0;
}
IntRect ColorInputType::elementRectRelativeToRootView() const
{
- if (!element().renderer())
- return IntRect();
- return element().document().view()->contentsToRootView(element().renderer()->absoluteBoundingBoxRect());
+ return element().document().view()->contentsToRootView(element().pixelSnappedBoundingBox());
}
Color ColorInputType::currentColor()
@@ -229,8 +232,8 @@ Vector<Color> ColorInputType::suggestions() const
#if ENABLE(DATALIST_ELEMENT)
HTMLDataListElement* dataList = element().dataList();
if (dataList) {
- Ref<HTMLCollection> options = dataList->options();
- for (unsigned i = 0; HTMLOptionElement* option = downcast<HTMLOptionElement>(options->item(i)); ++i) {
+ RefPtr<HTMLCollection> options = dataList->options();
+ for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); i++) {
if (!element().isValidValue(option->value()))
continue;
Color color(option->value());
diff --git a/Source/WebCore/html/ColorInputType.h b/Source/WebCore/html/ColorInputType.h
index 02f90ba2f..360e3005c 100644
--- a/Source/WebCore/html/ColorInputType.h
+++ b/Source/WebCore/html/ColorInputType.h
@@ -37,7 +37,7 @@
namespace WebCore {
-class ColorInputType final : public BaseClickableWithKeyInputType, public ColorChooserClient {
+class ColorInputType : public BaseClickableWithKeyInputType, public ColorChooserClient {
public:
explicit ColorInputType(HTMLInputElement& element) : BaseClickableWithKeyInputType(element) { }
virtual ~ColorInputType();
@@ -51,6 +51,7 @@ public:
virtual Vector<Color> suggestions() const override;
private:
+ virtual void attach() override;
virtual bool isColorControl() const override;
virtual const AtomicString& formControlType() const override;
virtual bool supportsRequired() const override;
@@ -69,7 +70,7 @@ private:
void updateColorSwatch();
HTMLElement* shadowColorSwatch() const;
- std::unique_ptr<ColorChooser> m_chooser;
+ OwnPtr<ColorChooser> m_chooser;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/DOMFormData.h b/Source/WebCore/html/DOMFormData.h
index 63f931326..842e62b04 100644
--- a/Source/WebCore/html/DOMFormData.h
+++ b/Source/WebCore/html/DOMFormData.h
@@ -44,8 +44,8 @@ class TextEncoding;
class DOMFormData : public FormDataList, public RefCounted<DOMFormData> {
public:
- static Ref<DOMFormData> create(HTMLFormElement* form) { return adoptRef(*new DOMFormData(form)); }
- static Ref<DOMFormData> create(const TextEncoding& encoding) { return adoptRef(*new DOMFormData(encoding)); }
+ static PassRefPtr<DOMFormData> create(HTMLFormElement* form) { return adoptRef(new DOMFormData(form)); }
+ static PassRefPtr<DOMFormData> create(const TextEncoding& encoding) { return adoptRef(new DOMFormData(encoding)); }
void append(const String& name, const String& value);
void append(const String& name, Blob*, const String& filename = String());
diff --git a/Source/WebCore/html/DOMSettableTokenList.cpp b/Source/WebCore/html/DOMSettableTokenList.cpp
index 3f3b011af..741ff595c 100644
--- a/Source/WebCore/html/DOMSettableTokenList.cpp
+++ b/Source/WebCore/html/DOMSettableTokenList.cpp
@@ -28,6 +28,11 @@
namespace WebCore {
+PassRefPtr<DOMSettableTokenList> DOMSettableTokenList::create()
+{
+ return adoptRef(new DOMSettableTokenList());
+}
+
void DOMSettableTokenList::ref()
{
RefCounted<DOMSettableTokenList>::ref();
diff --git a/Source/WebCore/html/DOMSettableTokenList.h b/Source/WebCore/html/DOMSettableTokenList.h
index 577d1f814..9d3dee6be 100644
--- a/Source/WebCore/html/DOMSettableTokenList.h
+++ b/Source/WebCore/html/DOMSettableTokenList.h
@@ -35,25 +35,22 @@ namespace WebCore {
typedef int ExceptionCode;
-class DOMSettableTokenList final : public DOMTokenList, public RefCounted<DOMSettableTokenList> {
+class DOMSettableTokenList : public DOMTokenList, public RefCounted<DOMSettableTokenList> {
WTF_MAKE_FAST_ALLOCATED;
public:
- static Ref<DOMSettableTokenList> create()
- {
- return adoptRef(*new DOMSettableTokenList);
- }
+ static PassRefPtr<DOMSettableTokenList> create();
- virtual void ref() override;
- virtual void deref() override;
+ virtual void ref() override final;
+ virtual void deref() override final;
- virtual unsigned length() const override;
- virtual const AtomicString item(unsigned index) const override;
+ virtual unsigned length() const override final;
+ virtual const AtomicString item(unsigned index) const override final;
- virtual AtomicString value() const override;
- virtual void setValue(const AtomicString&) override;
+ virtual AtomicString value() const override final;
+ virtual void setValue(const AtomicString&) override final;
private:
- virtual bool containsInternal(const AtomicString&) const override;
+ virtual bool containsInternal(const AtomicString&) const override final;
AtomicString m_value;
SpaceSplitString m_tokens;
diff --git a/Source/WebCore/html/DOMURL.cpp b/Source/WebCore/html/DOMURL.cpp
index 1aa55a839..3d65fc51c 100644
--- a/Source/WebCore/html/DOMURL.cpp
+++ b/Source/WebCore/html/DOMURL.cpp
@@ -1,32 +1,35 @@
/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2000 Simon Hausmann <hausmann@kde.org>
- * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2014 Apple Inc. All rights reserved.
- * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
* Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2012 Motorola Mobility Inc.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
+
+#if ENABLE(BLOB)
+
#include "DOMURL.h"
-#include "SecurityOrigin.h"
#include "ActiveDOMObject.h"
#include "Blob.h"
#include "BlobURL.h"
@@ -34,62 +37,11 @@
#include "PublicURLManager.h"
#include "ResourceRequest.h"
#include "ScriptExecutionContext.h"
+#include "SecurityOrigin.h"
#include <wtf/MainThread.h>
namespace WebCore {
-Ref<DOMURL> DOMURL::create(const String& url, const String& base, ExceptionCode& ec)
-{
- return adoptRef(*new DOMURL(url, base, ec));
-}
-
-Ref<DOMURL> DOMURL::create(const String& url, const DOMURL* base, ExceptionCode& ec)
-{
- ASSERT(base);
- return adoptRef(*new DOMURL(url, *base, ec));
-}
-
-Ref<DOMURL> DOMURL::create(const String& url, ExceptionCode& ec)
-{
- return adoptRef(*new DOMURL(url, ec));
-}
-
-inline DOMURL::DOMURL(const String& url, const String& base, ExceptionCode& ec)
- : m_baseURL(URL(), base)
- , m_url(m_baseURL, url)
-{
- if (!m_baseURL.isValid() || !m_url.isValid())
- ec = TypeError;
-}
-
-inline DOMURL::DOMURL(const String& url, const DOMURL& base, ExceptionCode& ec)
- : m_baseURL(base.href())
- , m_url(m_baseURL, url)
-{
- if (!m_baseURL.isValid() || !m_url.isValid())
- ec = TypeError;
-}
-
-inline DOMURL::DOMURL(const String& url, ExceptionCode& ec)
- : m_baseURL(blankURL())
- , m_url(m_baseURL, url)
-{
- if (!m_url.isValid())
- ec = TypeError;
-}
-
-void DOMURL::setHref(const String& url)
-{
- m_url = URL(m_baseURL, url);
-}
-
-void DOMURL::setHref(const String& url, ExceptionCode& ec)
-{
- setHref(url);
- if (!m_url.isValid())
- ec = TypeError;
-}
-
String DOMURL::createObjectURL(ScriptExecutionContext* scriptExecutionContext, Blob* blob)
{
if (!scriptExecutionContext || !blob)
@@ -116,11 +68,13 @@ void DOMURL::revokeObjectURL(ScriptExecutionContext* scriptExecutionContext, con
URL url(URL(), urlString);
ResourceRequest request(url);
#if ENABLE(CACHE_PARTITIONING)
- request.setDomainForCachePartition(scriptExecutionContext->topOrigin()->domainForCachePartition());
+ request.setCachePartition(scriptExecutionContext->topOrigin()->cachePartition());
#endif
- MemoryCache::removeRequestFromSessionCaches(*scriptExecutionContext, request);
+ MemoryCache::removeRequestFromCache(scriptExecutionContext, request);
scriptExecutionContext->publicURLManager().revoke(url);
}
} // namespace WebCore
+
+#endif // ENABLE(BLOB)
diff --git a/Source/WebCore/html/DOMURL.h b/Source/WebCore/html/DOMURL.h
index bc308496a..7d214d1cb 100644
--- a/Source/WebCore/html/DOMURL.h
+++ b/Source/WebCore/html/DOMURL.h
@@ -27,10 +27,9 @@
#ifndef DOMURL_h
#define DOMURL_h
-#include "ExceptionCode.h"
#include "URL.h"
-#include "URLUtils.h"
#include <wtf/HashSet.h>
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
@@ -40,29 +39,19 @@ class Blob;
class ScriptExecutionContext;
class URLRegistrable;
-class DOMURL : public RefCounted<DOMURL>, public URLUtils<DOMURL> {
+class DOMURL : public RefCounted<DOMURL> {
public:
- static Ref<DOMURL> create(const String& url, const String& base, ExceptionCode&);
- static Ref<DOMURL> create(const String& url, const DOMURL* base, ExceptionCode&);
- static Ref<DOMURL> create(const String& url, ExceptionCode&);
+ static PassRefPtr<DOMURL> create() { return adoptRef(new DOMURL); }
- URL href() const { return m_url; }
- void setHref(const String& url);
- void setHref(const String&, ExceptionCode&);
+#if ENABLE(BLOB)
+ static void contextDestroyed(ScriptExecutionContext*);
static String createObjectURL(ScriptExecutionContext*, Blob*);
static void revokeObjectURL(ScriptExecutionContext*, const String&);
static String createPublicURL(ScriptExecutionContext*, URLRegistrable*);
-
-private:
- DOMURL(const String& url, const String& base, ExceptionCode&);
- DOMURL(const String& url, const DOMURL& base, ExceptionCode&);
- DOMURL(const String& url, ExceptionCode&);
-
- URL m_baseURL;
- URL m_url;
+#endif
};
} // namespace WebCore
diff --git a/Source/WebCore/html/DOMURL.idl b/Source/WebCore/html/DOMURL.idl
index 085804189..db695aa89 100644
--- a/Source/WebCore/html/DOMURL.idl
+++ b/Source/WebCore/html/DOMURL.idl
@@ -26,17 +26,13 @@
[
GlobalContext=DOMWindow&WorkerGlobalScope,
- Constructor(DOMString url),
- Constructor(DOMString url, DOMString base),
- Constructor(DOMString url, DOMURL base),
- ConstructorRaisesException,
+ Constructor,
JSGenerateToNativeObject,
JSGenerateToJSObject,
+ JSNoStaticTables,
InterfaceName=URL,
ImplementationLacksVTable,
] interface DOMURL {
- [CallWith=ScriptExecutionContext,TreatReturnedNullStringAs=Null] static DOMString createObjectURL(Blob? blob);
- [CallWith=ScriptExecutionContext] static void revokeObjectURL(DOMString url);
+ [CallWith=ScriptExecutionContext,TreatReturnedNullStringAs=Null,Conditional=BLOB] static DOMString createObjectURL(Blob? blob);
+ [CallWith=ScriptExecutionContext,Conditional=BLOB] static void revokeObjectURL(DOMString url);
};
-
-DOMURL implements URLUtils;
diff --git a/Source/WebCore/html/DateInputType.cpp b/Source/WebCore/html/DateInputType.cpp
index b1e829dfc..91a7bc2ec 100644
--- a/Source/WebCore/html/DateInputType.cpp
+++ b/Source/WebCore/html/DateInputType.cpp
@@ -49,6 +49,11 @@ DateInputType::DateInputType(HTMLInputElement& element)
{
}
+void DateInputType::attach()
+{
+ observeFeatureIfVisible(FeatureObserver::InputTypeDate);
+}
+
const AtomicString& DateInputType::formControlType() const
{
return InputTypeNames::date();
@@ -61,7 +66,7 @@ DateComponents::Type DateInputType::dateType() const
StepRange DateInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateDefaultStep, dateDefaultStepBase, dateStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger));
+ DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateDefaultStep, dateDefaultStepBase, dateStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger));
const Decimal stepBase = parseToNumber(element().fastGetAttribute(minAttr), 0);
const Decimal minimum = parseToNumber(element().fastGetAttribute(minAttr), Decimal::fromDouble(DateComponents::minimumDate()));
diff --git a/Source/WebCore/html/DateInputType.h b/Source/WebCore/html/DateInputType.h
index 8ca01f5c6..f14a29f4b 100644
--- a/Source/WebCore/html/DateInputType.h
+++ b/Source/WebCore/html/DateInputType.h
@@ -36,11 +36,12 @@
namespace WebCore {
-class DateInputType final : public BaseChooserOnlyDateAndTimeInputType {
+class DateInputType : public BaseChooserOnlyDateAndTimeInputType {
public:
explicit DateInputType(HTMLInputElement&);
private:
+ virtual void attach() override;
virtual const AtomicString& formControlType() const override;
virtual DateComponents::Type dateType() const override;
virtual StepRange createStepRange(AnyStepHandling) const override;
diff --git a/Source/WebCore/html/DateTimeInputType.cpp b/Source/WebCore/html/DateTimeInputType.cpp
index b2efe8578..1e7fb1ffa 100644
--- a/Source/WebCore/html/DateTimeInputType.cpp
+++ b/Source/WebCore/html/DateTimeInputType.cpp
@@ -45,6 +45,11 @@ static const int dateTimeDefaultStep = 60;
static const int dateTimeDefaultStepBase = 0;
static const int dateTimeStepScaleFactor = 1000;
+void DateTimeInputType::attach()
+{
+ observeFeatureIfVisible(FeatureObserver::InputTypeDateTime);
+}
+
const AtomicString& DateTimeInputType::formControlType() const
{
return InputTypeNames::datetime();
@@ -62,7 +67,7 @@ Decimal DateTimeInputType::defaultValueForStepUp() const
StepRange DateTimeInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateTimeDefaultStep, dateTimeDefaultStepBase, dateTimeStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
+ DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateTimeDefaultStep, dateTimeDefaultStepBase, dateTimeStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
const Decimal stepBase = parseToNumber(element().fastGetAttribute(minAttr), 0);
const Decimal minimum = parseToNumber(element().fastGetAttribute(minAttr), Decimal::fromDouble(DateComponents::minimumDateTime()));
diff --git a/Source/WebCore/html/DateTimeInputType.h b/Source/WebCore/html/DateTimeInputType.h
index 28b511e1a..aab26a3da 100644
--- a/Source/WebCore/html/DateTimeInputType.h
+++ b/Source/WebCore/html/DateTimeInputType.h
@@ -37,11 +37,12 @@
namespace WebCore {
-class DateTimeInputType final : public BaseChooserOnlyDateAndTimeInputType {
+class DateTimeInputType : public BaseChooserOnlyDateAndTimeInputType {
public:
explicit DateTimeInputType(HTMLInputElement& element) : BaseDateTimeInputType(element) { }
private:
+ virtual void attach() override;
virtual const AtomicString& formControlType() const override;
virtual DateComponents::Type dateType() const override;
virtual StepRange createStepRange(AnyStepHandling) const override;
diff --git a/Source/WebCore/html/DateTimeLocalInputType.cpp b/Source/WebCore/html/DateTimeLocalInputType.cpp
index 4a438f37d..6f0f24933 100644
--- a/Source/WebCore/html/DateTimeLocalInputType.cpp
+++ b/Source/WebCore/html/DateTimeLocalInputType.cpp
@@ -44,6 +44,11 @@ static const int dateTimeLocalDefaultStep = 60;
static const int dateTimeLocalDefaultStepBase = 0;
static const int dateTimeLocalStepScaleFactor = 1000;
+void DateTimeLocalInputType::attach()
+{
+ observeFeatureIfVisible(FeatureObserver::InputTypeDateTimeLocal);
+}
+
const AtomicString& DateTimeLocalInputType::formControlType() const
{
return InputTypeNames::datetimelocal();
@@ -68,7 +73,7 @@ void DateTimeLocalInputType::setValueAsDate(double value, ExceptionCode& ec) con
StepRange DateTimeLocalInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateTimeLocalDefaultStep, dateTimeLocalDefaultStepBase, dateTimeLocalStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
+ DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateTimeLocalDefaultStep, dateTimeLocalDefaultStepBase, dateTimeLocalStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
const Decimal stepBase = parseToNumber(element().fastGetAttribute(minAttr), 0);
const Decimal minimum = parseToNumber(element().fastGetAttribute(minAttr), Decimal::fromDouble(DateComponents::minimumDateTime()));
diff --git a/Source/WebCore/html/DateTimeLocalInputType.h b/Source/WebCore/html/DateTimeLocalInputType.h
index 929a4ca6a..b1bc0490d 100644
--- a/Source/WebCore/html/DateTimeLocalInputType.h
+++ b/Source/WebCore/html/DateTimeLocalInputType.h
@@ -36,16 +36,17 @@
namespace WebCore {
-class DateTimeLocalInputType final : public BaseChooserOnlyDateAndTimeInputType {
+class DateTimeLocalInputType : public BaseChooserOnlyDateAndTimeInputType {
public:
explicit DateTimeLocalInputType(HTMLInputElement& element) : BaseChooserOnlyDateAndTimeInputType(element) { }
private:
+ virtual void attach() override;
virtual const AtomicString& formControlType() const override;
virtual DateComponents::Type dateType() const override;
virtual double valueAsDate() const override;
virtual void setValueAsDate(double, ExceptionCode&) const override;
- virtual StepRange createStepRange(AnyStepHandling) const override;
+ virtual StepRange createStepRange(AnyStepHandling) const;
virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const override;
virtual bool setMillisecondToDateComponents(double, DateComponents*) const override;
virtual bool isDateTimeLocalField() const override;
diff --git a/Source/WebCore/html/EmailInputType.cpp b/Source/WebCore/html/EmailInputType.cpp
index 68f35dbfb..570270191 100644
--- a/Source/WebCore/html/EmailInputType.cpp
+++ b/Source/WebCore/html/EmailInputType.cpp
@@ -44,7 +44,7 @@ static bool isValidEmailAddress(const String& address)
if (!addressLength)
return false;
- DEPRECATED_DEFINE_STATIC_LOCAL(const JSC::Yarr::RegularExpression, regExp, (emailPattern, TextCaseInsensitive));
+ DEFINE_STATIC_LOCAL(const JSC::Yarr::RegularExpression, regExp, (emailPattern, TextCaseInsensitive));
int matchLength;
int matchOffset = regExp.match(address, 0, &matchLength);
@@ -52,6 +52,12 @@ static bool isValidEmailAddress(const String& address)
return !matchOffset && matchLength == addressLength;
}
+void EmailInputType::attach()
+{
+ TextFieldInputType::attach();
+ observeFeatureIfVisible(FeatureObserver::InputTypeEmail);
+}
+
const AtomicString& EmailInputType::formControlType() const
{
return InputTypeNames::email();
@@ -102,7 +108,7 @@ String EmailInputType::sanitizeValue(const String& proposedValue) const
StringBuilder strippedValue;
for (unsigned i = 0; i < addresses.size(); ++i) {
if (i > 0)
- strippedValue.append(',');
+ strippedValue.append(",");
strippedValue.append(stripLeadingAndTrailingHTMLSpaces(addresses[i]));
}
return strippedValue.toString();
diff --git a/Source/WebCore/html/EmailInputType.h b/Source/WebCore/html/EmailInputType.h
index 45818cc02..a0c645163 100644
--- a/Source/WebCore/html/EmailInputType.h
+++ b/Source/WebCore/html/EmailInputType.h
@@ -35,11 +35,12 @@
namespace WebCore {
-class EmailInputType final : public BaseTextInputType {
+class EmailInputType : public BaseTextInputType {
public:
explicit EmailInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
private:
+ virtual void attach() override;
virtual const AtomicString& formControlType() const override;
virtual bool typeMismatchFor(const String&) const override;
virtual bool typeMismatch() const override;
diff --git a/Source/WebCore/html/FTPDirectoryDocument.cpp b/Source/WebCore/html/FTPDirectoryDocument.cpp
index 00de9ff57..ac29b3aef 100644
--- a/Source/WebCore/html/FTPDirectoryDocument.cpp
+++ b/Source/WebCore/html/FTPDirectoryDocument.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2008, 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
@@ -26,7 +26,9 @@
#if ENABLE(FTPDIR)
#include "FTPDirectoryDocument.h"
+#include "ExceptionCodePlaceholder.h"
#include "HTMLDocumentParser.h"
+#include "HTMLNames.h"
#include "HTMLTableElement.h"
#include "LocalizedStrings.h"
#include "Logging.h"
@@ -34,7 +36,10 @@
#include "Settings.h"
#include "SharedBuffer.h"
#include "Text.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/GregorianDateTime.h>
#include <wtf/StdLibExtras.h>
+#include <wtf/text/CString.h>
#include <wtf/unicode/CharacterNames.h>
namespace WebCore {
@@ -43,19 +48,17 @@ using namespace HTMLNames;
class FTPDirectoryDocumentParser final : public HTMLDocumentParser {
public:
- static Ref<FTPDirectoryDocumentParser> create(HTMLDocument& document)
+ static PassRefPtr<FTPDirectoryDocumentParser> create(HTMLDocument& document)
{
- return adoptRef(*new FTPDirectoryDocumentParser(document));
+ return adoptRef(new FTPDirectoryDocumentParser(document));
}
-private:
virtual void append(PassRefPtr<StringImpl>) override;
virtual void finish() override;
- // FIXME: Why do we need this?
virtual bool isWaitingForScripts() const override { return false; }
- void checkBuffer(int len = 10)
+ inline void checkBuffer(int len = 10)
{
if ((m_dest - m_buffer) > m_size - len) {
// Enlarge buffer
@@ -66,7 +69,8 @@ private:
m_size = newSize;
}
}
-
+
+private:
FTPDirectoryDocumentParser(HTMLDocument&);
// The parser will attempt to load the document template specified via the preference
@@ -77,13 +81,13 @@ private:
void parseAndAppendOneLine(const String&);
void appendEntry(const String& name, const String& size, const String& date, bool isDirectory);
- Ref<Element> createTDForFilename(const String&);
+ PassRefPtr<Element> createTDForFilename(const String&);
RefPtr<HTMLTableElement> m_tableElement;
- bool m_skipLF { false };
+ bool m_skipLF;
- int m_size { 254 };
+ int m_size;
UChar* m_buffer;
UChar* m_dest;
String m_carryOver;
@@ -93,6 +97,8 @@ private:
FTPDirectoryDocumentParser::FTPDirectoryDocumentParser(HTMLDocument& document)
: HTMLDocumentParser(document)
+ , m_skipLF(false)
+ , m_size(254)
, m_buffer(static_cast<UChar*>(fastMalloc(sizeof(UChar) * m_size)))
, m_dest(m_buffer)
{
@@ -101,53 +107,53 @@ FTPDirectoryDocumentParser::FTPDirectoryDocumentParser(HTMLDocument& document)
void FTPDirectoryDocumentParser::appendEntry(const String& filename, const String& size, const String& date, bool isDirectory)
{
RefPtr<Element> rowElement = m_tableElement->insertRow(-1, IGNORE_EXCEPTION);
- rowElement->setAttribute(HTMLNames::classAttr, "ftpDirectoryEntryRow");
+ rowElement->setAttribute("class", "ftpDirectoryEntryRow", IGNORE_EXCEPTION);
RefPtr<Element> element = document()->createElement(tdTag, false);
element->appendChild(Text::create(*document(), String(&noBreakSpace, 1)), IGNORE_EXCEPTION);
if (isDirectory)
- element->setAttribute(HTMLNames::classAttr, "ftpDirectoryIcon ftpDirectoryTypeDirectory");
+ element->setAttribute("class", "ftpDirectoryIcon ftpDirectoryTypeDirectory", IGNORE_EXCEPTION);
else
- element->setAttribute(HTMLNames::classAttr, "ftpDirectoryIcon ftpDirectoryTypeFile");
+ element->setAttribute("class", "ftpDirectoryIcon ftpDirectoryTypeFile", IGNORE_EXCEPTION);
rowElement->appendChild(element, IGNORE_EXCEPTION);
element = createTDForFilename(filename);
- element->setAttribute(HTMLNames::classAttr, "ftpDirectoryFileName");
+ element->setAttribute("class", "ftpDirectoryFileName", IGNORE_EXCEPTION);
rowElement->appendChild(element, IGNORE_EXCEPTION);
element = document()->createElement(tdTag, false);
element->appendChild(Text::create(*document(), date), IGNORE_EXCEPTION);
- element->setAttribute(HTMLNames::classAttr, "ftpDirectoryFileDate");
+ element->setAttribute("class", "ftpDirectoryFileDate", IGNORE_EXCEPTION);
rowElement->appendChild(element, IGNORE_EXCEPTION);
element = document()->createElement(tdTag, false);
element->appendChild(Text::create(*document(), size), IGNORE_EXCEPTION);
- element->setAttribute(HTMLNames::classAttr, "ftpDirectoryFileSize");
+ element->setAttribute("class", "ftpDirectoryFileSize", IGNORE_EXCEPTION);
rowElement->appendChild(element, IGNORE_EXCEPTION);
}
-Ref<Element> FTPDirectoryDocumentParser::createTDForFilename(const String& filename)
+PassRefPtr<Element> FTPDirectoryDocumentParser::createTDForFilename(const String& filename)
{
String fullURL = document()->baseURL().string();
- if (fullURL.endsWith('/'))
- fullURL = fullURL + filename;
+ if (fullURL[fullURL.length() - 1] == '/')
+ fullURL.append(filename);
else
- fullURL = fullURL + '/' + filename;
+ fullURL.append("/" + filename);
RefPtr<Element> anchorElement = document()->createElement(aTag, false);
- anchorElement->setAttribute(HTMLNames::hrefAttr, fullURL);
+ anchorElement->setAttribute("href", fullURL, IGNORE_EXCEPTION);
anchorElement->appendChild(Text::create(*document(), filename), IGNORE_EXCEPTION);
- Ref<Element> tdElement = document()->createElement(tdTag, false);
+ RefPtr<Element> tdElement = document()->createElement(tdTag, false);
tdElement->appendChild(anchorElement, IGNORE_EXCEPTION);
- return tdElement;
+ return tdElement.release();
}
static String processFilesizeString(const String& size, bool isDirectory)
{
if (isDirectory)
- return ASCIILiteral("--");
+ return "--";
bool valid;
int64_t bytes = size.toUInt64(&valid);
@@ -165,7 +171,7 @@ static String processFilesizeString(const String& size, bool isDirectory)
static bool wasLastDayOfMonth(int year, int month, int day)
{
- static const int lastDays[] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ static int lastDays[] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (month < 0 || month > 11)
return false;
@@ -235,9 +241,9 @@ static String processFileDateString(const FTPTime& fileTime)
String dateString;
if (fileTime.tm_year > -1)
- dateString = makeString(months[month], ' ', String::number(fileTime.tm_mday), ", ", String::number(fileTime.tm_year));
+ dateString = String(months[month]) + " " + String::number(fileTime.tm_mday) + ", " + String::number(fileTime.tm_year);
else
- dateString = makeString(months[month], ' ', String::number(fileTime.tm_mday), ", ", String::number(now.year()));
+ dateString = String(months[month]) + " " + String::number(fileTime.tm_mday) + ", " + String::number(now.year());
return dateString + timeOfDay;
}
@@ -255,7 +261,7 @@ void FTPDirectoryDocumentParser::parseAndAppendOneLine(const String& inputLine)
String filename(result.filename, result.filenameLength);
if (result.type == FTPDirectoryEntry) {
- filename.append('/');
+ filename.append("/");
// We have no interest in linking to "current directory"
if (filename == "./")
@@ -267,21 +273,22 @@ void FTPDirectoryDocumentParser::parseAndAppendOneLine(const String& inputLine)
appendEntry(filename, processFilesizeString(result.fileSize, result.type == FTPDirectoryEntry), processFileDateString(result.modifiedTime), result.type == FTPDirectoryEntry);
}
-static inline RefPtr<SharedBuffer> createTemplateDocumentData(Settings* settings)
+static inline PassRefPtr<SharedBuffer> createTemplateDocumentData(Settings* settings)
{
- RefPtr<SharedBuffer> buffer;
+ RefPtr<SharedBuffer> buffer = 0;
if (settings)
buffer = SharedBuffer::createWithContentsOfFile(settings->ftpDirectoryTemplatePath());
if (buffer)
LOG(FTP, "Loaded FTPDirectoryTemplate of length %i\n", buffer->size());
- return buffer;
+ return buffer.release();
}
bool FTPDirectoryDocumentParser::loadDocumentTemplate()
{
- static SharedBuffer* templateDocumentData = createTemplateDocumentData(document()->settings()).release().leakRef();
- // FIXME: Instead of storing the data, it would be more efficient if we could parse the template data into the
- // template Document once, store that document, then "copy" it whenever we get an FTP directory listing.
+ static SharedBuffer* templateDocumentData = createTemplateDocumentData(document()->settings()).leakRef();
+ // FIXME: Instead of storing the data, we'd rather actually parse the template data into the template Document once,
+ // store that document, then "copy" it whenever we get an FTP directory listing. There are complexities with this
+ // approach that make it worth putting this off.
if (!templateDocumentData) {
LOG_ERROR("Could not load templateData");
@@ -290,13 +297,13 @@ bool FTPDirectoryDocumentParser::loadDocumentTemplate()
HTMLDocumentParser::insert(String(templateDocumentData->data(), templateDocumentData->size()));
- RefPtr<Element> tableElement = document()->getElementById(String(ASCIILiteral("ftpDirectoryTable")));
+ RefPtr<Element> tableElement = document()->getElementById("ftpDirectoryTable");
if (!tableElement)
LOG_ERROR("Unable to find element by id \"ftpDirectoryTable\" in the template document.");
- else if (!is<HTMLTableElement>(*tableElement))
+ else if (!isHTMLTableElement(tableElement.get()))
LOG_ERROR("Element of id \"ftpDirectoryTable\" is not a table element");
else
- m_tableElement = downcast<HTMLTableElement>(tableElement.get());
+ m_tableElement = toHTMLTableElement(tableElement.get());
// Bail if we found the table element
if (m_tableElement)
@@ -304,13 +311,13 @@ bool FTPDirectoryDocumentParser::loadDocumentTemplate()
// Otherwise create one manually
tableElement = document()->createElement(tableTag, false);
- m_tableElement = downcast<HTMLTableElement>(tableElement.get());
- m_tableElement->setAttribute(HTMLNames::idAttr, "ftpDirectoryTable");
+ m_tableElement = toHTMLTableElement(tableElement.get());
+ m_tableElement->setAttribute("id", "ftpDirectoryTable", IGNORE_EXCEPTION);
// If we didn't find the table element, lets try to append our own to the body
// If that fails for some reason, cram it on the end of the document as a last
// ditch effort
- if (auto* body = document()->bodyOrFrameset())
+ if (Element* body = document()->body())
body->appendChild(m_tableElement, IGNORE_EXCEPTION);
else
document()->appendChild(m_tableElement, IGNORE_EXCEPTION);
@@ -329,13 +336,10 @@ void FTPDirectoryDocumentParser::createBasicDocument()
document()->appendChild(bodyElement, IGNORE_EXCEPTION);
RefPtr<Element> tableElement = document()->createElement(tableTag, false);
- m_tableElement = downcast<HTMLTableElement>(tableElement.get());
- m_tableElement->setAttribute(HTMLNames::idAttr, "ftpDirectoryTable");
- m_tableElement->setAttribute(HTMLNames::styleAttr, "width:100%");
+ m_tableElement = toHTMLTableElement(tableElement.get());
+ m_tableElement->setAttribute("id", "ftpDirectoryTable", IGNORE_EXCEPTION);
bodyElement->appendChild(m_tableElement, IGNORE_EXCEPTION);
-
- document()->processViewport("width=device-width", ViewportArguments::ViewportMeta);
}
void FTPDirectoryDocumentParser::append(PassRefPtr<StringImpl> inputSource)
@@ -411,7 +415,7 @@ void FTPDirectoryDocumentParser::finish()
m_carryOver = String();
}
- m_tableElement = nullptr;
+ m_tableElement = 0;
fastFree(m_buffer);
HTMLDocumentParser::finish();
@@ -425,7 +429,7 @@ FTPDirectoryDocument::FTPDirectoryDocument(Frame* frame, const URL& url)
#endif
}
-Ref<DocumentParser> FTPDirectoryDocument::createParser()
+PassRefPtr<DocumentParser> FTPDirectoryDocument::createParser()
{
return FTPDirectoryDocumentParser::create(*this);
}
diff --git a/Source/WebCore/html/FTPDirectoryDocument.h b/Source/WebCore/html/FTPDirectoryDocument.h
index c156ad6d3..9b99fc9f0 100644
--- a/Source/WebCore/html/FTPDirectoryDocument.h
+++ b/Source/WebCore/html/FTPDirectoryDocument.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
@@ -31,16 +31,16 @@ namespace WebCore {
class DOMImplementation;
-class FTPDirectoryDocument final : public HTMLDocument {
+class FTPDirectoryDocument : public HTMLDocument {
public:
- static Ref<FTPDirectoryDocument> create(Frame* frame, const URL& url)
+ static PassRefPtr<FTPDirectoryDocument> create(Frame* frame, const URL& url)
{
- return adoptRef(*new FTPDirectoryDocument(frame, url));
+ return adoptRef(new FTPDirectoryDocument(frame, url));
}
private:
FTPDirectoryDocument(Frame*, const URL&);
- virtual Ref<DocumentParser> createParser() override;
+ virtual PassRefPtr<DocumentParser> createParser() override;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/FileInputType.cpp b/Source/WebCore/html/FileInputType.cpp
index 489d79938..f7ab6b73e 100644
--- a/Source/WebCore/html/FileInputType.cpp
+++ b/Source/WebCore/html/FileInputType.cpp
@@ -45,34 +45,42 @@ namespace WebCore {
using namespace HTMLNames;
-class UploadButtonElement final : public HTMLInputElement {
+class UploadButtonElement : public HTMLInputElement {
public:
- static Ref<UploadButtonElement> create(Document&);
- static Ref<UploadButtonElement> createForMultiple(Document&);
+ static PassRefPtr<UploadButtonElement> create(Document&);
+ static PassRefPtr<UploadButtonElement> createForMultiple(Document&);
private:
UploadButtonElement(Document&);
+
+ virtual const AtomicString& shadowPseudoId() const override;
};
-Ref<UploadButtonElement> UploadButtonElement::create(Document& document)
+PassRefPtr<UploadButtonElement> UploadButtonElement::create(Document& document)
{
- Ref<UploadButtonElement> button = adoptRef(*new UploadButtonElement(document));
+ RefPtr<UploadButtonElement> button = adoptRef(new UploadButtonElement(document));
+ button->setType("button");
button->setValue(fileButtonChooseFileLabel());
- return button;
+ return button.release();
}
-Ref<UploadButtonElement> UploadButtonElement::createForMultiple(Document& document)
+PassRefPtr<UploadButtonElement> UploadButtonElement::createForMultiple(Document& document)
{
- Ref<UploadButtonElement> button = adoptRef(*new UploadButtonElement(document));
+ RefPtr<UploadButtonElement> button = adoptRef(new UploadButtonElement(document));
+ button->setType("button");
button->setValue(fileButtonChooseMultipleFilesLabel());
- return button;
+ return button.release();
}
UploadButtonElement::UploadButtonElement(Document& document)
: HTMLInputElement(inputTag, document, 0, false)
{
- setType(AtomicString("button", AtomicString::ConstructFromLiteral));
- setPseudo(AtomicString("-webkit-file-upload-button", AtomicString::ConstructFromLiteral));
+}
+
+const AtomicString& UploadButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-file-upload-button", AtomicString::ConstructFromLiteral));
+ return pseudoId;
}
FileInputType::FileInputType(HTMLInputElement& element)
@@ -180,12 +188,17 @@ void FileInputType::handleDOMActivateEvent(Event* event)
if (Chrome* chrome = this->chrome()) {
FileChooserSettings settings;
HTMLInputElement& input = element();
+#if ENABLE(DIRECTORY_UPLOAD)
+ settings.allowsDirectoryUpload = input.fastHasAttribute(webkitdirectoryAttr);
+ settings.allowsMultipleFiles = settings.allowsDirectoryUpload || input.fastHasAttribute(multipleAttr);
+#else
settings.allowsMultipleFiles = input.fastHasAttribute(multipleAttr);
+#endif
settings.acceptMIMETypes = input.acceptMIMETypes();
settings.acceptFileExtensions = input.acceptFileExtensions();
settings.selectedFiles = m_fileList->paths();
#if ENABLE(MEDIA_CAPTURE)
- settings.capture = input.shouldUseMediaCapture();
+ settings.capture = input.capture();
#endif
applyFileChooserSettings(settings);
@@ -195,9 +208,9 @@ void FileInputType::handleDOMActivateEvent(Event* event)
event->setDefaultHandled();
}
-RenderPtr<RenderElement> FileInputType::createInputRenderer(Ref<RenderStyle>&& style)
+RenderPtr<RenderElement> FileInputType::createInputRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderFileUploadControl>(element(), WTF::move(style));
+ return createRenderer<RenderFileUploadControl>(element(), std::move(style));
}
bool FileInputType::canSetStringValue() const
@@ -248,19 +261,44 @@ bool FileInputType::getTypeSpecificValue(String& value)
void FileInputType::setValue(const String&, bool, TextFieldEventBehavior)
{
- // FIXME: Should we clear the file list, or replace it with a new empty one here? This is observable from JavaScript through custom properties.
m_fileList->clear();
- m_icon = nullptr;
+ m_icon.clear();
element().setNeedsStyleRecalc();
}
PassRefPtr<FileList> FileInputType::createFileList(const Vector<FileChooserFileInfo>& files) const
{
- Vector<RefPtr<File>> fileObjects;
- for (const FileChooserFileInfo& info : files)
- fileObjects.append(File::createWithName(info.path, info.displayName));
+ RefPtr<FileList> fileList(FileList::create());
+ size_t size = files.size();
+
+#if ENABLE(DIRECTORY_UPLOAD)
+ // If a directory is being selected, the UI allows a directory to be chosen
+ // and the paths provided here share a root directory somewhere up the tree;
+ // we want to store only the relative paths from that point.
+ if (size && element().fastHasAttribute(webkitdirectoryAttr)) {
+ // Find the common root path.
+ String rootPath = directoryName(files[0].path);
+ for (size_t i = 1; i < size; i++) {
+ while (!files[i].path.startsWith(rootPath))
+ rootPath = directoryName(rootPath);
+ }
+ rootPath = directoryName(rootPath);
+ ASSERT(rootPath.length());
+ int rootLength = rootPath.length();
+ if (rootPath[rootLength - 1] != '\\' && rootPath[rootLength - 1] != '/')
+ rootLength += 1;
+ for (size_t i = 0; i < size; i++) {
+ // Normalize backslashes to slashes before exposing the relative path to script.
+ String relativePath = files[i].path.substring(rootLength).replace('\\', '/');
+ fileList->append(File::createWithRelativePath(files[i].path, relativePath));
+ }
+ return fileList;
+ }
+#endif
- return FileList::create(WTF::move(fileObjects));
+ for (size_t i = 0; i < size; i++)
+ fileList->append(File::createWithName(files[i].path, files[i].displayName, File::AllContentTypes));
+ return fileList;
}
bool FileInputType::isFileUpload() const
@@ -341,7 +379,8 @@ void FileInputType::setFiles(PassRefPtr<FileList> files)
m_fileList = files;
input->setFormControlValueMatchesRenderer(true);
- input->updateValidity();
+ input->notifyFormStateChanged();
+ input->setNeedsValidityCheck();
Vector<String> paths;
for (unsigned i = 0; i < m_fileList->length(); ++i)
@@ -378,6 +417,26 @@ void FileInputType::filesChosen(const Vector<FileChooserFileInfo>& files)
setFiles(createFileList(files));
}
+#if ENABLE(DIRECTORY_UPLOAD)
+void FileInputType::receiveDropForDirectoryUpload(const Vector<String>& paths)
+{
+ Chrome* chrome = this->chrome();
+ if (!chrome)
+ return;
+
+ FileChooserSettings settings;
+ HTMLInputElement* input = element();
+ settings.allowsDirectoryUpload = true;
+ settings.allowsMultipleFiles = true;
+ settings.selectedFiles.append(paths[0]);
+ settings.acceptMIMETypes = input->acceptMIMETypes();
+ settings.acceptFileExtensions = input->acceptFileExtensions();
+
+ applyFileChooserSettings(settings);
+ chrome->enumerateChosenDirectory(m_fileChooser);
+}
+#endif
+
void FileInputType::updateRendering(PassRefPtr<Icon> icon)
{
if (m_icon == icon)
@@ -397,6 +456,12 @@ bool FileInputType::receiveDroppedFiles(const DragData& dragData)
return false;
HTMLInputElement* input = &element();
+#if ENABLE(DIRECTORY_UPLOAD)
+ if (input->fastHasAttribute(webkitdirectoryAttr)) {
+ receiveDropForDirectoryUpload(paths);
+ return true;
+ }
+#endif
Vector<FileChooserFileInfo> files;
for (unsigned i = 0; i < paths.size(); ++i)
diff --git a/Source/WebCore/html/FileInputType.h b/Source/WebCore/html/FileInputType.h
index aaecc06a2..3bbad6c31 100644
--- a/Source/WebCore/html/FileInputType.h
+++ b/Source/WebCore/html/FileInputType.h
@@ -43,7 +43,7 @@ class DragData;
class FileList;
class Icon;
-class FileInputType final : public BaseClickableWithKeyInputType, private FileChooserClient, private FileIconLoaderClient {
+class FileInputType : public BaseClickableWithKeyInputType, private FileChooserClient, private FileIconLoaderClient {
public:
explicit FileInputType(HTMLInputElement&);
virtual ~FileInputType();
@@ -58,7 +58,7 @@ private:
virtual bool valueMissing(const String&) const override;
virtual String valueMissingText() const override;
virtual void handleDOMActivateEvent(Event*) override;
- virtual RenderPtr<RenderElement> createInputRenderer(Ref<RenderStyle>&&) override;
+ virtual RenderPtr<RenderElement> createInputRenderer(PassRef<RenderStyle>) override;
virtual bool canSetStringValue() const override;
virtual bool canChangeFromAnotherType() const override;
virtual FileList* files() override;
@@ -91,6 +91,9 @@ private:
virtual void updateRendering(PassRefPtr<Icon>) override;
PassRefPtr<FileList> createFileList(const Vector<FileChooserFileInfo>& files) const;
+#if ENABLE(DIRECTORY_UPLOAD)
+ void receiveDropForDirectoryUpload(const Vector<String>&);
+#endif
void requestIcon(const Vector<String>&);
void applyFileChooserSettings(const FileChooserSettings&);
diff --git a/Source/WebCore/html/FormAssociatedElement.cpp b/Source/WebCore/html/FormAssociatedElement.cpp
index 474fb65e6..44ee0507a 100644
--- a/Source/WebCore/html/FormAssociatedElement.cpp
+++ b/Source/WebCore/html/FormAssociatedElement.cpp
@@ -68,6 +68,7 @@ void FormAssociatedElement::didMoveToNewDocument(Document* oldDocument)
void FormAssociatedElement::insertedInto(ContainerNode& insertionPoint)
{
+ resetFormOwner();
if (!insertionPoint.inDocument())
return;
@@ -95,10 +96,10 @@ HTMLFormElement* FormAssociatedElement::findAssociatedForm(const HTMLElement* el
// the first element in the document to have an ID that equal to
// the value of form attribute, so we put the result of
// treeScope().getElementById() over the given element.
- HTMLFormElement* newForm = nullptr;
+ HTMLFormElement* newForm = 0;
Element* newFormCandidate = element->treeScope().getElementById(formId);
- if (is<HTMLFormElement>(newFormCandidate))
- newForm = downcast<HTMLFormElement>(newFormCandidate);
+ if (newFormCandidate && isHTMLFormElement(newFormCandidate))
+ newForm = toHTMLFormElement(newFormCandidate);
return newForm;
}
@@ -174,7 +175,7 @@ void FormAssociatedElement::formAttributeChanged()
bool FormAssociatedElement::customError() const
{
- return willValidate() && !m_customValidationMessage.isEmpty();
+ return asHTMLElement().willValidate() && !m_customValidationMessage.isEmpty();
}
bool FormAssociatedElement::hasBadInput() const
diff --git a/Source/WebCore/html/FormAssociatedElement.h b/Source/WebCore/html/FormAssociatedElement.h
index 7df6c39a0..ec9424064 100644
--- a/Source/WebCore/html/FormAssociatedElement.h
+++ b/Source/WebCore/html/FormAssociatedElement.h
@@ -106,7 +106,6 @@ protected:
String customValidationMessage() const;
private:
- virtual bool willValidate() const = 0;
virtual void refFormAssociatedElement() = 0;
virtual void derefFormAssociatedElement() = 0;
@@ -119,6 +118,9 @@ private:
String m_customValidationMessage;
};
+#define FORM_ASSOCIATED_ELEMENT_TYPE_CASTS(ToClassName, predicate) \
+ TYPE_CASTS_BASE(ToClassName, FormAssociatedElement, element, element->predicate, element.predicate)
+
} // namespace
#endif // FormAssociatedElement_h
diff --git a/Source/WebCore/html/FormController.cpp b/Source/WebCore/html/FormController.cpp
index b7df2d4dc..9752d3475 100644
--- a/Source/WebCore/html/FormController.cpp
+++ b/Source/WebCore/html/FormController.cpp
@@ -173,12 +173,8 @@ class SavedFormState {
WTF_MAKE_FAST_ALLOCATED;
public:
- SavedFormState()
- : m_controlStateCount(0)
- {
- }
-
- static std::unique_ptr<SavedFormState> deserialize(const Vector<String>&, size_t& index);
+ static OwnPtr<SavedFormState> create();
+ static OwnPtr<SavedFormState> deserialize(const Vector<String>&, size_t& index);
void serializeTo(Vector<String>&) const;
bool isEmpty() const { return m_stateForNewFormElements.isEmpty(); }
void appendControlState(const AtomicString& name, const AtomicString& type, const FormControlState&);
@@ -187,17 +183,24 @@ public:
Vector<String> getReferencedFilePaths() const;
private:
+ SavedFormState() : m_controlStateCount(0) { }
+
typedef HashMap<FormElementKey, Deque<FormControlState>, FormElementKeyHash, FormElementKeyHashTraits> FormElementStateMap;
FormElementStateMap m_stateForNewFormElements;
size_t m_controlStateCount;
};
+OwnPtr<SavedFormState> SavedFormState::create()
+{
+ return adoptPtr(new SavedFormState);
+}
+
static bool isNotFormControlTypeCharacter(UChar ch)
{
return ch != '-' && (ch > 'z' || ch < 'a');
}
-std::unique_ptr<SavedFormState> SavedFormState::deserialize(const Vector<String>& stateVector, size_t& index)
+OwnPtr<SavedFormState> SavedFormState::deserialize(const Vector<String>& stateVector, size_t& index)
{
if (index >= stateVector.size())
return nullptr;
@@ -205,7 +208,7 @@ std::unique_ptr<SavedFormState> SavedFormState::deserialize(const Vector<String>
size_t itemCount = stateVector[index++].toUInt();
if (!itemCount)
return nullptr;
- auto savedFormState = std::make_unique<SavedFormState>();
+ OwnPtr<SavedFormState> savedFormState = adoptPtr(new SavedFormState);
while (itemCount--) {
if (index + 1 >= stateVector.size())
return nullptr;
@@ -216,7 +219,7 @@ std::unique_ptr<SavedFormState> SavedFormState::deserialize(const Vector<String>
return nullptr;
savedFormState->appendControlState(name, type, state);
}
- return savedFormState;
+ return savedFormState.release();
}
void SavedFormState::serializeTo(Vector<String>& stateVector) const
@@ -286,11 +289,13 @@ class FormKeyGenerator {
WTF_MAKE_FAST_ALLOCATED;
public:
- FormKeyGenerator() = default;
+ static OwnPtr<FormKeyGenerator> create() { return adoptPtr(new FormKeyGenerator); }
AtomicString formKey(const HTMLFormControlElementWithState&);
void willDeleteForm(HTMLFormElement*);
private:
+ FormKeyGenerator() { }
+
typedef HashMap<HTMLFormElement*, AtomicString> FormToKeyMap;
typedef HashMap<String, unsigned> FormSignatureToNextIndexMap;
FormToKeyMap m_formToKeyMap;
@@ -302,7 +307,7 @@ static inline void recordFormStructure(const HTMLFormElement& form, StringBuilde
// 2 is enough to distinguish forms in webkit.org/b/91209#c0
const size_t namedControlsToBeRecorded = 2;
const Vector<FormAssociatedElement*>& controls = form.associatedElements();
- builder.appendLiteral(" [");
+ builder.append(" [");
for (size_t i = 0, namedControls = 0; i < controls.size() && namedControls < namedControlsToBeRecorded; ++i) {
if (!controls[i]->isFormControlElementWithState())
continue;
@@ -314,9 +319,9 @@ static inline void recordFormStructure(const HTMLFormElement& form, StringBuilde
continue;
namedControls++;
builder.append(name);
- builder.append(' ');
+ builder.append(" ");
}
- builder.append(']');
+ builder.append("]");
}
static inline String formSignature(const HTMLFormElement& form)
@@ -337,7 +342,7 @@ AtomicString FormKeyGenerator::formKey(const HTMLFormControlElementWithState& co
{
HTMLFormElement* form = ownerFormForState(control);
if (!form) {
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, formKeyForNoOwner, ("No owner", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, formKeyForNoOwner, ("No owner", AtomicString::ConstructFromLiteral));
return formKeyForNoOwner;
}
FormToKeyMap::const_iterator it = m_formToKeyMap.find(form);
@@ -390,29 +395,29 @@ static String formStateSignature()
// In the legacy version of serialized state, the first item was a name
// attribute value of a form control. The following string literal should
// contain some characters which are rarely used for name attribute values.
- DEPRECATED_DEFINE_STATIC_LOCAL(String, signature, (ASCIILiteral("\n\r?% WebKit serialized form state version 8 \n\r=&")));
+ DEFINE_STATIC_LOCAL(String, signature, (ASCIILiteral("\n\r?% WebKit serialized form state version 8 \n\r=&")));
return signature;
}
-std::unique_ptr<FormController::SavedFormStateMap> FormController::createSavedFormStateMap(const FormElementListHashSet& controlList)
+OwnPtr<FormController::SavedFormStateMap> FormController::createSavedFormStateMap(const FormElementListHashSet& controlList)
{
- FormKeyGenerator keyGenerator;
- auto stateMap = std::make_unique<SavedFormStateMap>();
+ OwnPtr<FormKeyGenerator> keyGenerator = FormKeyGenerator::create();
+ OwnPtr<SavedFormStateMap> stateMap = adoptPtr(new SavedFormStateMap);
for (FormElementListHashSet::const_iterator it = controlList.begin(); it != controlList.end(); ++it) {
HTMLFormControlElementWithState* control = it->get();
if (!control->shouldSaveAndRestoreFormControlState())
continue;
- auto& formState = stateMap->add(keyGenerator.formKey(*control).impl(), nullptr).iterator->value;
- if (!formState)
- formState = std::make_unique<SavedFormState>();
- formState->appendControlState(control->name(), control->type(), control->saveFormControlState());
+ SavedFormStateMap::AddResult result = stateMap->add(keyGenerator->formKey(*control).impl(), nullptr);
+ if (result.isNewEntry)
+ result.iterator->value = SavedFormState::create();
+ result.iterator->value->appendControlState(control->name(), control->type(), control->saveFormControlState());
}
- return stateMap;
+ return stateMap.release();
}
Vector<String> FormController::formElementsState() const
{
- std::unique_ptr<SavedFormStateMap> stateMap = createSavedFormStateMap(m_formElementsWithState);
+ OwnPtr<SavedFormStateMap> stateMap = createSavedFormStateMap(m_formElementsWithState);
Vector<String> stateVector;
stateVector.reserveInitialCapacity(m_formElementsWithState.size() * 4);
stateVector.append(formStateSignature());
@@ -436,7 +441,7 @@ FormControlState FormController::takeStateForFormElement(const HTMLFormControlEl
if (m_savedFormStateMap.isEmpty())
return FormControlState();
if (!m_formKeyGenerator)
- m_formKeyGenerator = std::make_unique<FormKeyGenerator>();
+ m_formKeyGenerator = FormKeyGenerator::create();
SavedFormStateMap::iterator it = m_savedFormStateMap.find(m_formKeyGenerator->formKey(control).impl());
if (it == m_savedFormStateMap.end())
return FormControlState();
@@ -456,12 +461,12 @@ void FormController::formStatesFromStateVector(const Vector<String>& stateVector
while (i + 1 < stateVector.size()) {
AtomicString formKey = stateVector[i++];
- auto state = SavedFormState::deserialize(stateVector, i);
+ OwnPtr<SavedFormState> state = SavedFormState::deserialize(stateVector, i);
if (!state) {
i = 0;
break;
}
- map.add(formKey.impl(), WTF::move(state));
+ map.add(formKey.impl(), state.release());
}
if (i != stateVector.size())
map.clear();
diff --git a/Source/WebCore/html/FormController.h b/Source/WebCore/html/FormController.h
index 14620566a..e146b64f6 100644
--- a/Source/WebCore/html/FormController.h
+++ b/Source/WebCore/html/FormController.h
@@ -74,7 +74,10 @@ inline void FormControlState::append(const String& value)
class FormController {
WTF_MAKE_FAST_ALLOCATED;
public:
- FormController();
+ static OwnPtr<FormController> create()
+ {
+ return adoptPtr(new FormController);
+ }
~FormController();
CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
@@ -92,20 +95,21 @@ public:
void restoreControlStateFor(HTMLFormControlElementWithState&);
void restoreControlStateIn(HTMLFormElement&);
- WEBCORE_EXPORT static Vector<String> getReferencedFilePaths(const Vector<String>& stateVector);
+ static Vector<String> getReferencedFilePaths(const Vector<String>& stateVector);
private:
- typedef ListHashSet<RefPtr<HTMLFormControlElementWithState>> FormElementListHashSet;
- typedef HashMap<RefPtr<AtomicStringImpl>, std::unique_ptr<SavedFormState>> SavedFormStateMap;
+ typedef ListHashSet<RefPtr<HTMLFormControlElementWithState>, 64> FormElementListHashSet;
+ typedef HashMap<RefPtr<AtomicStringImpl>, OwnPtr<SavedFormState>> SavedFormStateMap;
- static std::unique_ptr<SavedFormStateMap> createSavedFormStateMap(const FormElementListHashSet&);
+ FormController();
+ static OwnPtr<SavedFormStateMap> createSavedFormStateMap(const FormElementListHashSet&);
FormControlState takeStateForFormElement(const HTMLFormControlElementWithState&);
static void formStatesFromStateVector(const Vector<String>&, SavedFormStateMap&);
CheckedRadioButtons m_checkedRadioButtons;
FormElementListHashSet m_formElementsWithState;
SavedFormStateMap m_savedFormStateMap;
- std::unique_ptr<FormKeyGenerator> m_formKeyGenerator;
+ OwnPtr<FormKeyGenerator> m_formKeyGenerator;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/FormDataList.cpp b/Source/WebCore/html/FormDataList.cpp
index 136b6af7b..48fc62969 100644
--- a/Source/WebCore/html/FormDataList.cpp
+++ b/Source/WebCore/html/FormDataList.cpp
@@ -22,7 +22,6 @@
#include "FormDataList.h"
#include "LineEnding.h"
-#include <wtf/text/StringView.h>
namespace WebCore {
@@ -33,7 +32,7 @@ FormDataList::FormDataList(const TextEncoding& c)
void FormDataList::appendString(const String& s)
{
- CString cstr = m_encoding.encode(s, EntitiesForUnencodables);
+ CString cstr = m_encoding.encode(s.deprecatedCharacters(), s.length(), EntitiesForUnencodables);
m_items.append(normalizeLineEndingsToCRLF(cstr));
}
diff --git a/Source/WebCore/html/HTMLAllCollection.cpp b/Source/WebCore/html/HTMLAllCollection.cpp
index 01668714e..1812ab176 100644
--- a/Source/WebCore/html/HTMLAllCollection.cpp
+++ b/Source/WebCore/html/HTMLAllCollection.cpp
@@ -30,33 +30,36 @@
namespace WebCore {
-Ref<HTMLAllCollection> HTMLAllCollection::create(Document& document, CollectionType type)
+PassRef<HTMLAllCollection> HTMLAllCollection::create(Document& document, CollectionType type)
{
return adoptRef(*new HTMLAllCollection(document, type));
}
-inline HTMLAllCollection::HTMLAllCollection(Document& document, CollectionType type)
+HTMLAllCollection::HTMLAllCollection(Document& document, CollectionType type)
: HTMLCollection(document, type)
{
}
-Element* HTMLAllCollection::namedItemWithIndex(const AtomicString& name, unsigned index) const
+HTMLAllCollection::~HTMLAllCollection()
{
- updateNamedElementCache();
- const CollectionNamedElementCache& cache = namedItemCaches();
+}
+
+Node* HTMLAllCollection::namedItemWithIndex(const AtomicString& name, unsigned index) const
+{
+ updateNameCache();
- if (const Vector<Element*>* elements = cache.findElementsWithId(name)) {
- if (index < elements->size())
- return elements->at(index);
- index -= elements->size();
+ if (Vector<Element*>* cache = idCache(name)) {
+ if (index < cache->size())
+ return cache->at(index);
+ index -= cache->size();
}
- if (const Vector<Element*>* elements = cache.findElementsWithName(name)) {
- if (index < elements->size())
- return elements->at(index);
+ if (Vector<Element*>* cache = nameCache(name)) {
+ if (index < cache->size())
+ return cache->at(index);
}
- return nullptr;
+ return 0;
}
} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLAllCollection.h b/Source/WebCore/html/HTMLAllCollection.h
index 51451174b..6c93aea72 100644
--- a/Source/WebCore/html/HTMLAllCollection.h
+++ b/Source/WebCore/html/HTMLAllCollection.h
@@ -32,9 +32,10 @@ namespace WebCore {
class HTMLAllCollection final : public HTMLCollection {
public:
- static Ref<HTMLAllCollection> create(Document&, CollectionType);
+ static PassRef<HTMLAllCollection> create(Document&, CollectionType);
+ virtual ~HTMLAllCollection();
- Element* namedItemWithIndex(const AtomicString& name, unsigned index) const;
+ Node* namedItemWithIndex(const AtomicString& name, unsigned index) const;
private:
HTMLAllCollection(Document&, CollectionType);
@@ -42,6 +43,4 @@ private:
} // namespace WebCore
-SPECIALIZE_TYPE_TRAITS_HTMLCOLLECTION(HTMLAllCollection, DocAll)
-
#endif // HTMLAllCollection_h
diff --git a/Source/WebCore/html/HTMLAnchorElement.cpp b/Source/WebCore/html/HTMLAnchorElement.cpp
index 5bd7e58b4..053e57f7f 100644
--- a/Source/WebCore/html/HTMLAnchorElement.cpp
+++ b/Source/WebCore/html/HTMLAnchorElement.cpp
@@ -24,8 +24,8 @@
#include "config.h"
#include "HTMLAnchorElement.h"
+#include "Attribute.h"
#include "DNS.h"
-#include "ElementIterator.h"
#include "EventHandler.h"
#include "EventNames.h"
#include "Frame.h"
@@ -33,14 +33,12 @@
#include "FrameLoaderClient.h"
#include "FrameLoaderTypes.h"
#include "FrameSelection.h"
-#include "HTMLCanvasElement.h"
#include "HTMLImageElement.h"
#include "HTMLParserIdioms.h"
#include "KeyboardEvent.h"
#include "MouseEvent.h"
#include "PingLoader.h"
#include "PlatformMouseEvent.h"
-#include "RelList.h"
#include "RenderImage.h"
#include "ResourceRequest.h"
#include "SVGImage.h"
@@ -62,14 +60,14 @@ HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document& doc
{
}
-Ref<HTMLAnchorElement> HTMLAnchorElement::create(Document& document)
+PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(Document& document)
{
- return adoptRef(*new HTMLAnchorElement(aTag, document));
+ return adoptRef(new HTMLAnchorElement(aTag, document));
}
-Ref<HTMLAnchorElement> HTMLAnchorElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLAnchorElement(tagName, document));
+ return adoptRef(new HTMLAnchorElement(tagName, document));
}
HTMLAnchorElement::~HTMLAnchorElement()
@@ -144,7 +142,7 @@ bool HTMLAnchorElement::isKeyboardFocusable(KeyboardEvent* event) const
if (!document().frame()->eventHandler().tabsToLinks(event))
return false;
- if (!renderer() && ancestorsOfType<HTMLCanvasElement>(*this).first())
+ if (isInCanvasSubtree())
return true;
return hasNonEmptyBox(renderBoxModelObject());
@@ -152,26 +150,25 @@ bool HTMLAnchorElement::isKeyboardFocusable(KeyboardEvent* event) const
static void appendServerMapMousePosition(StringBuilder& url, Event* event)
{
- ASSERT(event);
- if (!is<MouseEvent>(*event))
+ if (!event->isMouseEvent())
return;
ASSERT(event->target());
Node* target = event->target()->toNode();
ASSERT(target);
- if (!is<HTMLImageElement>(*target))
+ if (!isHTMLImageElement(target))
return;
- HTMLImageElement& imageElement = downcast<HTMLImageElement>(*target);
- if (!imageElement.isServerMap())
+ HTMLImageElement* imageElement = toHTMLImageElement(target);
+ if (!imageElement || !imageElement->isServerMap())
return;
- if (!is<RenderImage>(imageElement.renderer()))
+ if (!imageElement->renderer() || !imageElement->renderer()->isRenderImage())
return;
- auto& renderer = downcast<RenderImage>(*imageElement.renderer());
+ RenderImage* renderer = toRenderImage(imageElement->renderer());
// FIXME: This should probably pass true for useTransforms.
- FloatPoint absolutePosition = renderer.absoluteToLocal(FloatPoint(downcast<MouseEvent>(*event).pageX(), downcast<MouseEvent>(*event).pageY()));
+ FloatPoint absolutePosition = renderer->absoluteToLocal(FloatPoint(static_cast<MouseEvent*>(event)->pageX(), static_cast<MouseEvent*>(event)->pageY()));
int x = absolutePosition.x();
int y = absolutePosition.y();
url.append('?');
@@ -189,7 +186,7 @@ void HTMLAnchorElement::defaultEventHandler(Event* event)
return;
}
- if (MouseEvent::canTriggerActivationBehavior(*event) && treatLinkAsLiveForEventType(eventType(event))) {
+ if (isLinkClick(event) && treatLinkAsLiveForEventType(eventType(event))) {
handleClick(event);
return;
}
@@ -197,9 +194,9 @@ void HTMLAnchorElement::defaultEventHandler(Event* event)
if (hasEditableStyle()) {
// This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked
// for the LiveWhenNotFocused editable link behavior
- if (event->type() == eventNames().mousedownEvent && is<MouseEvent>(*event) && downcast<MouseEvent>(*event).button() != RightButton && document().frame()) {
- setRootEditableElementForSelectionOnMouseDown(document().frame()->selection().selection().rootEditableElement());
- m_wasShiftKeyDownOnMouseDown = downcast<MouseEvent>(*event).shiftKey();
+ if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() != RightButton && document().frame()) {
+ setRootEditableElementForSelectionOnMouseDown(document().frame()->selection().rootEditableElement());
+ m_wasShiftKeyDownOnMouseDown = static_cast<MouseEvent*>(event)->shiftKey();
} else if (event->type() == eventNames().mouseoverEvent) {
// These are cleared on mouseover and not mouseout because their values are needed for drag events,
// but drag events happen after mouse out events.
@@ -231,7 +228,7 @@ void HTMLAnchorElement::setActive(bool down, bool pause)
// Don't set the link to be active if the current selection is in the same editable block as
// this link
case EditableLinkLiveWhenNotFocused:
- if (down && document().frame() && document().frame()->selection().selection().rootEditableElement() == rootEditableElement())
+ if (down && document().frame() && document().frame()->selection().rootEditableElement() == rootEditableElement())
return;
break;
@@ -250,7 +247,7 @@ void HTMLAnchorElement::parseAttribute(const QualifiedName& name, const AtomicSt
bool wasLink = isLink();
setIsLink(!value.isNull() && !shouldProhibitLinks(this));
if (wasLink != isLink())
- setNeedsStyleRecalc();
+ didAffectSelector(AffectedSelectorLink | AffectedSelectorVisited | AffectedSelectorEnabled);
if (isLink()) {
String parsedURL = stripLeadingAndTrailingHTMLSpaces(value);
if (document().isDNSPrefetchEnabled()) {
@@ -261,12 +258,8 @@ void HTMLAnchorElement::parseAttribute(const QualifiedName& name, const AtomicSt
invalidateCachedVisitedLinkHash();
} else if (name == nameAttr || name == titleAttr) {
// Do nothing.
- } else if (name == relAttr) {
- if (SpaceSplitString::spaceSplitStringContainsValue(value, "noreferrer", true))
- m_linkRelations |= RelationNoReferrer;
- if (m_relList)
- m_relList->updateRelAttribute(value);
- }
+ } else if (name == relAttr)
+ setRel(value);
else
HTMLElement::parseAttribute(name, value);
}
@@ -283,6 +276,7 @@ bool HTMLAnchorElement::isURLAttribute(const Attribute& attribute) const
bool HTMLAnchorElement::canStartSelection() const
{
+ // FIXME: We probably want this same behavior in SVGAElement too
if (!isLink())
return HTMLElement::canStartSelection();
return hasEditableStyle();
@@ -291,7 +285,7 @@ bool HTMLAnchorElement::canStartSelection() const
bool HTMLAnchorElement::draggable() const
{
// Should be draggable if we have an href attribute.
- const AtomicString& value = fastGetAttribute(draggableAttr);
+ const AtomicString& value = getAttribute(draggableAttr);
if (equalIgnoringCase(value, "true"))
return true;
if (equalIgnoringCase(value, "false"))
@@ -314,11 +308,10 @@ bool HTMLAnchorElement::hasRel(uint32_t relation) const
return m_linkRelations & relation;
}
-DOMTokenList& HTMLAnchorElement::relList()
+void HTMLAnchorElement::setRel(const String& value)
{
- if (!m_relList)
- m_relList = std::make_unique<RelList>(*this);
- return *m_relList;
+ if (SpaceSplitString::spaceSplitStringContainsValue(value, "noreferrer", true))
+ m_linkRelations |= RelationNoReferrer;
}
const AtomicString& HTMLAnchorElement::name() const
@@ -487,7 +480,8 @@ String HTMLAnchorElement::search() const
String HTMLAnchorElement::origin() const
{
- return SecurityOrigin::create(href()).get().toString();
+ RefPtr<SecurityOrigin> origin = SecurityOrigin::create(href());
+ return origin->toString();
}
void HTMLAnchorElement::setSearch(const String& value)
@@ -502,12 +496,7 @@ void HTMLAnchorElement::setSearch(const String& value)
String HTMLAnchorElement::text()
{
- return textContent();
-}
-
-void HTMLAnchorElement::setText(const String& text, ExceptionCode& ec)
-{
- setTextContent(text, ec);
+ return innerText();
}
String HTMLAnchorElement::toString() const
@@ -522,12 +511,12 @@ bool HTMLAnchorElement::isLiveLink() const
void HTMLAnchorElement::sendPings(const URL& destinationURL)
{
- if (!fastHasAttribute(pingAttr) || !document().settings() || !document().settings()->hyperlinkAuditingEnabled())
+ if (!hasAttribute(pingAttr) || !document().settings() || !document().settings()->hyperlinkAuditingEnabled())
return;
- SpaceSplitString pingURLs(fastGetAttribute(pingAttr), false);
+ SpaceSplitString pingURLs(getAttribute(pingAttr), false);
for (unsigned i = 0; i < pingURLs.size(); i++)
- PingLoader::sendPing(*document().frame(), document().completeURL(pingURLs[i]), destinationURL);
+ PingLoader::sendPing(document().frame(), document().completeURL(pingURLs[i]), destinationURL);
}
void HTMLAnchorElement::handleClick(Event* event)
@@ -558,18 +547,16 @@ void HTMLAnchorElement::handleClick(Event* event)
frame->loader().client().startDownload(request, fastGetAttribute(downloadAttr));
} else
#endif
-
- frame->loader().urlSelected(kurl, target(), event, LockHistory::No, LockBackForwardList::No, hasRel(RelationNoReferrer) ? NeverSendReferrer : MaybeSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate());
+ frame->loader().urlSelected(kurl, target(), event, false, false, hasRel(RelationNoReferrer) ? NeverSendReferrer : MaybeSendReferrer);
sendPings(kurl);
}
HTMLAnchorElement::EventType HTMLAnchorElement::eventType(Event* event)
{
- ASSERT(event);
- if (!is<MouseEvent>(*event))
+ if (!event->isMouseEvent())
return NonMouseEvent;
- return downcast<MouseEvent>(*event).shiftKey() ? MouseEventWithShiftKey : MouseEventWithoutShiftKey;
+ return static_cast<MouseEvent*>(event)->shiftKey() ? MouseEventWithShiftKey : MouseEventWithoutShiftKey;
}
bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const
@@ -604,12 +591,22 @@ bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const
bool isEnterKeyKeydownEvent(Event* event)
{
- return event->type() == eventNames().keydownEvent && is<KeyboardEvent>(*event) && downcast<KeyboardEvent>(*event).keyIdentifier() == "Enter";
+ return event->type() == eventNames().keydownEvent && event->isKeyboardEvent() && static_cast<KeyboardEvent*>(event)->keyIdentifier() == "Enter";
+}
+
+bool isLinkClick(Event* event)
+{
+ return event->type() == eventNames().clickEvent && (!event->isMouseEvent() || static_cast<MouseEvent*>(event)->button() != RightButton);
}
bool shouldProhibitLinks(Element* element)
{
+#if ENABLE(SVG)
return isInSVGImage(element);
+#else
+ UNUSED_PARAM(element);
+ return false;
+#endif
}
bool HTMLAnchorElement::willRespondToMouseClickEvents()
@@ -621,7 +618,7 @@ typedef HashMap<const HTMLAnchorElement*, RefPtr<Element>> RootEditableElementMa
static RootEditableElementMap& rootEditableElementMap()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(RootEditableElementMap, map, ());
+ DEFINE_STATIC_LOCAL(RootEditableElementMap, map, ());
return map;
}
diff --git a/Source/WebCore/html/HTMLAnchorElement.h b/Source/WebCore/html/HTMLAnchorElement.h
index 4b66a0145..466916325 100644
--- a/Source/WebCore/html/HTMLAnchorElement.h
+++ b/Source/WebCore/html/HTMLAnchorElement.h
@@ -30,8 +30,6 @@
namespace WebCore {
-class RelList;
-
// Link relation bitmask values.
// FIXME: Uncomment as the various link relations are implemented.
enum {
@@ -57,8 +55,8 @@ enum {
class HTMLAnchorElement : public HTMLElement {
public:
- static Ref<HTMLAnchorElement> create(Document&);
- static Ref<HTMLAnchorElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLAnchorElement> create(Document&);
+ static PassRefPtr<HTMLAnchorElement> create(const QualifiedName&, Document&);
virtual ~HTMLAnchorElement();
@@ -91,21 +89,19 @@ public:
String origin() const;
String text();
- void setText(const String&, ExceptionCode&);
String toString() const;
bool isLiveLink() const;
- virtual bool willRespondToMouseClickEvents() override final;
+ virtual bool willRespondToMouseClickEvents() override;
bool hasRel(uint32_t relation) const;
+ void setRel(const String&);
LinkHash visitedLinkHash() const;
void invalidateCachedVisitedLinkHash() { m_cachedVisitedLinkHash = 0; }
- DOMTokenList& relList();
-
protected:
HTMLAnchorElement(const QualifiedName&, Document&);
@@ -115,14 +111,14 @@ private:
virtual bool supportsFocus() const override;
virtual bool isMouseFocusable() const override;
virtual bool isKeyboardFocusable(KeyboardEvent*) const override;
- virtual void defaultEventHandler(Event*) override final;
+ virtual void defaultEventHandler(Event*) override;
virtual void setActive(bool active = true, bool pause = false) override final;
- virtual void accessKeyAction(bool sendMouseEvents) override final;
- virtual bool isURLAttribute(const Attribute&) const override final;
- virtual bool canStartSelection() const override final;
+ virtual void accessKeyAction(bool sendMouseEvents) override;
+ virtual bool isURLAttribute(const Attribute&) const override;
+ virtual bool canStartSelection() const override;
virtual String target() const override;
virtual short tabIndex() const override final;
- virtual bool draggable() const override final;
+ virtual bool draggable() const override;
void sendPings(const URL& destinationURL);
@@ -144,8 +140,6 @@ private:
bool m_wasShiftKeyDownOnMouseDown : 1;
uint32_t m_linkRelations : 30;
mutable LinkHash m_cachedVisitedLinkHash;
-
- std::unique_ptr<RelList> m_relList;
};
inline LinkHash HTMLAnchorElement::visitedLinkHash() const
@@ -158,8 +152,11 @@ inline LinkHash HTMLAnchorElement::visitedLinkHash() const
// Functions shared with the other anchor elements (i.e., SVG).
bool isEnterKeyKeydownEvent(Event*);
+bool isLinkClick(Event*);
bool shouldProhibitLinks(Element*);
+NODE_TYPE_CASTS(HTMLAnchorElement)
+
} // namespace WebCore
#endif // HTMLAnchorElement_h
diff --git a/Source/WebCore/html/HTMLAnchorElement.idl b/Source/WebCore/html/HTMLAnchorElement.idl
index 8ed588bda..df6836282 100644
--- a/Source/WebCore/html/HTMLAnchorElement.idl
+++ b/Source/WebCore/html/HTMLAnchorElement.idl
@@ -44,7 +44,6 @@ interface HTMLAnchorElement : HTMLElement {
readonly attribute DOMString port;
readonly attribute DOMString protocol;
readonly attribute DOMString search;
- readonly attribute DOMString text;
#else
[TreatNullAs=NullString] attribute DOMString hash;
[TreatNullAs=NullString] attribute DOMString host;
@@ -53,10 +52,12 @@ interface HTMLAnchorElement : HTMLElement {
[TreatNullAs=NullString] attribute DOMString port;
[TreatNullAs=NullString] attribute DOMString protocol;
[TreatNullAs=NullString] attribute DOMString search;
+
[TreatNullAs=NullString] readonly attribute DOMString origin;
- [SetterRaisesException] attribute DOMString text;
#endif
+ readonly attribute DOMString text;
+
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
[NotEnumerable] DOMString toString();
#endif
@@ -65,7 +66,5 @@ interface HTMLAnchorElement : HTMLElement {
// Objective-C extension:
readonly attribute URL absoluteLinkURL;
#endif
-
- readonly attribute DOMTokenList relList;
};
diff --git a/Source/WebCore/html/HTMLAppletElement.cpp b/Source/WebCore/html/HTMLAppletElement.cpp
index 5b5ea688c..ca6fd25ef 100644
--- a/Source/WebCore/html/HTMLAppletElement.cpp
+++ b/Source/WebCore/html/HTMLAppletElement.cpp
@@ -48,9 +48,9 @@ HTMLAppletElement::HTMLAppletElement(const QualifiedName& tagName, Document& doc
m_serviceType = "application/x-java-applet";
}
-Ref<HTMLAppletElement> HTMLAppletElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
+PassRefPtr<HTMLAppletElement> HTMLAppletElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
{
- return adoptRef(*new HTMLAppletElement(tagName, document, createdByParser));
+ return adoptRef(new HTMLAppletElement(tagName, document, createdByParser));
}
void HTMLAppletElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -75,23 +75,23 @@ bool HTMLAppletElement::rendererIsNeeded(const RenderStyle& style)
return HTMLPlugInImageElement::rendererIsNeeded(style);
}
-RenderPtr<RenderElement> HTMLAppletElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLAppletElement::createElementRenderer(PassRef<RenderStyle> style)
{
if (!canEmbedJava())
- return RenderElement::createFor(*this, WTF::move(style));
+ return RenderElement::createFor(*this, std::move(style));
- return RenderEmbeddedObject::createForApplet(*this, WTF::move(style));
+ return RenderEmbeddedObject::createForApplet(*this, std::move(style));
}
-RenderWidget* HTMLAppletElement::renderWidgetLoadingPlugin() const
+RenderWidget* HTMLAppletElement::renderWidgetForJSBindings() const
{
if (!canEmbedJava())
- return nullptr;
+ return 0;
// Needs to load the plugin immediatedly because this function is called
// when JavaScript code accesses the plugin.
// FIXME: <rdar://16893708> Check if dispatching events here is safe.
- document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
+ document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasksSynchronously);
return renderWidget();
}
@@ -117,19 +117,19 @@ void HTMLAppletElement::updateWidget(PluginCreationOption pluginCreationOption)
RenderEmbeddedObject* renderer = renderEmbeddedObject();
LayoutUnit contentWidth = renderer->style().width().isFixed() ? LayoutUnit(renderer->style().width().value()) :
- renderer->width() - renderer->horizontalBorderAndPaddingExtent();
+ renderer->width() - renderer->borderAndPaddingWidth();
LayoutUnit contentHeight = renderer->style().height().isFixed() ? LayoutUnit(renderer->style().height().value()) :
- renderer->height() - renderer->verticalBorderAndPaddingExtent();
+ renderer->height() - renderer->borderAndPaddingHeight();
Vector<String> paramNames;
Vector<String> paramValues;
paramNames.append("code");
- paramValues.append(fastGetAttribute(codeAttr).string());
+ paramValues.append(getAttribute(codeAttr).string());
- const AtomicString& codeBase = fastGetAttribute(codebaseAttr);
+ const AtomicString& codeBase = getAttribute(codebaseAttr);
if (!codeBase.isNull()) {
- paramNames.append(ASCIILiteral("codeBase"));
+ paramNames.append("codeBase");
paramValues.append(codeBase.string());
}
@@ -139,18 +139,18 @@ void HTMLAppletElement::updateWidget(PluginCreationOption pluginCreationOption)
paramValues.append(name.string());
}
- const AtomicString& archive = fastGetAttribute(archiveAttr);
+ const AtomicString& archive = getAttribute(archiveAttr);
if (!archive.isNull()) {
- paramNames.append(ASCIILiteral("archive"));
+ paramNames.append("archive");
paramValues.append(archive.string());
}
- paramNames.append(ASCIILiteral("baseURL"));
+ paramNames.append("baseURL");
paramValues.append(document().baseURL().string());
- const AtomicString& mayScript = fastGetAttribute(mayscriptAttr);
+ const AtomicString& mayScript = getAttribute(mayscriptAttr);
if (!mayScript.isNull()) {
- paramNames.append(ASCIILiteral("mayScript"));
+ paramNames.append("mayScript");
paramValues.append(mayScript.string());
}
diff --git a/Source/WebCore/html/HTMLAppletElement.h b/Source/WebCore/html/HTMLAppletElement.h
index ea8941e58..fcfc09ac5 100644
--- a/Source/WebCore/html/HTMLAppletElement.h
+++ b/Source/WebCore/html/HTMLAppletElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLAppletElement final : public HTMLPlugInImageElement {
public:
- static Ref<HTMLAppletElement> create(const QualifiedName&, Document&, bool createdByParser);
+ static PassRefPtr<HTMLAppletElement> create(const QualifiedName&, Document&, bool createdByParser);
private:
HTMLAppletElement(const QualifiedName&, Document&, bool createdByParser);
@@ -37,9 +37,9 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
virtual bool rendererIsNeeded(const RenderStyle&) override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
- virtual RenderWidget* renderWidgetLoadingPlugin() const override;
+ virtual RenderWidget* renderWidgetForJSBindings() const override;
virtual void updateWidget(PluginCreationOption) override;
bool canEmbedJava() const;
diff --git a/Source/WebCore/html/HTMLAreaElement.cpp b/Source/WebCore/html/HTMLAreaElement.cpp
index 5a0ad839a..5eeb31e46 100644
--- a/Source/WebCore/html/HTMLAreaElement.cpp
+++ b/Source/WebCore/html/HTMLAreaElement.cpp
@@ -23,6 +23,7 @@
#include "HTMLAreaElement.h"
#include "AffineTransform.h"
+#include "Attribute.h"
#include "Frame.h"
#include "HTMLImageElement.h"
#include "HTMLMapElement.h"
@@ -44,9 +45,9 @@ inline HTMLAreaElement::HTMLAreaElement(const QualifiedName& tagName, Document&
ASSERT(hasTagName(areaTag));
}
-Ref<HTMLAreaElement> HTMLAreaElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLAreaElement> HTMLAreaElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLAreaElement(tagName, document));
+ return adoptRef(new HTMLAreaElement(tagName, document));
}
void HTMLAreaElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -78,7 +79,7 @@ void HTMLAreaElement::invalidateCachedRegion()
bool HTMLAreaElement::mapMouseEvent(LayoutPoint location, const LayoutSize& size, HitTestResult& result)
{
if (m_lastSize != size) {
- m_region = std::make_unique<Path>(getRegion(size));
+ m_region = adoptPtr(new Path(getRegion(size)));
m_lastSize = size;
}
@@ -142,29 +143,30 @@ Path HTMLAreaElement::getRegion(const LayoutSize& size) const
}
Path path;
+ RenderView* renderView = document().renderView();
switch (shape) {
case Poly:
if (m_coordsLen >= 6) {
int numPoints = m_coordsLen / 2;
- path.moveTo(FloatPoint(minimumValueForLength(m_coords[0], width), minimumValueForLength(m_coords[1], height)));
+ path.moveTo(FloatPoint(minimumValueForLength(m_coords[0], width, renderView), minimumValueForLength(m_coords[1], height, renderView)));
for (int i = 1; i < numPoints; ++i)
- path.addLineTo(FloatPoint(minimumValueForLength(m_coords[i * 2], width), minimumValueForLength(m_coords[i * 2 + 1], height)));
+ path.addLineTo(FloatPoint(minimumValueForLength(m_coords[i * 2], width, renderView), minimumValueForLength(m_coords[i * 2 + 1], height, renderView)));
path.closeSubpath();
}
break;
case Circle:
if (m_coordsLen >= 3) {
Length radius = m_coords[2];
- int r = std::min(minimumValueForLength(radius, width), minimumValueForLength(radius, height));
- path.addEllipse(FloatRect(minimumValueForLength(m_coords[0], width) - r, minimumValueForLength(m_coords[1], height) - r, 2 * r, 2 * r));
+ int r = std::min(minimumValueForLength(radius, width, renderView), minimumValueForLength(radius, height, renderView));
+ path.addEllipse(FloatRect(minimumValueForLength(m_coords[0], width, renderView) - r, minimumValueForLength(m_coords[1], height, renderView) - r, 2 * r, 2 * r));
}
break;
case Rect:
if (m_coordsLen >= 4) {
- int x0 = minimumValueForLength(m_coords[0], width);
- int y0 = minimumValueForLength(m_coords[1], height);
- int x1 = minimumValueForLength(m_coords[2], width);
- int y1 = minimumValueForLength(m_coords[3], height);
+ int x0 = minimumValueForLength(m_coords[0], width, renderView);
+ int y0 = minimumValueForLength(m_coords[1], height, renderView);
+ int x1 = minimumValueForLength(m_coords[2], width, renderView);
+ int y1 = minimumValueForLength(m_coords[3], height, renderView);
path.addRect(FloatRect(x0, y0, x1 - x0, y1 - y0));
}
break;
@@ -181,10 +183,10 @@ Path HTMLAreaElement::getRegion(const LayoutSize& size) const
HTMLImageElement* HTMLAreaElement::imageElement() const
{
Node* mapElement = parentNode();
- if (!is<HTMLMapElement>(mapElement))
- return nullptr;
+ if (!mapElement || !isHTMLMapElement(mapElement))
+ return 0;
- return downcast<HTMLMapElement>(*mapElement).imageElement();
+ return toHTMLMapElement(mapElement)->imageElement();
}
bool HTMLAreaElement::isKeyboardFocusable(KeyboardEvent*) const
@@ -217,11 +219,11 @@ void HTMLAreaElement::setFocus(bool shouldBeFocused)
if (!imageElement)
return;
- auto* renderer = imageElement->renderer();
- if (!is<RenderImage>(renderer))
+ auto renderer = imageElement->renderer();
+ if (!renderer || !renderer->isRenderImage())
return;
- downcast<RenderImage>(*renderer).areaElementFocusChanged(this);
+ toRenderImage(renderer)->areaElementFocusChanged(this);
}
void HTMLAreaElement::updateFocusAppearance(bool restorePreviousSelection)
diff --git a/Source/WebCore/html/HTMLAreaElement.h b/Source/WebCore/html/HTMLAreaElement.h
index c8e4bf95a..ae6c2a8bb 100644
--- a/Source/WebCore/html/HTMLAreaElement.h
+++ b/Source/WebCore/html/HTMLAreaElement.h
@@ -35,7 +35,7 @@ class Path;
class HTMLAreaElement final : public HTMLAnchorElement {
public:
- static Ref<HTMLAreaElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLAreaElement> create(const QualifiedName&, Document&);
bool isDefault() const { return m_shape == Default; }
@@ -64,13 +64,15 @@ private:
Path getRegion(const LayoutSize&) const;
void invalidateCachedRegion();
- std::unique_ptr<Path> m_region;
+ OwnPtr<Path> m_region;
std::unique_ptr<Length[]> m_coords;
int m_coordsLen;
LayoutSize m_lastSize;
Shape m_shape;
};
+NODE_TYPE_CASTS(HTMLAreaElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLAreaElement.idl b/Source/WebCore/html/HTMLAreaElement.idl
index 8f3f3304b..d0250529b 100644
--- a/Source/WebCore/html/HTMLAreaElement.idl
+++ b/Source/WebCore/html/HTMLAreaElement.idl
@@ -24,7 +24,6 @@ interface HTMLAreaElement : HTMLElement {
[Reflect, URL] attribute DOMString href;
[Reflect] attribute boolean noHref;
[Reflect] attribute DOMString ping;
- [Reflect] attribute DOMString rel;
[Reflect] attribute DOMString shape;
[Reflect] attribute DOMString target;
@@ -44,7 +43,5 @@ interface HTMLAreaElement : HTMLElement {
// Objective-C extension:
readonly attribute URL absoluteLinkURL;
#endif
-
- readonly attribute DOMTokenList relList;
};
diff --git a/Source/WebCore/html/HTMLAttachmentElement.cpp b/Source/WebCore/html/HTMLAttachmentElement.cpp
deleted file mode 100644
index 2f261a592..000000000
--- a/Source/WebCore/html/HTMLAttachmentElement.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "HTMLAttachmentElement.h"
-
-#if ENABLE(ATTACHMENT_ELEMENT)
-
-#include "File.h"
-#include "HTMLNames.h"
-#include "RenderAttachment.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-HTMLAttachmentElement::HTMLAttachmentElement(const QualifiedName& tagName, Document& document)
- : HTMLElement(tagName, document)
-{
- ASSERT(hasTagName(attachmentTag));
-}
-
-HTMLAttachmentElement::~HTMLAttachmentElement()
-{
-}
-
-Ref<HTMLAttachmentElement> HTMLAttachmentElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(*new HTMLAttachmentElement(tagName, document));
-}
-
-RenderPtr<RenderElement> HTMLAttachmentElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
-{
- return createRenderer<RenderAttachment>(*this, WTF::move(style));
-}
-
-File* HTMLAttachmentElement::file() const
-{
- return m_file.get();
-}
-
-void HTMLAttachmentElement::setFile(File* file)
-{
- m_file = file;
-
- auto* renderer = this->renderer();
- if (!is<RenderAttachment>(renderer))
- return;
-
- downcast<RenderAttachment>(*renderer).invalidate();
-}
-
-void HTMLAttachmentElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
-{
- if ((name == progressAttr || name == titleAttr || name == subtitleAttr) && is<RenderAttachment>(renderer())) {
- downcast<RenderAttachment>(*renderer()).invalidate();
- return;
- }
-
- HTMLElement::parseAttribute(name, value);
-}
-
-String HTMLAttachmentElement::attachmentTitle() const
-{
- String title = fastGetAttribute(titleAttr);
- if (!title.isEmpty())
- return title;
- return m_file ? m_file->name() : String();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(ATTACHMENT_ELEMENT)
diff --git a/Source/WebCore/html/HTMLAttachmentElement.h b/Source/WebCore/html/HTMLAttachmentElement.h
deleted file mode 100644
index 46a34ed91..000000000
--- a/Source/WebCore/html/HTMLAttachmentElement.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLAttachmentElement_h
-#define HTMLAttachmentElement_h
-
-#if ENABLE(ATTACHMENT_ELEMENT)
-
-#include "HTMLElement.h"
-
-namespace WebCore {
-
-class File;
-
-class HTMLAttachmentElement final : public HTMLElement {
-public:
- static Ref<HTMLAttachmentElement> create(const QualifiedName&, Document&);
- File* file() const;
- void setFile(File*);
-
- String attachmentTitle() const;
-
-private:
- HTMLAttachmentElement(const QualifiedName&, Document&);
- virtual ~HTMLAttachmentElement();
-
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
-
- virtual bool shouldSelectOnMouseDown() override { return true; }
- virtual bool canContainRangeEndPoint() const override { return false; }
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
-
- RefPtr<File> m_file;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(ATTACHMENT_ELEMENT)
-#endif // HTMLAttachmentElement_h
diff --git a/Source/WebCore/html/HTMLAttachmentElement.idl b/Source/WebCore/html/HTMLAttachmentElement.idl
deleted file mode 100644
index 85bd478c9..000000000
--- a/Source/WebCore/html/HTMLAttachmentElement.idl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- Conditional=ATTACHMENT_ELEMENT
-] interface HTMLAttachmentElement : HTMLElement {
- attribute File file;
-};
diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in
index 9ed84f015..949d04fdf 100644
--- a/Source/WebCore/html/HTMLAttributeNames.in
+++ b/Source/WebCore/html/HTMLAttributeNames.in
@@ -42,7 +42,6 @@ aria-pressed
aria-readonly
aria-relevant
aria-required
-aria-roledescription
aria-selected
aria-setsize
aria-sort
@@ -170,11 +169,6 @@ novalidate
nowrap
object
onabort
-onanimationstart
-onanimationiteration
-onanimationend
-onautocomplete
-onautocompleteerror
onbeforecopy
onbeforecut
onbeforeload
@@ -216,7 +210,6 @@ onload
onloadeddata
onloadedmetadata
onloadstart
-onmessage
onmousedown
onmouseenter
onmouseleave
@@ -271,19 +264,11 @@ onwebkitfullscreenerror
onwebkitkeyadded
onwebkitkeyerror
onwebkitkeymessage
-onwebkitmouseforcechanged
-onwebkitmouseforcedown
-onwebkitmouseforceup
-onwebkitmouseforcewillbegin
onwebkitneedkey
onwebkitsourceclose
onwebkitsourceended
onwebkitsourceopen
onwebkittransitionend
-onwebkitwillrevealbottom
-onwebkitwillrevealleft
-onwebkitwillrevealright
-onwebkitwillrevealtop
open
optimum
pattern
@@ -316,6 +301,7 @@ scoped
scrollamount
scrolldelay
scrolling
+seamless
select
selected
shape
@@ -335,7 +321,6 @@ standby
start
step
style
-subtitle
summary
tabindex
tableborder
@@ -353,20 +338,19 @@ valign
value
valuetype
version
+viewsource
vlink
vspace
webkitallowfullscreen
-webkitattachmentpath
+webkitdirectory
width
wrap
autocorrect
autocapitalize
+data-youtube-id
onwebkitcurrentplaybacktargetiswirelesschanged
onwebkitplaybacktargetavailabilitychanged
-onwebkitpresentationmodechanged
-x-webkit-imagemenu
webkit-playsinline
x-webkit-airplay
x-webkit-wirelessvideoplaybackdisabled
-x-itunes-inherit-uri-query-component
diff --git a/Source/WebCore/html/HTMLAudioElement.cpp b/Source/WebCore/html/HTMLAudioElement.cpp
index 0d8168f2e..b487a3b7e 100644
--- a/Source/WebCore/html/HTMLAudioElement.cpp
+++ b/Source/WebCore/html/HTMLAudioElement.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -39,23 +39,23 @@ HTMLAudioElement::HTMLAudioElement(const QualifiedName& tagName, Document& docum
ASSERT(hasTagName(audioTag));
}
-Ref<HTMLAudioElement> HTMLAudioElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
+PassRefPtr<HTMLAudioElement> HTMLAudioElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
{
- Ref<HTMLAudioElement> audioElement = adoptRef(*new HTMLAudioElement(tagName, document, createdByParser));
+ RefPtr<HTMLAudioElement> audioElement(adoptRef(new HTMLAudioElement(tagName, document, createdByParser)));
audioElement->suspendIfNeeded();
- return audioElement;
+ return audioElement.release();
}
-Ref<HTMLAudioElement> HTMLAudioElement::createForJSConstructor(Document& document, const String& src)
+PassRefPtr<HTMLAudioElement> HTMLAudioElement::createForJSConstructor(Document& document, const String& src)
{
- Ref<HTMLAudioElement> audio = adoptRef(*new HTMLAudioElement(audioTag, document, false));
+ RefPtr<HTMLAudioElement> audio = adoptRef(new HTMLAudioElement(audioTag, document, false));
audio->setPreload("auto");
if (!src.isNull()) {
audio->setSrc(src);
audio->scheduleDelayedAction(HTMLMediaElement::LoadMediaResource);
}
audio->suspendIfNeeded();
- return audio;
+ return audio.release();
}
}
diff --git a/Source/WebCore/html/HTMLAudioElement.h b/Source/WebCore/html/HTMLAudioElement.h
index 75c6755ab..0f97d1452 100644
--- a/Source/WebCore/html/HTMLAudioElement.h
+++ b/Source/WebCore/html/HTMLAudioElement.h
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -36,22 +36,16 @@ class Document;
class HTMLAudioElement final : public HTMLMediaElement {
public:
- static Ref<HTMLAudioElement> create(const QualifiedName&, Document&, bool);
- static Ref<HTMLAudioElement> createForJSConstructor(Document&, const String& src);
+ static PassRefPtr<HTMLAudioElement> create(const QualifiedName&, Document&, bool);
+ static PassRefPtr<HTMLAudioElement> createForJSConstructor(Document&, const String& src);
private:
HTMLAudioElement(const QualifiedName&, Document&, bool);
-
- virtual PlatformMediaSession::MediaType presentationType() const override { return PlatformMediaSession::Audio; }
};
-} // namespace WebCore
+NODE_TYPE_CASTS(HTMLAudioElement)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLAudioElement)
- static bool isType(const WebCore::HTMLMediaElement& element) { return element.hasTagName(WebCore::HTMLNames::audioTag); }
- static bool isType(const WebCore::Element& element) { return is<WebCore::HTMLMediaElement>(element) && isType(downcast<WebCore::HTMLMediaElement>(element)); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::HTMLMediaElement>(node) && isType(downcast<WebCore::HTMLMediaElement>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+} //namespace
-#endif // ENABLE(VIDEO)
-#endif // HTMLAudioElement_h
+#endif
+#endif
diff --git a/Source/WebCore/html/HTMLAudioElement.idl b/Source/WebCore/html/HTMLAudioElement.idl
index 30e5d90a0..4685ac9fa 100644
--- a/Source/WebCore/html/HTMLAudioElement.idl
+++ b/Source/WebCore/html/HTMLAudioElement.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/HTMLBDIElement.h b/Source/WebCore/html/HTMLBDIElement.h
index ada79efb4..d5ec4bf7c 100644
--- a/Source/WebCore/html/HTMLBDIElement.h
+++ b/Source/WebCore/html/HTMLBDIElement.h
@@ -27,9 +27,9 @@ namespace WebCore {
class HTMLBDIElement final : public HTMLElement {
public:
- static Ref<HTMLBDIElement> create(const QualifiedName& name, Document& document)
+ static PassRefPtr<HTMLBDIElement> create(const QualifiedName& name, Document& document)
{
- return adoptRef(*new HTMLBDIElement(name, document));
+ return adoptRef(new HTMLBDIElement(name, document));
}
private:
diff --git a/Source/WebCore/html/HTMLBRElement.cpp b/Source/WebCore/html/HTMLBRElement.cpp
index 5bbcff7f4..5eea85ae9 100644
--- a/Source/WebCore/html/HTMLBRElement.cpp
+++ b/Source/WebCore/html/HTMLBRElement.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLBRElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
@@ -38,14 +39,14 @@ HTMLBRElement::HTMLBRElement(const QualifiedName& tagName, Document& document)
ASSERT(hasTagName(brTag));
}
-Ref<HTMLBRElement> HTMLBRElement::create(Document& document)
+PassRefPtr<HTMLBRElement> HTMLBRElement::create(Document& document)
{
- return adoptRef(*new HTMLBRElement(brTag, document));
+ return adoptRef(new HTMLBRElement(brTag, document));
}
-Ref<HTMLBRElement> HTMLBRElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLBRElement> HTMLBRElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLBRElement(tagName, document));
+ return adoptRef(new HTMLBRElement(tagName, document));
}
bool HTMLBRElement::isPresentationAttribute(const QualifiedName& name) const
@@ -70,12 +71,12 @@ void HTMLBRElement::collectStyleForPresentationAttribute(const QualifiedName& na
HTMLElement::collectStyleForPresentationAttribute(name, value, style);
}
-RenderPtr<RenderElement> HTMLBRElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLBRElement::createElementRenderer(PassRef<RenderStyle> style)
{
if (style.get().hasContent())
- return RenderElement::createFor(*this, WTF::move(style));
+ return RenderElement::createFor(*this, std::move(style));
- return createRenderer<RenderLineBreak>(*this, WTF::move(style));
+ return createRenderer<RenderLineBreak>(*this, std::move(style));
}
}
diff --git a/Source/WebCore/html/HTMLBRElement.h b/Source/WebCore/html/HTMLBRElement.h
index 23e4fefc6..b5439c5c9 100644
--- a/Source/WebCore/html/HTMLBRElement.h
+++ b/Source/WebCore/html/HTMLBRElement.h
@@ -30,8 +30,8 @@ namespace WebCore {
class HTMLBRElement final : public HTMLElement {
public:
- static Ref<HTMLBRElement> create(Document&);
- static Ref<HTMLBRElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLBRElement> create(Document&);
+ static PassRefPtr<HTMLBRElement> create(const QualifiedName&, Document&);
virtual bool canContainRangeEndPoint() const override { return false; }
@@ -41,7 +41,7 @@ private:
virtual bool isPresentationAttribute(const QualifiedName&) const override;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
};
} // namespace
diff --git a/Source/WebCore/html/HTMLBaseElement.cpp b/Source/WebCore/html/HTMLBaseElement.cpp
index f3e29d021..7e8d2764a 100644
--- a/Source/WebCore/html/HTMLBaseElement.cpp
+++ b/Source/WebCore/html/HTMLBaseElement.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLBaseElement.h"
+#include "Attribute.h"
#include "Document.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
@@ -38,9 +39,9 @@ inline HTMLBaseElement::HTMLBaseElement(const QualifiedName& tagName, Document&
ASSERT(hasTagName(baseTag));
}
-Ref<HTMLBaseElement> HTMLBaseElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLBaseElement> HTMLBaseElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLBaseElement(tagName, document));
+ return adoptRef(new HTMLBaseElement(tagName, document));
}
void HTMLBaseElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
diff --git a/Source/WebCore/html/HTMLBaseElement.h b/Source/WebCore/html/HTMLBaseElement.h
index a0e656d43..4054e1758 100644
--- a/Source/WebCore/html/HTMLBaseElement.h
+++ b/Source/WebCore/html/HTMLBaseElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLBaseElement final : public HTMLElement {
public:
- static Ref<HTMLBaseElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLBaseElement> create(const QualifiedName&, Document&);
URL href() const;
void setHref(const AtomicString&);
@@ -44,6 +44,8 @@ private:
virtual void removedFrom(ContainerNode&) override;
};
+NODE_TYPE_CASTS(HTMLBaseElement)
+
} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLBaseFontElement.cpp b/Source/WebCore/html/HTMLBaseFontElement.cpp
index 62ce8161b..499f94b32 100644
--- a/Source/WebCore/html/HTMLBaseFontElement.cpp
+++ b/Source/WebCore/html/HTMLBaseFontElement.cpp
@@ -35,9 +35,9 @@ inline HTMLBaseFontElement::HTMLBaseFontElement(const QualifiedName& tagName, Do
ASSERT(hasTagName(basefontTag));
}
-Ref<HTMLBaseFontElement> HTMLBaseFontElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLBaseFontElement> HTMLBaseFontElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLBaseFontElement(tagName, document));
+ return adoptRef(new HTMLBaseFontElement(tagName, document));
}
}
diff --git a/Source/WebCore/html/HTMLBaseFontElement.h b/Source/WebCore/html/HTMLBaseFontElement.h
index 6da448125..328f66f43 100644
--- a/Source/WebCore/html/HTMLBaseFontElement.h
+++ b/Source/WebCore/html/HTMLBaseFontElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLBaseFontElement final : public HTMLElement {
public:
- static Ref<HTMLBaseFontElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLBaseFontElement> create(const QualifiedName&, Document&);
private:
HTMLBaseFontElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLBodyElement.cpp b/Source/WebCore/html/HTMLBodyElement.cpp
index 4df6e2b03..9da1410fe 100644
--- a/Source/WebCore/html/HTMLBodyElement.cpp
+++ b/Source/WebCore/html/HTMLBodyElement.cpp
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Simon Hausmann (hausmann@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2006-2010, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,6 +24,7 @@
#include "config.h"
#include "HTMLBodyElement.h"
+#include "Attribute.h"
#include "CSSImageValue.h"
#include "CSSParser.h"
#include "CSSValueKeywords.h"
@@ -35,7 +36,6 @@
#include "HTMLParserIdioms.h"
#include "Page.h"
#include "StyleProperties.h"
-#include <wtf/NeverDestroyed.h>
namespace WebCore {
@@ -47,21 +47,14 @@ HTMLBodyElement::HTMLBodyElement(const QualifiedName& tagName, Document& documen
ASSERT(hasTagName(bodyTag));
}
-bool HTMLBodyElement::isFirstBodyElementOfDocument() const
+PassRefPtr<HTMLBodyElement> HTMLBodyElement::create(Document& document)
{
- // By spec http://dev.w3.org/csswg/cssom-view/#the-html-body-element
- // "The HTML body element is the first body HTML element child of the root HTML element html."
- return document().body() == this;
+ return adoptRef(new HTMLBodyElement(bodyTag, document));
}
-Ref<HTMLBodyElement> HTMLBodyElement::create(Document& document)
+PassRefPtr<HTMLBodyElement> HTMLBodyElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLBodyElement(bodyTag, document));
-}
-
-Ref<HTMLBodyElement> HTMLBodyElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(*new HTMLBodyElement(tagName, document));
+ return adoptRef(new HTMLBodyElement(tagName, document));
}
HTMLBodyElement::~HTMLBodyElement()
@@ -82,7 +75,7 @@ void HTMLBodyElement::collectStyleForPresentationAttribute(const QualifiedName&
if (!url.isEmpty()) {
auto imageValue = CSSImageValue::create(document().completeURL(url).string());
imageValue.get().setInitiator(localName());
- style.setProperty(CSSProperty(CSSPropertyBackgroundImage, WTF::move(imageValue)));
+ style.setProperty(CSSProperty(CSSPropertyBackgroundImage, std::move(imageValue)));
}
} else if (name == marginwidthAttr || name == leftmarginAttr) {
addHTMLLengthToStyle(style, CSSPropertyMarginRight, value);
@@ -101,49 +94,6 @@ void HTMLBodyElement::collectStyleForPresentationAttribute(const QualifiedName&
HTMLElement::collectStyleForPresentationAttribute(name, value, style);
}
-HTMLElement::EventHandlerNameMap HTMLBodyElement::createWindowEventHandlerNameMap()
-{
- static const QualifiedName* const table[] = {
- &onbeforeunloadAttr,
- &onblurAttr,
- &onerrorAttr,
- &onfocusAttr,
- &onfocusinAttr,
- &onfocusoutAttr,
- &onhashchangeAttr,
- &onloadAttr,
- &onmessageAttr,
- &onofflineAttr,
- &ononlineAttr,
- &onorientationchangeAttr,
- &onpagehideAttr,
- &onpageshowAttr,
- &onpopstateAttr,
- &onresizeAttr,
- &onscrollAttr,
- &onstorageAttr,
- &onunloadAttr,
- &onwebkitmouseforcechangedAttr,
- &onwebkitmouseforcedownAttr,
- &onwebkitmouseforceupAttr,
- &onwebkitmouseforcewillbeginAttr,
- &onwebkitwillrevealbottomAttr,
- &onwebkitwillrevealleftAttr,
- &onwebkitwillrevealrightAttr,
- &onwebkitwillrevealtopAttr,
- };
-
- EventHandlerNameMap map;
- populateEventHandlerNameMap(map, table);
- return map;
-}
-
-const AtomicString& HTMLBodyElement::eventNameForWindowEventHandlerAttribute(const QualifiedName& attributeName)
-{
- static NeverDestroyed<EventHandlerNameMap> map = createWindowEventHandlerNameMap();
- return eventNameForEventHandlerAttribute(attributeName, map.get());
-}
-
void HTMLBodyElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == vlinkAttr || name == alinkAttr || name == linkAttr) {
@@ -167,21 +117,42 @@ void HTMLBodyElement::parseAttribute(const QualifiedName& name, const AtomicStri
}
setNeedsStyleRecalc();
- return;
- }
-
- if (name == onselectionchangeAttr) {
+ } else if (name == onloadAttr)
+ document().setWindowAttributeEventListener(eventNames().loadEvent, name, value);
+ else if (name == onbeforeunloadAttr)
+ document().setWindowAttributeEventListener(eventNames().beforeunloadEvent, name, value);
+ else if (name == onunloadAttr)
+ document().setWindowAttributeEventListener(eventNames().unloadEvent, name, value);
+ else if (name == onpagehideAttr)
+ document().setWindowAttributeEventListener(eventNames().pagehideEvent, name, value);
+ else if (name == onpageshowAttr)
+ document().setWindowAttributeEventListener(eventNames().pageshowEvent, name, value);
+ else if (name == onpopstateAttr)
+ document().setWindowAttributeEventListener(eventNames().popstateEvent, name, value);
+ else if (name == onblurAttr)
+ document().setWindowAttributeEventListener(eventNames().blurEvent, name, value);
+ else if (name == onfocusAttr)
+ document().setWindowAttributeEventListener(eventNames().focusEvent, name, value);
+#if ENABLE(ORIENTATION_EVENTS)
+ else if (name == onorientationchangeAttr)
+ document().setWindowAttributeEventListener(eventNames().orientationchangeEvent, name, value);
+#endif
+ else if (name == onhashchangeAttr)
+ document().setWindowAttributeEventListener(eventNames().hashchangeEvent, name, value);
+ else if (name == onresizeAttr)
+ document().setWindowAttributeEventListener(eventNames().resizeEvent, name, value);
+ else if (name == onscrollAttr)
+ document().setWindowAttributeEventListener(eventNames().scrollEvent, name, value);
+ else if (name == onselectionchangeAttr)
document().setAttributeEventListener(eventNames().selectionchangeEvent, name, value);
- return;
- }
-
- auto& eventName = eventNameForWindowEventHandlerAttribute(name);
- if (!eventName.isNull()) {
- document().setWindowAttributeEventListener(eventName, name, value);
- return;
- }
-
- HTMLElement::parseAttribute(name, value);
+ else if (name == onstorageAttr)
+ document().setWindowAttributeEventListener(eventNames().storageEvent, name, value);
+ else if (name == ononlineAttr)
+ document().setWindowAttributeEventListener(eventNames().onlineEvent, name, value);
+ else if (name == onofflineAttr)
+ document().setWindowAttributeEventListener(eventNames().offlineEvent, name, value);
+ else
+ HTMLElement::parseAttribute(name, value);
}
Node::InsertionNotificationRequest HTMLBodyElement::insertedInto(ContainerNode& insertionPoint)
@@ -193,9 +164,9 @@ Node::InsertionNotificationRequest HTMLBodyElement::insertedInto(ContainerNode&
// FIXME: It's surprising this is web compatible since it means a marginwidth and marginheight attribute can
// magically appear on the <body> of all documents embedded through <iframe> or <frame>.
// FIXME: Perhaps this code should be in attach() instead of here.
- HTMLFrameOwnerElement* ownerElement = document().ownerElement();
- if (is<HTMLFrameElementBase>(ownerElement)) {
- HTMLFrameElementBase& ownerFrameElement = downcast<HTMLFrameElementBase>(*ownerElement);
+ Element* ownerElement = document().ownerElement();
+ if (ownerElement && isHTMLFrameElementBase(*ownerElement)) {
+ HTMLFrameElementBase& ownerFrameElement = toHTMLFrameElementBase(*ownerElement);
int marginWidth = ownerFrameElement.marginWidth();
if (marginWidth != -1)
setIntegralAttribute(marginwidthAttr, marginWidth);
@@ -217,9 +188,9 @@ bool HTMLBodyElement::supportsFocus() const
return hasEditableStyle() || HTMLElement::supportsFocus();
}
-static int adjustForZoom(int value, const Frame& frame)
+static int adjustForZoom(int value, Frame& frame)
{
- double zoomFactor = frame.pageZoomFactor() * frame.frameScaleFactor();
+ float zoomFactor = frame.pageZoomFactor() * frame.frameScaleFactor();
if (zoomFactor == 1)
return value;
// Needed because of truncation (rather than rounding) when scaling up.
@@ -230,101 +201,91 @@ static int adjustForZoom(int value, const Frame& frame)
int HTMLBodyElement::scrollLeft()
{
- if (isFirstBodyElementOfDocument()) {
- document().updateLayoutIgnorePendingStylesheets();
- Frame* frame = document().frame();
- if (!frame)
- return 0;
- FrameView* view = frame->view();
- if (!view)
- return 0;
- return adjustForZoom(view->contentsScrollPosition().x(), *frame);
- }
- return HTMLElement::scrollLeft();
+ document().updateLayoutIgnorePendingStylesheets();
+ Frame* frame = document().frame();
+ if (!frame)
+ return 0;
+ FrameView* view = frame->view();
+ if (!view)
+ return 0;
+#if PLATFORM(IOS)
+ return adjustForZoom(view->actualScrollX(), *frame);
+#else
+ return adjustForZoom(view->scrollX(), *frame);
+#endif
}
void HTMLBodyElement::setScrollLeft(int scrollLeft)
{
- if (isFirstBodyElementOfDocument()) {
- document().updateLayoutIgnorePendingStylesheets();
- Frame* frame = document().frame();
- if (!frame)
- return;
- FrameView* view = frame->view();
- if (!view)
- return;
- view->setScrollPosition(IntPoint(static_cast<int>(scrollLeft * frame->pageZoomFactor() * frame->frameScaleFactor()), view->scrollY()));
- }
- HTMLElement::setScrollLeft(scrollLeft);
+ document().updateLayoutIgnorePendingStylesheets();
+ Frame* frame = document().frame();
+ if (!frame)
+ return;
+ FrameView* view = frame->view();
+ if (!view)
+ return;
+ view->setScrollPosition(IntPoint(static_cast<int>(scrollLeft * frame->pageZoomFactor() * frame->frameScaleFactor()), view->scrollY()));
}
int HTMLBodyElement::scrollTop()
{
- if (isFirstBodyElementOfDocument()) {
- document().updateLayoutIgnorePendingStylesheets();
- Frame* frame = document().frame();
- if (!frame)
- return 0;
- FrameView* view = frame->view();
- if (!view)
- return 0;
- return adjustForZoom(view->contentsScrollPosition().y(), *frame);
- }
- return HTMLElement::scrollTop();
+ document().updateLayoutIgnorePendingStylesheets();
+ Frame* frame = document().frame();
+ if (!frame)
+ return 0;
+ FrameView* view = frame->view();
+ if (!view)
+ return 0;
+#if PLATFORM(IOS)
+ return adjustForZoom(view->actualScrollY(), *frame);
+#else
+ return adjustForZoom(view->scrollY(), *frame);
+#endif
}
void HTMLBodyElement::setScrollTop(int scrollTop)
{
- if (isFirstBodyElementOfDocument()) {
- document().updateLayoutIgnorePendingStylesheets();
- Frame* frame = document().frame();
- if (!frame)
- return;
- FrameView* view = frame->view();
- if (!view)
- return;
- view->setScrollPosition(IntPoint(view->scrollX(), static_cast<int>(scrollTop * frame->pageZoomFactor() * frame->frameScaleFactor())));
- }
- return HTMLElement::setScrollTop(scrollTop);
+ document().updateLayoutIgnorePendingStylesheets();
+ Frame* frame = document().frame();
+ if (!frame)
+ return;
+ FrameView* view = frame->view();
+ if (!view)
+ return;
+ view->setScrollPosition(IntPoint(view->scrollX(), static_cast<int>(scrollTop * frame->pageZoomFactor() * frame->frameScaleFactor())));
}
int HTMLBodyElement::scrollHeight()
{
- if (isFirstBodyElementOfDocument()) {
- // Update the document's layout.
- document().updateLayoutIgnorePendingStylesheets();
- Frame* frame = document().frame();
- if (!frame)
- return 0;
- FrameView* view = frame->view();
- if (!view)
- return 0;
- return adjustForZoom(view->contentsHeight(), *frame);
- }
- return HTMLElement::scrollHeight();
+ // Update the document's layout.
+ document().updateLayoutIgnorePendingStylesheets();
+ Frame* frame = document().frame();
+ if (!frame)
+ return 0;
+ FrameView* view = frame->view();
+ if (!view)
+ return 0;
+ return adjustForZoom(view->contentsHeight(), *frame);
}
int HTMLBodyElement::scrollWidth()
{
- if (isFirstBodyElementOfDocument()) {
- // Update the document's layout.
- document().updateLayoutIgnorePendingStylesheets();
- Frame* frame = document().frame();
- if (!frame)
- return 0;
- FrameView* view = frame->view();
- if (!view)
- return 0;
- return adjustForZoom(view->contentsWidth(), *frame);
- }
- return HTMLElement::scrollWidth();
+ // Update the document's layout.
+ document().updateLayoutIgnorePendingStylesheets();
+ Frame* frame = document().frame();
+ if (!frame)
+ return 0;
+ FrameView* view = frame->view();
+ if (!view)
+ return 0;
+ return adjustForZoom(view->contentsWidth(), *frame);
}
void HTMLBodyElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
{
HTMLElement::addSubresourceAttributeURLs(urls);
- addSubresourceURL(urls, document().completeURL(fastGetAttribute(backgroundAttr)));
+ addSubresourceURL(urls, document().completeURL(getAttribute(backgroundAttr)));
}
} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLBodyElement.h b/Source/WebCore/html/HTMLBodyElement.h
index c4cdfd505..440bd064f 100644
--- a/Source/WebCore/html/HTMLBodyElement.h
+++ b/Source/WebCore/html/HTMLBodyElement.h
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Simon Hausmann <hausmann@kde.org>
- * Copyright (C) 2004, 2006, 2009, 2010, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2006, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -28,19 +28,37 @@
namespace WebCore {
+class Document;
+
class HTMLBodyElement final : public HTMLElement {
public:
- static Ref<HTMLBodyElement> create(Document&);
- static Ref<HTMLBodyElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLBodyElement> create(Document&);
+ static PassRefPtr<HTMLBodyElement> create(const QualifiedName&, Document&);
virtual ~HTMLBodyElement();
- static const AtomicString& eventNameForWindowEventHandlerAttribute(const QualifiedName& attributeName);
+ // Declared virtual in Element
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(load);
+
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeunload);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(hashchange);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(message);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(offline);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(online);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(popstate);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload);
+
+#if ENABLE(ORIENTATION_EVENTS)
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange);
+#endif
private:
HTMLBodyElement(const QualifiedName&, Document&);
- bool isFirstBodyElementOfDocument() const;
-
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
virtual bool isPresentationAttribute(const QualifiedName&) const override;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
@@ -52,19 +70,19 @@ private:
virtual bool supportsFocus() const override;
virtual int scrollLeft() override;
- virtual void setScrollLeft(int) override;
+ virtual void setScrollLeft(int scrollLeft) override;
virtual int scrollTop() override;
- virtual void setScrollTop(int) override;
+ virtual void setScrollTop(int scrollTop) override;
virtual int scrollHeight() override;
virtual int scrollWidth() override;
virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override;
-
- static EventHandlerNameMap createWindowEventHandlerNameMap();
};
+NODE_TYPE_CASTS(HTMLBodyElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLBodyElement.idl b/Source/WebCore/html/HTMLBodyElement.idl
index c43cefe39..a07e7e7f3 100644
--- a/Source/WebCore/html/HTMLBodyElement.idl
+++ b/Source/WebCore/html/HTMLBodyElement.idl
@@ -26,26 +26,31 @@ interface HTMLBodyElement : HTMLElement {
[Reflect] attribute DOMString text;
[Reflect] attribute DOMString vLink;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onblur;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onerror;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onfocus;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onfocusin;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onfocusout;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onload;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onresize;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onscroll;
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
+ // Event handler attributes
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onbeforeunload;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onhashchange;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onmessage;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onoffline;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener ononline;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onpopstate;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onresize;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onstorage;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onunload;
- [NotEnumerable, WindowEventHandler, Conditional=MOUSE_FORCE_EVENTS] attribute EventHandler onwebkitmouseforcechanged;
- [NotEnumerable, WindowEventHandler, Conditional=MOUSE_FORCE_EVENTS] attribute EventHandler onwebkitmouseforcedown;
- [NotEnumerable, WindowEventHandler, Conditional=MOUSE_FORCE_EVENTS] attribute EventHandler onwebkitmouseforcewillbegin;
- [NotEnumerable, WindowEventHandler, Conditional=MOUSE_FORCE_EVENTS] attribute EventHandler onwebkitmouseforceup;
- [NotEnumerable, WindowEventHandler, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventHandler onwebkitwillrevealbottom;
- [NotEnumerable, WindowEventHandler, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventHandler onwebkitwillrevealleft;
- [NotEnumerable, WindowEventHandler, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventHandler onwebkitwillrevealright;
- [NotEnumerable, WindowEventHandler, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventHandler onwebkitwillrevealtop;
+ [Conditional=ORIENTATION_EVENTS, NotEnumerable, JSWindowEventListener] attribute EventListener onorientationchange;
- // Unique to Document and HTMLBodyElement
- [NotEnumerable, DocumentEventHandler] attribute EventHandler onselectionchange;
+ // Overrides of Element attributes (with different implementation in bindings).
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onblur;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onerror;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onfocus;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onload;
+
+ // Not implemented yet.
+ // [NotEnumerable, JSWindowEventListener] attribute EventListener onafterprint;
+ // [NotEnumerable, JSWindowEventListener] attribute EventListener onbeforeprint;
+ // [NotEnumerable, JSWindowEventListener] attribute EventListener onredo;
+ // [NotEnumerable, JSWindowEventListener] attribute EventListener onundo;
+#endif
};
-HTMLBodyElement implements WindowEventHandlers;
diff --git a/Source/WebCore/html/HTMLButtonElement.cpp b/Source/WebCore/html/HTMLButtonElement.cpp
index 963fd80c6..bceeef5e9 100644
--- a/Source/WebCore/html/HTMLButtonElement.cpp
+++ b/Source/WebCore/html/HTMLButtonElement.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "HTMLButtonElement.h"
+#include "Attribute.h"
#include "EventNames.h"
#include "FormDataList.h"
#include "HTMLFormElement.h"
@@ -46,9 +47,9 @@ inline HTMLButtonElement::HTMLButtonElement(const QualifiedName& tagName, Docume
ASSERT(hasTagName(buttonTag));
}
-Ref<HTMLButtonElement> HTMLButtonElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
+PassRefPtr<HTMLButtonElement> HTMLButtonElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
{
- return adoptRef(*new HTMLButtonElement(tagName, document, form));
+ return adoptRef(new HTMLButtonElement(tagName, document, form));
}
void HTMLButtonElement::setType(const AtomicString& type)
@@ -56,24 +57,24 @@ void HTMLButtonElement::setType(const AtomicString& type)
setAttribute(typeAttr, type);
}
-RenderPtr<RenderElement> HTMLButtonElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLButtonElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderButton>(*this, WTF::move(style));
+ return createRenderer<RenderButton>(*this, std::move(style));
}
const AtomicString& HTMLButtonElement::formControlType() const
{
switch (m_type) {
case SUBMIT: {
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, submit, ("submit", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, submit, ("submit", AtomicString::ConstructFromLiteral));
return submit;
}
case BUTTON: {
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, button, ("button", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, button, ("button", AtomicString::ConstructFromLiteral));
return button;
}
case RESET: {
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, reset, ("reset", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, reset, ("reset", AtomicString::ConstructFromLiteral));
return reset;
}
}
@@ -122,29 +123,28 @@ void HTMLButtonElement::defaultEventHandler(Event* event)
}
}
- if (is<KeyboardEvent>(*event)) {
- KeyboardEvent& keyboardEvent = downcast<KeyboardEvent>(*event);
- if (keyboardEvent.type() == eventNames().keydownEvent && keyboardEvent.keyIdentifier() == "U+0020") {
+ if (event->isKeyboardEvent()) {
+ if (event->type() == eventNames().keydownEvent && static_cast<KeyboardEvent*>(event)->keyIdentifier() == "U+0020") {
setActive(true, true);
// No setDefaultHandled() - IE dispatches a keypress in this case.
return;
}
- if (keyboardEvent.type() == eventNames().keypressEvent) {
- switch (keyboardEvent.charCode()) {
+ if (event->type() == eventNames().keypressEvent) {
+ switch (static_cast<KeyboardEvent*>(event)->charCode()) {
case '\r':
- dispatchSimulatedClick(&keyboardEvent);
- keyboardEvent.setDefaultHandled();
+ dispatchSimulatedClick(event);
+ event->setDefaultHandled();
return;
case ' ':
// Prevent scrolling down the page.
- keyboardEvent.setDefaultHandled();
+ event->setDefaultHandled();
return;
}
}
- if (keyboardEvent.type() == eventNames().keyupEvent && keyboardEvent.keyIdentifier() == "U+0020") {
+ if (event->type() == eventNames().keyupEvent && static_cast<KeyboardEvent*>(event)->keyIdentifier() == "U+0020") {
if (active())
- dispatchSimulatedClick(&keyboardEvent);
- keyboardEvent.setDefaultHandled();
+ dispatchSimulatedClick(event);
+ event->setDefaultHandled();
return;
}
}
@@ -154,7 +154,9 @@ void HTMLButtonElement::defaultEventHandler(Event* event)
bool HTMLButtonElement::willRespondToMouseClickEvents()
{
- return !isDisabledFormControl();
+ if (!isDisabledFormControl() && form() && (m_type == SUBMIT || m_type == RESET))
+ return true;
+ return HTMLFormControlElement::willRespondToMouseClickEvents();
}
bool HTMLButtonElement::isSuccessfulSubmitButton() const
@@ -194,14 +196,14 @@ bool HTMLButtonElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == formactionAttr || HTMLFormControlElement::isURLAttribute(attribute);
}
-const AtomicString& HTMLButtonElement::value() const
+String HTMLButtonElement::value() const
{
- return fastGetAttribute(valueAttr);
+ return getAttribute(valueAttr);
}
-bool HTMLButtonElement::computeWillValidate() const
+bool HTMLButtonElement::recalcWillValidate() const
{
- return m_type == SUBMIT && HTMLFormControlElement::computeWillValidate();
+ return m_type == SUBMIT && HTMLFormControlElement::recalcWillValidate();
}
} // namespace
diff --git a/Source/WebCore/html/HTMLButtonElement.h b/Source/WebCore/html/HTMLButtonElement.h
index 5d7df8062..df6cbcc2e 100644
--- a/Source/WebCore/html/HTMLButtonElement.h
+++ b/Source/WebCore/html/HTMLButtonElement.h
@@ -30,11 +30,11 @@ namespace WebCore {
class HTMLButtonElement final : public HTMLFormControlElement {
public:
- static Ref<HTMLButtonElement> create(const QualifiedName&, Document&, HTMLFormElement*);
+ static PassRefPtr<HTMLButtonElement> create(const QualifiedName&, Document&, HTMLFormElement*);
void setType(const AtomicString&);
- const AtomicString& value() const;
+ String value() const;
virtual bool willRespondToMouseClickEvents() override;
@@ -45,7 +45,7 @@ private:
virtual const AtomicString& formControlType() const override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
// HTMLFormControlElement always creates one, but buttons don't need it.
virtual bool alwaysCreateUserAgentShadowRoot() const override { return false; }
@@ -69,7 +69,7 @@ private:
virtual bool canStartSelection() const override { return false; }
virtual bool isOptionalFormControl() const override { return true; }
- virtual bool computeWillValidate() const override;
+ virtual bool recalcWillValidate() const override;
Type m_type;
bool m_isActivatedSubmit;
diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp
index 961b623ec..518a34233 100644
--- a/Source/WebCore/html/HTMLCanvasElement.cpp
+++ b/Source/WebCore/html/HTMLCanvasElement.cpp
@@ -12,10 +12,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,6 +28,7 @@
#include "config.h"
#include "HTMLCanvasElement.h"
+#include "Attribute.h"
#include "CanvasGradient.h"
#include "CanvasPattern.h"
#include "CanvasRenderingContext2D.h"
@@ -37,42 +38,38 @@
#include "ExceptionCode.h"
#include "Frame.h"
#include "FrameLoaderClient.h"
-#include "GeometryUtilities.h"
#include "GraphicsContext.h"
#include "HTMLNames.h"
#include "ImageData.h"
#include "MIMETypeRegistry.h"
+#include "MainFrame.h"
#include "Page.h"
#include "RenderHTMLCanvas.h"
#include "ScriptController.h"
#include "Settings.h"
#include <math.h>
-#include <runtime/JSCInlines.h>
#include <runtime/JSLock.h>
+#include <runtime/Operations.h>
#if ENABLE(WEBGL)
#include "WebGLContextAttributes.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
#endif
namespace WebCore {
using namespace HTMLNames;
-// These values come from the WhatWG/W3C HTML spec.
+// These values come from the WhatWG spec.
static const int DefaultWidth = 300;
static const int DefaultHeight = 150;
// Firefox limits width/height to 32767 pixels, but slows down dramatically before it
// reaches that limit. We limit by area instead, giving us larger maximum dimensions,
-// in exchange for a smaller maximum canvas size. The maximum canvas size is in device pixels.
-#if PLATFORM(IOS)
-static const unsigned MaxCanvasArea = 4096 * 4096;
-#elif PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101100
-static const unsigned MaxCanvasArea = 8192 * 8192;
-#else
-static const unsigned MaxCanvasArea = 16384 * 16384;
+// in exchange for a smaller maximum canvas size.
+#if !PLATFORM(IOS)
+static const float MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels
#endif
HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document& document)
@@ -80,21 +77,27 @@ HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document& doc
, m_size(DefaultWidth, DefaultHeight)
, m_rendererIsCanvas(false)
, m_ignoreReset(false)
+ , m_deviceScaleFactor(targetDeviceScaleFactor())
, m_originClean(true)
+#if PLATFORM(IOS)
+ // FIXME: We should look to reconcile usage of MaxCanvasArea and m_maximumDecodedImageSize.
+ , m_maximumDecodedImageSize(document.settings() ? document.settings()->maximumDecodedImageSize() : 0)
+#endif
, m_hasCreatedImageBuffer(false)
, m_didClearImageBuffer(false)
{
ASSERT(hasTagName(canvasTag));
+ setHasCustomStyleResolveCallbacks();
}
-Ref<HTMLCanvasElement> HTMLCanvasElement::create(Document& document)
+PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(Document& document)
{
- return adoptRef(*new HTMLCanvasElement(canvasTag, document));
+ return adoptRef(new HTMLCanvasElement(canvasTag, document));
}
-Ref<HTMLCanvasElement> HTMLCanvasElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLCanvasElement(tagName, document));
+ return adoptRef(new HTMLCanvasElement(tagName, document));
}
HTMLCanvasElement::~HTMLCanvasElement()
@@ -102,7 +105,7 @@ HTMLCanvasElement::~HTMLCanvasElement()
for (auto it = m_observers.begin(), end = m_observers.end(); it != end; ++it)
(*it)->canvasDestroyed(*this);
- m_context = nullptr; // Ensure this goes away before the ImageBuffer.
+ m_context.clear(); // Ensure this goes away before the ImageBuffer.
}
void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -112,16 +115,26 @@ void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicSt
HTMLElement::parseAttribute(name, value);
}
-RenderPtr<RenderElement> HTMLCanvasElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition& insertionPosition)
+RenderPtr<RenderElement> HTMLCanvasElement::createElementRenderer(PassRef<RenderStyle> style)
{
Frame* frame = document().frame();
if (frame && frame->script().canExecuteScripts(NotAboutToExecuteScript)) {
m_rendererIsCanvas = true;
- return createRenderer<RenderHTMLCanvas>(*this, WTF::move(style));
+ return createRenderer<RenderHTMLCanvas>(*this, std::move(style));
}
m_rendererIsCanvas = false;
- return HTMLElement::createElementRenderer(WTF::move(style), insertionPosition);
+ return HTMLElement::createElementRenderer(std::move(style));
+}
+
+void HTMLCanvasElement::willAttachRenderers()
+{
+ setIsInCanvasSubtree(true);
+}
+
+bool HTMLCanvasElement::areAuthorShadowsAllowed() const
+{
+ return false;
}
bool HTMLCanvasElement::canContainRangeEndPoint() const
@@ -198,8 +211,8 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, Canvas
if (Settings* settings = document().settings())
usesDashbardCompatibilityMode = settings->usesDashboardBackwardCompatibilityMode();
#endif
- m_context = std::make_unique<CanvasRenderingContext2D>(this, document().inQuirksMode(), usesDashbardCompatibilityMode);
-#if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS)
+ m_context = CanvasRenderingContext2D::create(this, document().inQuirksMode(), usesDashbardCompatibilityMode);
+#if USE(IOSURFACE_CANVAS_BACKING_STORE) || (ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING))
// Need to make sure a RenderLayer and compositing layer get created for the Canvas
setNeedsStyleRecalc(SyntheticStyleChange);
#endif
@@ -213,7 +226,14 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, Canvas
if (m_context && !m_context->is3d())
return nullptr;
if (!m_context) {
- m_context = WebGLRenderingContextBase::create(this, static_cast<WebGLContextAttributes*>(attrs), type);
+ Page* page = document().page();
+ if (page && !document().url().isLocalFile()) {
+ WebGLLoadPolicy policy = page->mainFrame().loader().client().webGLPolicyForURL(document().url());
+
+ if (policy == WebGLBlock)
+ return nullptr;
+ }
+ m_context = WebGLRenderingContext::create(this, static_cast<WebGLContextAttributes*>(attrs));
if (m_context) {
// Need to make sure a RenderLayer and compositing layer get created for the Canvas
setNeedsStyleRecalc(SyntheticStyleChange);
@@ -256,11 +276,7 @@ bool HTMLCanvasElement::is2dType(const String& type)
bool HTMLCanvasElement::is3dType(const String& type)
{
// Retain support for the legacy "webkit-3d" name.
- return type == "webgl" || type == "experimental-webgl"
-#if ENABLE(WEBGL2)
- || type == "experimental-webgl2"
-#endif
- || type == "webkit-3d";
+ return type == "webgl" || type == "experimental-webgl" || type == "webkit-3d";
}
#endif
@@ -317,27 +333,33 @@ void HTMLCanvasElement::reset()
IntSize oldSize = size();
IntSize newSize(w, h);
+ float newDeviceScaleFactor = targetDeviceScaleFactor();
+
// If the size of an existing buffer matches, we can just clear it instead of reallocating.
// This optimization is only done for 2D canvases for now.
- if (m_hasCreatedImageBuffer && oldSize == newSize && m_context && m_context->is2d()) {
+ if (m_hasCreatedImageBuffer && oldSize == newSize && m_deviceScaleFactor == newDeviceScaleFactor && m_context && m_context->is2d()) {
if (!m_didClearImageBuffer)
clearImageBuffer();
return;
}
+ m_deviceScaleFactor = newDeviceScaleFactor;
+
setSurfaceSize(newSize);
#if ENABLE(WEBGL)
- if (is3D() && oldSize != size())
- static_cast<WebGLRenderingContextBase*>(m_context.get())->reshape(width(), height());
+ if (m_context && m_context->is3d() && oldSize != size())
+ static_cast<WebGLRenderingContext*>(m_context.get())->reshape(width(), height());
#endif
if (auto renderer = this->renderer()) {
if (m_rendererIsCanvas) {
if (oldSize != size()) {
- downcast<RenderHTMLCanvas>(*renderer).canvasSizeChanged();
+ toRenderHTMLCanvas(renderer)->canvasSizeChanged();
+#if USE(ACCELERATED_COMPOSITING)
if (renderBox() && renderBox()->hasAcceleratedCompositing())
renderBox()->contentChanged(CanvasChanged);
+#endif
}
if (hadImageBuffer)
renderer->repaint();
@@ -348,6 +370,15 @@ void HTMLCanvasElement::reset()
(*it)->canvasResized(*this);
}
+float HTMLCanvasElement::targetDeviceScaleFactor() const
+{
+#if ENABLE(HIGH_DPI_CANVAS)
+ return document().frame() ? document().frame()->page()->deviceScaleFactor() : 1;
+#else
+ return 1;
+#endif
+}
+
bool HTMLCanvasElement::paintsIntoCanvasBuffer() const
{
ASSERT(m_context);
@@ -356,12 +387,13 @@ bool HTMLCanvasElement::paintsIntoCanvasBuffer() const
return true;
#endif
+#if USE(ACCELERATED_COMPOSITING)
if (!m_context->isAccelerated())
return true;
if (renderBox() && renderBox()->hasAcceleratedCompositing())
return false;
-
+#endif
return true;
}
@@ -388,15 +420,15 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r, boo
#if ENABLE(CSS_IMAGE_ORIENTATION)
orientationDescription.setImageOrientationEnum(renderer()->style().imageOrientation());
#endif
- context->drawImage(m_presentedImage.get(), ColorSpaceDeviceRGB, snappedIntRect(r), ImagePaintingOptions(orientationDescription, useLowQualityScale));
+ context->drawImage(m_presentedImage.get(), ColorSpaceDeviceRGB, pixelSnappedIntRect(r), CompositeSourceOver, orientationDescription, useLowQualityScale);
} else
- context->drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, snappedIntRect(r), useLowQualityScale);
+ context->drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, pixelSnappedIntRect(r), CompositeSourceOver, BlendModeNormal, useLowQualityScale);
}
}
#if ENABLE(WEBGL)
if (is3D())
- static_cast<WebGLRenderingContextBase*>(m_context.get())->markLayerComposited();
+ static_cast<WebGLRenderingContext*>(m_context.get())->markLayerComposited();
#endif
}
@@ -423,14 +455,14 @@ void HTMLCanvasElement::makePresentationCopy()
void HTMLCanvasElement::clearPresentationCopy()
{
- m_presentedImage = nullptr;
+ m_presentedImage.clear();
}
void HTMLCanvasElement::setSurfaceSize(const IntSize& size)
{
m_size = size;
m_hasCreatedImageBuffer = false;
- m_contextStateSaver = nullptr;
+ m_contextStateSaver.clear();
m_imageBuffer.reset();
clearCopiedImage();
}
@@ -471,23 +503,24 @@ String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit
return buffer()->toDataURL(encodingMimeType, quality);
}
-RefPtr<ImageData> HTMLCanvasElement::getImageData()
+PassRefPtr<ImageData> HTMLCanvasElement::getImageData()
{
-#if ENABLE(WEBGL)
- if (!is3D())
- return nullptr;
+ if (!m_context || !m_context->is3d())
+ return 0;
- WebGLRenderingContextBase* ctx = static_cast<WebGLRenderingContextBase*>(m_context.get());
+#if ENABLE(WEBGL)
+ WebGLRenderingContext* ctx = static_cast<WebGLRenderingContext*>(m_context.get());
return ctx->paintRenderingResultsToImageData();
#else
- return nullptr;
+ return 0;
#endif
}
FloatRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect) const
{
FloatRect deviceRect(logicalRect);
+ deviceRect.scale(m_deviceScaleFactor);
float x = floorf(deviceRect.x());
float y = floorf(deviceRect.y());
@@ -503,15 +536,15 @@ FloatRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect
FloatSize HTMLCanvasElement::convertLogicalToDevice(const FloatSize& logicalSize) const
{
- float width = ceilf(logicalSize.width());
- float height = ceilf(logicalSize.height());
+ float width = ceilf(logicalSize.width() * m_deviceScaleFactor);
+ float height = ceilf(logicalSize.height() * m_deviceScaleFactor);
return FloatSize(width, height);
}
FloatSize HTMLCanvasElement::convertDeviceToLogical(const FloatSize& deviceSize) const
{
- float width = ceilf(deviceSize.width());
- float height = ceilf(deviceSize.height());
+ float width = ceilf(deviceSize.width() / m_deviceScaleFactor);
+ float height = ceilf(deviceSize.height() / m_deviceScaleFactor);
return FloatSize(width, height);
}
@@ -544,13 +577,6 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const
#endif
}
-size_t HTMLCanvasElement::memoryCost() const
-{
- if (!m_imageBuffer)
- return 0;
- return 4 * m_imageBuffer->internalSize().width() * m_imageBuffer->internalSize().height();
-}
-
void HTMLCanvasElement::createImageBuffer() const
{
ASSERT(!m_imageBuffer);
@@ -563,21 +589,20 @@ void HTMLCanvasElement::createImageBuffer() const
if (!deviceSize.isExpressibleAsIntSize())
return;
- if (deviceSize.width() * deviceSize.height() > MaxCanvasArea) {
- StringBuilder stringBuilder;
- stringBuilder.appendLiteral("Canvas area exceeds the maximum limit (width * height > ");
- stringBuilder.appendNumber(MaxCanvasArea);
- stringBuilder.appendLiteral(").");
- document().addConsoleMessage(MessageSource::JS, MessageLevel::Warning, stringBuilder.toString());
+#if PLATFORM(IOS)
+ if (deviceSize.width() * deviceSize.height() * 4 > m_maximumDecodedImageSize)
return;
- }
+#else
+ if (deviceSize.width() * deviceSize.height() > MaxCanvasArea)
+ return;
+#endif
IntSize bufferSize(deviceSize.width(), deviceSize.height());
if (!bufferSize.width() || !bufferSize.height())
return;
RenderingMode renderingMode = shouldAccelerate(bufferSize) ? Accelerated : Unaccelerated;
- m_imageBuffer = ImageBuffer::create(size(), renderingMode);
+ m_imageBuffer = ImageBuffer::create(size(), m_deviceScaleFactor, ColorSpaceDeviceRGB, renderingMode);
if (!m_imageBuffer)
return;
m_imageBuffer->context()->setShadowsIgnoreTransforms(true);
@@ -585,12 +610,13 @@ void HTMLCanvasElement::createImageBuffer() const
if (document().settings() && !document().settings()->antialiased2dCanvasEnabled())
m_imageBuffer->context()->setShouldAntialias(false);
m_imageBuffer->context()->setStrokeThickness(1);
- m_contextStateSaver = std::make_unique<GraphicsContextStateSaver>(*m_imageBuffer->context());
+ m_contextStateSaver = adoptPtr(new GraphicsContextStateSaver(*m_imageBuffer->context()));
JSC::JSLockHolder lock(scriptExecutionContext()->vm());
- scriptExecutionContext()->vm().heap.reportExtraMemoryAllocated(memoryCost());
+ size_t numBytes = 4 * m_imageBuffer->internalSize().width() * m_imageBuffer->internalSize().height();
+ scriptExecutionContext()->vm()->heap.reportExtraMemoryCost(numBytes);
-#if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS)
+#if USE(IOSURFACE_CANVAS_BACKING_STORE) || (ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING))
if (m_context && m_context->is2d())
// Recalculate compositing requirements if acceleration state changed.
const_cast<HTMLCanvasElement*>(this)->setNeedsStyleRecalc(SyntheticStyleChange);
@@ -644,7 +670,7 @@ void HTMLCanvasElement::clearImageBuffer() const
void HTMLCanvasElement::clearCopiedImage()
{
- m_copiedImage = nullptr;
+ m_copiedImage.clear();
m_didClearImageBuffer = false;
}
diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h
index 8ef0eee9b..383a188e7 100644
--- a/Source/WebCore/html/HTMLCanvasElement.h
+++ b/Source/WebCore/html/HTMLCanvasElement.h
@@ -12,10 +12,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -31,7 +31,6 @@
#include "FloatRect.h"
#include "HTMLElement.h"
#include "IntSize.h"
-#include <memory>
#include <wtf/Forward.h>
#if USE(CG)
@@ -63,8 +62,8 @@ public:
class HTMLCanvasElement final : public HTMLElement {
public:
- static Ref<HTMLCanvasElement> create(Document&);
- static Ref<HTMLCanvasElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLCanvasElement> create(Document&);
+ static PassRefPtr<HTMLCanvasElement> create(const QualifiedName&, Document&);
virtual ~HTMLCanvasElement();
void addObserver(CanvasObserver&);
@@ -81,7 +80,7 @@ public:
void setSize(const IntSize& newSize)
{
- if (newSize == size())
+ if (newSize == size() && targetDeviceScaleFactor() == m_deviceScaleFactor)
return;
m_ignoreReset = true;
setWidth(newSize.width());
@@ -115,7 +114,7 @@ public:
ImageBuffer* buffer() const;
Image* copiedImage() const;
void clearCopiedImage();
- RefPtr<ImageData> getImageData();
+ PassRefPtr<ImageData> getImageData();
void makePresentationCopy();
void clearPresentationCopy();
@@ -128,26 +127,40 @@ public:
void setOriginTainted() { m_originClean = false; }
bool originClean() const { return m_originClean; }
+#if PLATFORM(IOS)
+ // FIXME: Can we use unsigned data types, unsigned or size_t?
+ void setMaximumDecodedImageSize(float maximumDecodedImageSize) { m_maximumDecodedImageSize = maximumDecodedImageSize; }
+ float maximumDecodedImageSize() { return m_maximumDecodedImageSize; }
+#endif
+
AffineTransform baseTransform() const;
+#if ENABLE(WEBGL)
+ bool is3D() const;
+#endif
+
void makeRenderingResultsAvailable();
bool hasCreatedImageBuffer() const { return m_hasCreatedImageBuffer; }
bool shouldAccelerate(const IntSize&) const;
- size_t memoryCost() const;
+ float deviceScaleFactor() const { return m_deviceScaleFactor; }
private:
HTMLCanvasElement(const QualifiedName&, Document&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
+ virtual void willAttachRenderers() override;
+ virtual bool areAuthorShadowsAllowed() const override;
virtual bool canContainRangeEndPoint() const override;
virtual bool canStartSelection() const override;
void reset();
+ float targetDeviceScaleFactor() const;
+
void createImageBuffer() const;
void clearImageBuffer() const;
@@ -155,33 +168,37 @@ private:
bool paintsIntoCanvasBuffer() const;
-#if ENABLE(WEBGL)
- bool is3D() const;
-#endif
-
HashSet<CanvasObserver*> m_observers;
IntSize m_size;
- std::unique_ptr<CanvasRenderingContext> m_context;
+ OwnPtr<CanvasRenderingContext> m_context;
bool m_rendererIsCanvas;
bool m_ignoreReset;
FloatRect m_dirtyRect;
+ float m_deviceScaleFactor;
bool m_originClean;
+#if PLATFORM(IOS)
+ // FIXME: Can we use a unsigned data type, unsigned or size_t?
+ float m_maximumDecodedImageSize;
+#endif
+
// m_createdImageBuffer means we tried to malloc the buffer. We didn't necessarily get it.
mutable bool m_hasCreatedImageBuffer;
mutable bool m_didClearImageBuffer;
mutable std::unique_ptr<ImageBuffer> m_imageBuffer;
- mutable std::unique_ptr<GraphicsContextStateSaver> m_contextStateSaver;
+ mutable OwnPtr<GraphicsContextStateSaver> m_contextStateSaver;
mutable RefPtr<Image> m_presentedImage;
mutable RefPtr<Image> m_copiedImage; // FIXME: This is temporary for platforms that have to copy the image buffer to render (and for CSSCanvasValue).
};
+NODE_TYPE_CASTS(HTMLCanvasElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLCanvasElement.idl b/Source/WebCore/html/HTMLCanvasElement.idl
index aa346efbf..87b609ab0 100644
--- a/Source/WebCore/html/HTMLCanvasElement.idl
+++ b/Source/WebCore/html/HTMLCanvasElement.idl
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,7 +26,6 @@
[
JSGenerateToNativeObject,
- ReportExtraMemoryCost
] interface HTMLCanvasElement : HTMLElement {
attribute long width;
@@ -34,11 +33,13 @@
[Custom, RaisesException] DOMString toDataURL([TreatNullAs=NullString, TreatUndefinedAs=NullString,Default=Undefined] optional DOMString type);
+#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
// The custom binding is needed to handle context creation attributes.
[Custom] any getContext([Default=Undefined] optional DOMString contextId);
[Custom] any probablySupportsContext([Default=Undefined] optional DOMString contextId);
#endif
+#endif
};
diff --git a/Source/WebCore/html/HTMLCollection.cpp b/Source/WebCore/html/HTMLCollection.cpp
index 3b4b62f72..58a9eeca2 100644
--- a/Source/WebCore/html/HTMLCollection.cpp
+++ b/Source/WebCore/html/HTMLCollection.cpp
@@ -65,7 +65,7 @@ static bool shouldOnlyIncludeDirectChildren(CollectionType type)
return false;
}
-inline auto HTMLCollection::rootTypeFromCollectionType(CollectionType type) -> RootType
+static NodeListRootType rootTypeFromCollectionType(CollectionType type)
{
switch (type) {
case DocImages:
@@ -79,7 +79,7 @@ inline auto HTMLCollection::rootTypeFromCollectionType(CollectionType type) -> R
case WindowNamedItems:
case DocumentNamedItems:
case FormControls:
- return HTMLCollection::IsRootedAtDocument;
+ return NodeListIsRootedAtDocument;
case NodeChildren:
case TableTBodies:
case TSectionRows:
@@ -89,10 +89,10 @@ inline auto HTMLCollection::rootTypeFromCollectionType(CollectionType type) -> R
case SelectedOptions:
case DataListOptions:
case MapAreas:
- return HTMLCollection::IsRootedAtNode;
+ return NodeListIsRootedAtNode;
}
ASSERT_NOT_REACHED();
- return HTMLCollection::IsRootedAtNode;
+ return NodeListIsRootedAtNode;
}
static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(CollectionType type)
@@ -133,29 +133,29 @@ static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col
HTMLCollection::HTMLCollection(ContainerNode& ownerNode, CollectionType type, ElementTraversalType traversalType)
: m_ownerNode(ownerNode)
- , m_indexCache(*this)
- , m_collectionType(type)
- , m_invalidationType(invalidationTypeExcludingIdAndNameAttributes(type))
, m_rootType(rootTypeFromCollectionType(type))
+ , m_invalidationType(invalidationTypeExcludingIdAndNameAttributes(type))
, m_shouldOnlyIncludeDirectChildren(shouldOnlyIncludeDirectChildren(type))
+ , m_isNameCacheValid(false)
+ , m_collectionType(type)
, m_usesCustomForwardOnlyTraversal(traversalType == CustomForwardOnlyTraversal)
+ , m_isItemRefElementsCacheValid(false)
{
ASSERT(m_rootType == static_cast<unsigned>(rootTypeFromCollectionType(type)));
ASSERT(m_invalidationType == static_cast<unsigned>(invalidationTypeExcludingIdAndNameAttributes(type)));
ASSERT(m_collectionType == static_cast<unsigned>(type));
+
+ document().registerCollection(*this);
}
-Ref<HTMLCollection> HTMLCollection::create(ContainerNode& base, CollectionType type)
+PassRefPtr<HTMLCollection> HTMLCollection::create(ContainerNode& base, CollectionType type)
{
- return adoptRef(*new HTMLCollection(base, type));
+ return adoptRef(new HTMLCollection(base, type));
}
HTMLCollection::~HTMLCollection()
{
- if (m_indexCache.hasValidCache(*this))
- document().unregisterCollection(*this);
- if (hasNamedElementCache())
- document().collectionWillClearIdNameMap(*this);
+ document().unregisterCollection(*this);
// HTMLNameCollection removes cache by itself.
if (type() != WindowNamedItems && type() != DocumentNamedItems)
ownerNode().nodeLists()->removeCachedCollection(this);
@@ -169,47 +169,53 @@ ContainerNode& HTMLCollection::rootNode() const
return ownerNode();
}
-static inline bool isMatchingHTMLElement(const HTMLCollection& collection, HTMLElement& element)
+inline bool isMatchingElement(const HTMLCollection& htmlCollection, Element& element)
{
- switch (collection.type()) {
+ CollectionType type = htmlCollection.type();
+ if (!element.isHTMLElement() && !(type == DocAll || type == NodeChildren || type == WindowNamedItems))
+ return false;
+
+ switch (type) {
case DocImages:
- return element.hasTagName(imgTag);
+ return element.hasLocalName(imgTag);
case DocScripts:
- return element.hasTagName(scriptTag);
+ return element.hasLocalName(scriptTag);
case DocForms:
- return element.hasTagName(formTag);
+ return element.hasLocalName(formTag);
case TableTBodies:
- return element.hasTagName(tbodyTag);
+ return element.hasLocalName(tbodyTag);
case TRCells:
- return element.hasTagName(tdTag) || element.hasTagName(thTag);
+ return element.hasLocalName(tdTag) || element.hasLocalName(thTag);
case TSectionRows:
- return element.hasTagName(trTag);
+ return element.hasLocalName(trTag);
case SelectOptions:
- return element.hasTagName(optionTag);
+ return element.hasLocalName(optionTag);
case SelectedOptions:
- return is<HTMLOptionElement>(element) && downcast<HTMLOptionElement>(element).selected();
+ return element.hasLocalName(optionTag) && toHTMLOptionElement(element).selected();
case DataListOptions:
- if (is<HTMLOptionElement>(element)) {
- HTMLOptionElement& option = downcast<HTMLOptionElement>(element);
+ if (element.hasLocalName(optionTag)) {
+ HTMLOptionElement& option = toHTMLOptionElement(element);
if (!option.isDisabledFormControl() && !option.value().isEmpty())
return true;
}
return false;
case MapAreas:
- return element.hasTagName(areaTag);
+ return element.hasLocalName(areaTag);
case DocApplets:
- return is<HTMLAppletElement>(element) || (is<HTMLObjectElement>(element) && downcast<HTMLObjectElement>(element).containsJavaApplet());
+ return element.hasLocalName(appletTag) || (element.hasLocalName(objectTag) && toHTMLObjectElement(element).containsJavaApplet());
case DocEmbeds:
- return element.hasTagName(embedTag);
+ return element.hasLocalName(embedTag);
case DocLinks:
- return (element.hasTagName(aTag) || element.hasTagName(areaTag)) && element.fastHasAttribute(hrefAttr);
+ return (element.hasLocalName(aTag) || element.hasLocalName(areaTag)) && element.fastHasAttribute(hrefAttr);
case DocAnchors:
- return element.hasTagName(aTag) && element.fastHasAttribute(nameAttr);
- case DocumentNamedItems:
- return downcast<DocumentNameCollection>(collection).elementMatches(element);
+ return element.hasLocalName(aTag) && element.fastHasAttribute(nameAttr);
case DocAll:
case NodeChildren:
+ return true;
+ case DocumentNamedItems:
+ return static_cast<const DocumentNameCollection&>(htmlCollection).nodeMatches(&element);
case WindowNamedItems:
+ return static_cast<const WindowNameCollection&>(htmlCollection).nodeMatches(&element);
case FormControls:
case TableRows:
break;
@@ -218,52 +224,36 @@ static inline bool isMatchingHTMLElement(const HTMLCollection& collection, HTMLE
return false;
}
-static inline bool isMatchingElement(const HTMLCollection& collection, Element& element)
-{
- // Collection types that deal with any type of Elements, not just HTMLElements.
- switch (collection.type()) {
- case DocAll:
- case NodeChildren:
- return true;
- case WindowNamedItems:
- return downcast<WindowNameCollection>(collection).elementMatches(element);
- default:
- // Collection types that only deal with HTMLElements.
- return is<HTMLElement>(element) && isMatchingHTMLElement(collection, downcast<HTMLElement>(element));
- }
-}
-
-static inline Element* previousElement(ContainerNode& base, Element& element, bool onlyIncludeDirectChildren)
+static Element* previousElement(ContainerNode& base, Element* previous, bool onlyIncludeDirectChildren)
{
- return onlyIncludeDirectChildren ? ElementTraversal::previousSibling(element) : ElementTraversal::previous(element, &base);
+ return onlyIncludeDirectChildren ? ElementTraversal::previousSibling(previous) : ElementTraversal::previous(previous, &base);
}
-ALWAYS_INLINE Element* HTMLCollection::iterateForPreviousElement(Element* element) const
+ALWAYS_INLINE Element* HTMLCollection::iterateForPreviousElement(Element* current) const
{
bool onlyIncludeDirectChildren = m_shouldOnlyIncludeDirectChildren;
ContainerNode& rootNode = this->rootNode();
- for (; element; element = previousElement(rootNode, *element, onlyIncludeDirectChildren)) {
- if (isMatchingElement(*this, *element))
- return element;
+ for (; current; current = previousElement(rootNode, current, onlyIncludeDirectChildren)) {
+ if (isMatchingElement(*this, *current))
+ return current;
}
return nullptr;
}
-static inline Element* firstMatchingElement(const HTMLCollection& collection, ContainerNode& root)
+inline Element* firstMatchingElement(const HTMLCollection& collection, ContainerNode& root)
{
- Element* element = ElementTraversal::firstWithin(root);
+ Element* element = ElementTraversal::firstWithin(&root);
while (element && !isMatchingElement(collection, *element))
- element = ElementTraversal::next(*element, &root);
+ element = ElementTraversal::next(element, &root);
return element;
}
-static inline Element* nextMatchingElement(const HTMLCollection& collection, Element& element, ContainerNode& root)
+inline Element* nextMatchingElement(const HTMLCollection& collection, Element* current, ContainerNode& root)
{
- Element* next = &element;
do {
- next = ElementTraversal::next(*next, &root);
- } while (next && !isMatchingElement(collection, *next));
- return next;
+ current = ElementTraversal::next(current, &root);
+ } while (current && !isMatchingElement(collection, *current));
+ return current;
}
unsigned HTMLCollection::length() const
@@ -271,7 +261,7 @@ unsigned HTMLCollection::length() const
return m_indexCache.nodeCount(*this);
}
-Element* HTMLCollection::item(unsigned offset) const
+Node* HTMLCollection::item(unsigned offset) const
{
return m_indexCache.nodeAt(*this, offset);
}
@@ -280,40 +270,29 @@ static inline bool nameShouldBeVisibleInDocumentAll(HTMLElement& element)
{
// The document.all collection returns only certain types of elements by name,
// although it returns any type of element by id.
- return element.hasTagName(appletTag)
- || element.hasTagName(embedTag)
- || element.hasTagName(formTag)
- || element.hasTagName(imgTag)
- || element.hasTagName(inputTag)
- || element.hasTagName(objectTag)
- || element.hasTagName(selectTag);
+ return element.hasLocalName(appletTag)
+ || element.hasLocalName(embedTag)
+ || element.hasLocalName(formTag)
+ || element.hasLocalName(imgTag)
+ || element.hasLocalName(inputTag)
+ || element.hasLocalName(objectTag)
+ || element.hasLocalName(selectTag);
}
-static inline bool nameShouldBeVisibleInDocumentAll(Element& element)
+inline Element* firstMatchingChildElement(const HTMLCollection& nodeList, ContainerNode& root)
{
- return is<HTMLElement>(element) && nameShouldBeVisibleInDocumentAll(downcast<HTMLElement>(element));
-}
-
-static inline Element* firstMatchingChildElement(const HTMLCollection& nodeList, ContainerNode& root)
-{
- Element* element = ElementTraversal::firstWithin(root);
+ Element* element = ElementTraversal::firstWithin(&root);
while (element && !isMatchingElement(nodeList, *element))
- element = ElementTraversal::nextSibling(*element);
+ element = ElementTraversal::nextSibling(element);
return element;
}
-static inline Element* nextMatchingSiblingElement(const HTMLCollection& nodeList, Element& element)
+inline Element* nextMatchingSiblingElement(const HTMLCollection& nodeList, Element* current)
{
- Element* next = &element;
do {
- next = ElementTraversal::nextSibling(*next);
- } while (next && !isMatchingElement(nodeList, *next));
- return next;
-}
-
-inline bool HTMLCollection::usesCustomForwardOnlyTraversal() const
-{
- return m_usesCustomForwardOnlyTraversal;
+ current = ElementTraversal::nextSibling(current);
+ } while (current && !isMatchingElement(nodeList, *current));
+ return current;
}
inline Element* HTMLCollection::firstElement(ContainerNode& root) const
@@ -334,23 +313,25 @@ inline Element* HTMLCollection::traverseForward(Element& current, unsigned count
if (!element)
return nullptr;
}
- } else if (m_shouldOnlyIncludeDirectChildren) {
- for (traversedCount = 0; traversedCount < count; ++traversedCount) {
- element = nextMatchingSiblingElement(*this, *element);
- if (!element)
- return nullptr;
- }
- } else {
+ return element;
+ }
+ if (m_shouldOnlyIncludeDirectChildren) {
for (traversedCount = 0; traversedCount < count; ++traversedCount) {
- element = nextMatchingElement(*this, *element, root);
+ element = nextMatchingSiblingElement(*this, element);
if (!element)
return nullptr;
}
+ return element;
+ }
+ for (traversedCount = 0; traversedCount < count; ++traversedCount) {
+ element = nextMatchingElement(*this, element, root);
+ if (!element)
+ return nullptr;
}
return element;
}
-Element* HTMLCollection::collectionBegin() const
+Element* HTMLCollection::collectionFirst() const
{
return firstElement(rootNode());
}
@@ -359,46 +340,46 @@ Element* HTMLCollection::collectionLast() const
{
// FIXME: This should be optimized similarly to the forward case.
auto& root = rootNode();
- Element* last = m_shouldOnlyIncludeDirectChildren ? ElementTraversal::lastChild(root) : ElementTraversal::lastWithin(root);
+ Element* last = m_shouldOnlyIncludeDirectChildren ? ElementTraversal::lastChild(&root) : ElementTraversal::lastWithin(&root);
return iterateForPreviousElement(last);
}
-void HTMLCollection::collectionTraverseForward(Element*& current, unsigned count, unsigned& traversedCount) const
+Element* HTMLCollection::collectionTraverseForward(Element& current, unsigned count, unsigned& traversedCount) const
{
- current = traverseForward(*current, count, traversedCount, rootNode());
+ return traverseForward(current, count, traversedCount, rootNode());
}
-void HTMLCollection::collectionTraverseBackward(Element*& current, unsigned count) const
+Element* HTMLCollection::collectionTraverseBackward(Element& current, unsigned count) const
{
// FIXME: This should be optimized similarly to the forward case.
+ auto& root = rootNode();
+ Element* element = &current;
if (m_shouldOnlyIncludeDirectChildren) {
- for (; count && current; --count)
- current = iterateForPreviousElement(ElementTraversal::previousSibling(*current));
- return;
+ for (; count && element ; --count)
+ element = iterateForPreviousElement(ElementTraversal::previousSibling(element));
+ return element;
}
- auto& root = rootNode();
- for (; count && current; --count)
- current = iterateForPreviousElement(ElementTraversal::previous(*current, &root));
+ for (; count && element ; --count)
+ element = iterateForPreviousElement(ElementTraversal::previous(element, &root));
+ return element;
}
-void HTMLCollection::invalidateCache(Document& document) const
+void HTMLCollection::invalidateCache() const
{
- if (m_indexCache.hasValidCache(*this)) {
- document.unregisterCollection(const_cast<HTMLCollection&>(*this));
- m_indexCache.invalidate(*this);
- }
- if (hasNamedElementCache())
- invalidateNamedElementCache(document);
+ m_indexCache.invalidate();
+ m_isNameCacheValid = false;
+ m_isItemRefElementsCacheValid = false;
+ m_idCache.clear();
+ m_nameCache.clear();
}
-void HTMLCollection::invalidateNamedElementCache(Document& document) const
+void HTMLCollection::invalidateIdNameCacheMaps() const
{
- ASSERT(hasNamedElementCache());
- document.collectionWillClearIdNameMap(*this);
- m_namedElementCache = nullptr;
+ m_idCache.clear();
+ m_nameCache.clear();
}
-Element* HTMLCollection::namedItem(const AtomicString& name) const
+Node* HTMLCollection::namedItem(const AtomicString& name) const
{
// http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp
// This method first searches for an object with a matching id
@@ -407,69 +388,65 @@ Element* HTMLCollection::namedItem(const AtomicString& name) const
// that are allowed a name attribute.
if (name.isEmpty())
- return nullptr;
+ return 0;
ContainerNode& root = rootNode();
if (!usesCustomForwardOnlyTraversal() && root.isInTreeScope()) {
- Element* candidate = nullptr;
-
TreeScope& treeScope = root.treeScope();
+ Element* candidate = 0;
if (treeScope.hasElementWithId(*name.impl())) {
if (!treeScope.containsMultipleElementsWithId(name))
candidate = treeScope.getElementById(name);
} else if (treeScope.hasElementWithName(*name.impl())) {
if (!treeScope.containsMultipleElementsWithName(name)) {
candidate = treeScope.getElementByName(name);
- if (candidate && type() == DocAll && !nameShouldBeVisibleInDocumentAll(*candidate))
- candidate = nullptr;
+ if (candidate && type() == DocAll && (!candidate->isHTMLElement() || !nameShouldBeVisibleInDocumentAll(toHTMLElement(*candidate))))
+ candidate = 0;
}
} else
- return nullptr;
+ return 0;
- if (candidate && isMatchingElement(*this, *candidate)) {
- if (m_shouldOnlyIncludeDirectChildren ? candidate->parentNode() == &root : candidate->isDescendantOf(&root))
- return candidate;
- }
+ if (candidate && isMatchingElement(*this, *candidate)
+ && (m_shouldOnlyIncludeDirectChildren ? candidate->parentNode() == &root : candidate->isDescendantOf(&root)))
+ return candidate;
}
// The pathological case. We need to walk the entire subtree.
- updateNamedElementCache();
- ASSERT(m_namedElementCache);
+ updateNameCache();
- if (const Vector<Element*>* idResults = m_namedElementCache->findElementsWithId(name)) {
+ if (Vector<Element*>* idResults = idCache(name)) {
if (idResults->size())
return idResults->at(0);
}
- if (const Vector<Element*>* nameResults = m_namedElementCache->findElementsWithName(name)) {
+ if (Vector<Element*>* nameResults = nameCache(name)) {
if (nameResults->size())
return nameResults->at(0);
}
- return nullptr;
+ return 0;
}
-void HTMLCollection::updateNamedElementCache() const
+void HTMLCollection::updateNameCache() const
{
- if (hasNamedElementCache())
+ if (hasNameCache())
return;
- auto cache = std::make_unique<CollectionNamedElementCache>();
+ ContainerNode& root = rootNode();
- unsigned size = m_indexCache.nodeCount(*this);
- for (unsigned i = 0; i < size; ++i) {
- Element& element = *m_indexCache.nodeAt(*this, i);
- const AtomicString& id = element.getIdAttribute();
- if (!id.isEmpty())
- cache->appendToIdCache(id, element);
- if (!is<HTMLElement>(element))
+ unsigned count;
+ for (Element* element = firstElement(root); element; element = traverseForward(*element, 1, count, root)) {
+ const AtomicString& idAttrVal = element->getIdAttribute();
+ if (!idAttrVal.isEmpty())
+ appendIdCache(idAttrVal, element);
+ if (!element->isHTMLElement())
continue;
- const AtomicString& name = element.getNameAttribute();
- if (!name.isEmpty() && id != name && (type() != DocAll || nameShouldBeVisibleInDocumentAll(downcast<HTMLElement>(element))))
- cache->appendToNameCache(name, element);
+ const AtomicString& nameAttrVal = element->getNameAttribute();
+ if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != DocAll || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element))))
+ appendNameCache(nameAttrVal, element);
}
- setNamedItemCache(WTF::move(cache));
+ setHasNameCache();
}
bool HTMLCollection::hasNamedItem(const AtomicString& name) const
@@ -478,34 +455,22 @@ bool HTMLCollection::hasNamedItem(const AtomicString& name) const
return namedItem(name);
}
-Vector<Ref<Element>> HTMLCollection::namedItems(const AtomicString& name) const
+void HTMLCollection::namedItems(const AtomicString& name, Vector<Ref<Element>>& result) const
{
- // FIXME: This non-virtual function can't possibly be doing the correct thing for
- // any derived class that overrides the virtual namedItem function.
-
- Vector<Ref<Element>> elements;
-
+ ASSERT(result.isEmpty());
if (name.isEmpty())
- return elements;
-
- updateNamedElementCache();
- ASSERT(m_namedElementCache);
+ return;
- auto* elementsWithId = m_namedElementCache->findElementsWithId(name);
- auto* elementsWithName = m_namedElementCache->findElementsWithName(name);
+ updateNameCache();
- elements.reserveInitialCapacity((elementsWithId ? elementsWithId->size() : 0) + (elementsWithName ? elementsWithName->size() : 0));
+ Vector<Element*>* idResults = idCache(name);
+ Vector<Element*>* nameResults = nameCache(name);
- if (elementsWithId) {
- for (auto& element : *elementsWithId)
- elements.uncheckedAppend(*element);
- }
- if (elementsWithName) {
- for (auto& element : *elementsWithName)
- elements.uncheckedAppend(*element);
- }
+ for (unsigned i = 0; idResults && i < idResults->size(); ++i)
+ result.append(*idResults->at(i));
- return elements;
+ for (unsigned i = 0; nameResults && i < nameResults->size(); ++i)
+ result.append(*nameResults->at(i));
}
PassRefPtr<NodeList> HTMLCollection::tags(const String& name)
@@ -513,10 +478,12 @@ PassRefPtr<NodeList> HTMLCollection::tags(const String& name)
return ownerNode().getElementsByTagName(name);
}
-Element* HTMLCollection::customElementAfter(Element*) const
+void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element* element)
{
- ASSERT_NOT_REACHED();
- return nullptr;
+ OwnPtr<Vector<Element*>>& vector = map.add(key.impl(), nullptr).iterator->value;
+ if (!vector)
+ vector = adoptPtr(new Vector<Element*>);
+ vector->append(element);
}
} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLCollection.h b/Source/WebCore/html/HTMLCollection.h
index 4714e908d..17c81c7e1 100644
--- a/Source/WebCore/html/HTMLCollection.h
+++ b/Source/WebCore/html/HTMLCollection.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,235 +24,106 @@
#define HTMLCollection_h
#include "CollectionIndexCache.h"
+#include "CollectionType.h"
+#include "ContainerNode.h"
+#include "Document.h"
#include "HTMLNames.h"
#include "LiveNodeList.h"
#include "ScriptWrappable.h"
+#include <wtf/Forward.h>
#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
namespace WebCore {
class Element;
-class CollectionNamedElementCache {
-public:
- const Vector<Element*>* findElementsWithId(const AtomicString& id) const;
- const Vector<Element*>* findElementsWithName(const AtomicString& name) const;
-
- void appendToIdCache(const AtomicString& id, Element&);
- void appendToNameCache(const AtomicString& name, Element&);
- void didPopulate();
-
- size_t memoryCost() const;
-
-private:
- typedef HashMap<AtomicStringImpl*, Vector<Element*>> StringToElementsMap;
-
- const Vector<Element*>* find(const StringToElementsMap&, const AtomicString& key) const;
- static void append(StringToElementsMap&, const AtomicString& key, Element&);
-
- StringToElementsMap m_idMap;
- StringToElementsMap m_nameMap;
-
-#if !ASSERT_DISABLED
- bool m_didPopulate { false };
-#endif
-};
-
class HTMLCollection : public ScriptWrappable, public RefCounted<HTMLCollection> {
public:
- static Ref<HTMLCollection> create(ContainerNode& base, CollectionType);
+ static PassRefPtr<HTMLCollection> create(ContainerNode& base, CollectionType);
virtual ~HTMLCollection();
// DOM API
unsigned length() const;
- Element* item(unsigned offset) const;
- virtual Element* namedItem(const AtomicString& name) const;
+ Node* item(unsigned offset) const;
+ virtual Node* namedItem(const AtomicString& name) const;
PassRefPtr<NodeList> tags(const String&);
// Non-DOM API
bool hasNamedItem(const AtomicString& name) const;
- Vector<Ref<Element>> namedItems(const AtomicString& name) const;
- size_t memoryCost() const;
-
- bool isRootedAtDocument() const;
- NodeListInvalidationType invalidationType() const;
- CollectionType type() const;
- ContainerNode& ownerNode() const;
- void invalidateCache(const QualifiedName* attributeName) const;
- virtual void invalidateCache(Document&) const;
-
- // For CollectionIndexCache; do not use elsewhere.
- Element* collectionBegin() const;
+ void namedItems(const AtomicString& name, Vector<Ref<Element>>&) const;
+
+ bool isRootedAtDocument() const { return m_rootType == NodeListIsRootedAtDocument; }
+ NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); }
+ CollectionType type() const { return static_cast<CollectionType>(m_collectionType); }
+ ContainerNode& ownerNode() const { return const_cast<ContainerNode&>(m_ownerNode.get()); }
+ void invalidateCache(const QualifiedName* attrName) const
+ {
+ if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName))
+ invalidateCache();
+ else if (*attrName == HTMLNames::idAttr || *attrName == HTMLNames::nameAttr)
+ invalidateIdNameCacheMaps();
+ }
+ virtual void invalidateCache() const;
+ void invalidateIdNameCacheMaps() const;
+
+ // For CollectionIndexCache
+ Element* collectionFirst() const;
Element* collectionLast() const;
- Element* collectionEnd() const;
- void collectionTraverseForward(Element*&, unsigned count, unsigned& traversedCount) const;
- void collectionTraverseBackward(Element*&, unsigned count) const;
- bool collectionCanTraverseBackward() const;
- void willValidateIndexCache() const;
-
- bool hasNamedElementCache() const;
+ Element* collectionTraverseForward(Element&, unsigned count, unsigned& traversedCount) const;
+ Element* collectionTraverseBackward(Element&, unsigned count) const;
+ bool collectionCanTraverseBackward() const { return !m_usesCustomForwardOnlyTraversal; }
protected:
enum ElementTraversalType { NormalTraversal, CustomForwardOnlyTraversal };
HTMLCollection(ContainerNode& base, CollectionType, ElementTraversalType = NormalTraversal);
- virtual void updateNamedElementCache() const;
+ virtual void updateNameCache() const;
- void setNamedItemCache(std::unique_ptr<CollectionNamedElementCache>) const;
- const CollectionNamedElementCache& namedItemCaches() const;
+ typedef HashMap<AtomicStringImpl*, OwnPtr<Vector<Element*>>> NodeCacheMap;
+ Vector<Element*>* idCache(const AtomicString& name) const { return m_idCache.get(name.impl()); }
+ Vector<Element*>* nameCache(const AtomicString& name) const { return m_nameCache.get(name.impl()); }
+ void appendIdCache(const AtomicString& name, Element* element) const { append(m_idCache, name, element); }
+ void appendNameCache(const AtomicString& name, Element* element) const { append(m_nameCache, name, element); }
-private:
- Document& document() const;
+ Document& document() const { return m_ownerNode->document(); }
ContainerNode& rootNode() const;
- bool usesCustomForwardOnlyTraversal() const;
+ bool usesCustomForwardOnlyTraversal() const { return m_usesCustomForwardOnlyTraversal; }
- Element* iterateForPreviousElement(Element*) const;
- Element* firstElement(ContainerNode& root) const;
- Element* traverseForward(Element&, unsigned count, unsigned& traversedCount, ContainerNode& root) const;
+ bool isItemRefElementsCacheValid() const { return m_isItemRefElementsCacheValid; }
+ void setItemRefElementsCacheValid() const { m_isItemRefElementsCacheValid = true; }
- virtual Element* customElementAfter(Element*) const;
+ NodeListRootType rootType() const { return static_cast<NodeListRootType>(m_rootType); }
- void invalidateNamedElementCache(Document&) const;
+ bool hasNameCache() const { return m_isNameCacheValid; }
+ void setHasNameCache() const { m_isNameCacheValid = true; }
- enum RootType { IsRootedAtNode, IsRootedAtDocument };
- static RootType rootTypeFromCollectionType(CollectionType);
+private:
+ static void append(NodeCacheMap&, const AtomicString&, Element*);
+
+ Element* iterateForPreviousElement(Element* current) const;
+ Element* firstElement(ContainerNode& root) const;
+ Element* traverseForward(Element& current, unsigned count, unsigned& traversedCount, ContainerNode& root) const;
+
+ virtual Element* customElementAfter(Element*) const { ASSERT_NOT_REACHED(); return nullptr; }
Ref<ContainerNode> m_ownerNode;
- mutable CollectionIndexCache<HTMLCollection, Element*> m_indexCache;
- mutable std::unique_ptr<CollectionNamedElementCache> m_namedElementCache;
+ mutable CollectionIndexCache<HTMLCollection, Element> m_indexCache;
- const unsigned m_collectionType : 5;
+ const unsigned m_rootType : 2;
const unsigned m_invalidationType : 4;
- const unsigned m_rootType : 1;
const unsigned m_shouldOnlyIncludeDirectChildren : 1;
- const unsigned m_usesCustomForwardOnlyTraversal : 1;
-};
-inline const Vector<Element*>* CollectionNamedElementCache::findElementsWithId(const AtomicString& id) const
-{
- return find(m_idMap, id);
-}
-
-inline const Vector<Element*>* CollectionNamedElementCache::findElementsWithName(const AtomicString& name) const
-{
- return find(m_nameMap, name);
-}
-
-inline void CollectionNamedElementCache::appendToIdCache(const AtomicString& id, Element& element)
-{
- return append(m_idMap, id, element);
-}
+ mutable unsigned m_isNameCacheValid : 1;
+ const unsigned m_collectionType : 5;
+ const unsigned m_usesCustomForwardOnlyTraversal : 1;
+ mutable unsigned m_isItemRefElementsCacheValid : 1;
-inline void CollectionNamedElementCache::appendToNameCache(const AtomicString& name, Element& element)
-{
- return append(m_nameMap, name, element);
-}
+ mutable NodeCacheMap m_idCache;
+ mutable NodeCacheMap m_nameCache;
+};
-inline size_t CollectionNamedElementCache::memoryCost() const
-{
- return (m_idMap.size() + m_nameMap.size()) * sizeof(Element*);
-}
+} // namespace
-inline void CollectionNamedElementCache::didPopulate()
-{
-#if !ASSERT_DISABLED
- m_didPopulate = true;
#endif
- if (size_t cost = memoryCost())
- reportExtraMemoryAllocatedForCollectionIndexCache(cost);
-}
-
-inline const Vector<Element*>* CollectionNamedElementCache::find(const StringToElementsMap& map, const AtomicString& key) const
-{
- ASSERT(m_didPopulate);
- auto it = map.find(key.impl());
- return it != map.end() ? &it->value : nullptr;
-}
-
-inline void CollectionNamedElementCache::append(StringToElementsMap& map, const AtomicString& key, Element& element)
-{
- map.add(key.impl(), Vector<Element*>()).iterator->value.append(&element);
-}
-
-inline size_t HTMLCollection::memoryCost() const
-{
- return m_indexCache.memoryCost() + (m_namedElementCache ? m_namedElementCache->memoryCost() : 0);
-}
-
-inline bool HTMLCollection::isRootedAtDocument() const
-{
- return m_rootType == IsRootedAtDocument;
-}
-
-inline NodeListInvalidationType HTMLCollection::invalidationType() const
-{
- return static_cast<NodeListInvalidationType>(m_invalidationType);
-}
-
-inline CollectionType HTMLCollection::type() const
-{
- return static_cast<CollectionType>(m_collectionType);
-}
-
-inline ContainerNode& HTMLCollection::ownerNode() const
-{
- return const_cast<ContainerNode&>(m_ownerNode.get());
-}
-
-inline Document& HTMLCollection::document() const
-{
- return m_ownerNode->document();
-}
-
-inline void HTMLCollection::invalidateCache(const QualifiedName* attributeName) const
-{
- if (!attributeName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attributeName))
- invalidateCache(document());
- else if (hasNamedElementCache() && (*attributeName == HTMLNames::idAttr || *attributeName == HTMLNames::nameAttr))
- invalidateNamedElementCache(document());
-}
-
-inline Element* HTMLCollection::collectionEnd() const
-{
- return nullptr;
-}
-
-inline bool HTMLCollection::collectionCanTraverseBackward() const
-{
- return !m_usesCustomForwardOnlyTraversal;
-}
-
-inline void HTMLCollection::willValidateIndexCache() const
-{
- document().registerCollection(const_cast<HTMLCollection&>(*this));
-}
-
-inline bool HTMLCollection::hasNamedElementCache() const
-{
- return !!m_namedElementCache;
-}
-
-inline void HTMLCollection::setNamedItemCache(std::unique_ptr<CollectionNamedElementCache> cache) const
-{
- ASSERT(cache);
- ASSERT(!m_namedElementCache);
- cache->didPopulate();
- m_namedElementCache = WTF::move(cache);
- document().collectionCachedIdNameMap(*this);
-}
-
-inline const CollectionNamedElementCache& HTMLCollection::namedItemCaches() const
-{
- ASSERT(!!m_namedElementCache);
- return *m_namedElementCache;
-}
-
-} // namespace WebCore
-
-#define SPECIALIZE_TYPE_TRAITS_HTMLCOLLECTION(ClassName, Type) \
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ClassName) \
- static bool isType(const WebCore::HTMLCollection& collection) { return collection.type() == WebCore::Type; } \
-SPECIALIZE_TYPE_TRAITS_END()
-
-#endif // HTMLCollection_h
diff --git a/Source/WebCore/html/HTMLCollection.idl b/Source/WebCore/html/HTMLCollection.idl
index b3e78fb10..62cb050ae 100644
--- a/Source/WebCore/html/HTMLCollection.idl
+++ b/Source/WebCore/html/HTMLCollection.idl
@@ -22,7 +22,6 @@
CustomToJSObject,
GenerateIsReachable=ImplOwnerNodeRoot,
ObjCPolymorphic,
- ReportExtraMemoryCost,
] interface HTMLCollection {
readonly attribute unsigned long length;
getter Node item([Default=Undefined] optional unsigned long index);
diff --git a/Source/WebCore/html/HTMLDListElement.cpp b/Source/WebCore/html/HTMLDListElement.cpp
index f61ed02b6..00d32cde5 100644
--- a/Source/WebCore/html/HTMLDListElement.cpp
+++ b/Source/WebCore/html/HTMLDListElement.cpp
@@ -35,9 +35,9 @@ inline HTMLDListElement::HTMLDListElement(const QualifiedName& tagName, Document
ASSERT(hasTagName(dlTag));
}
-Ref<HTMLDListElement> HTMLDListElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLDListElement> HTMLDListElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLDListElement(tagName, document));
+ return adoptRef(new HTMLDListElement(tagName, document));
}
}
diff --git a/Source/WebCore/html/HTMLDListElement.h b/Source/WebCore/html/HTMLDListElement.h
index 6bd758222..a11ac5cc1 100644
--- a/Source/WebCore/html/HTMLDListElement.h
+++ b/Source/WebCore/html/HTMLDListElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLDListElement final : public HTMLElement {
public:
- static Ref<HTMLDListElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLDListElement> create(const QualifiedName&, Document&);
private:
HTMLDListElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLDataListElement.cpp b/Source/WebCore/html/HTMLDataListElement.cpp
index fe5e76fad..8c204eb04 100644
--- a/Source/WebCore/html/HTMLDataListElement.cpp
+++ b/Source/WebCore/html/HTMLDataListElement.cpp
@@ -33,6 +33,7 @@
#if ENABLE(DATALIST_ELEMENT)
#include "HTMLDataListElement.h"
+#include "FeatureObserver.h"
#include "HTMLNames.h"
#include "IdTargetObserverRegistry.h"
@@ -43,12 +44,13 @@ inline HTMLDataListElement::HTMLDataListElement(const QualifiedName& tagName, Do
{
}
-Ref<HTMLDataListElement> HTMLDataListElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLDataListElement> HTMLDataListElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLDataListElement(tagName, document));
+ FeatureObserver::observe(&document, FeatureObserver::DataListElement);
+ return adoptRef(new HTMLDataListElement(tagName, document));
}
-Ref<HTMLCollection> HTMLDataListElement::options()
+PassRefPtr<HTMLCollection> HTMLDataListElement::options()
{
return ensureCachedHTMLCollection(DataListOptions);
}
diff --git a/Source/WebCore/html/HTMLDataListElement.h b/Source/WebCore/html/HTMLDataListElement.h
index 1d7724367..67fb1db8d 100644
--- a/Source/WebCore/html/HTMLDataListElement.h
+++ b/Source/WebCore/html/HTMLDataListElement.h
@@ -40,9 +40,9 @@ namespace WebCore {
class HTMLDataListElement final : public HTMLElement {
public:
- static Ref<HTMLDataListElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLDataListElement> create(const QualifiedName&, Document&);
- Ref<HTMLCollection> options();
+ PassRefPtr<HTMLCollection> options();
void optionElementChildrenChanged();
@@ -50,6 +50,8 @@ private:
HTMLDataListElement(const QualifiedName&, Document&);
};
+NODE_TYPE_CASTS(HTMLDataListElement)
+
} // namespace WebCore
#endif // ENABLE(DATALIST_ELEMENT)
diff --git a/Source/WebCore/html/HTMLDetailsElement.cpp b/Source/WebCore/html/HTMLDetailsElement.cpp
index 430212c1a..0efa66694 100644
--- a/Source/WebCore/html/HTMLDetailsElement.cpp
+++ b/Source/WebCore/html/HTMLDetailsElement.cpp
@@ -22,8 +22,6 @@
#include "HTMLDetailsElement.h"
#if ENABLE(DETAILS_ELEMENT)
-#include "AXObjectCache.h"
-#include "ElementIterator.h"
#include "HTMLSummaryElement.h"
#include "InsertionPoint.h"
#include "LocalizedStrings.h"
@@ -37,13 +35,13 @@ using namespace HTMLNames;
static const AtomicString& summaryQuerySelector()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, selector, ("summary:first-of-type", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, selector, ("summary:first-of-type", AtomicString::ConstructFromLiteral));
return selector;
};
-class DetailsContentElement final : public InsertionPoint {
+class DetailsContentElement : public InsertionPoint {
public:
- static Ref<DetailsContentElement> create(Document&);
+ static PassRefPtr<DetailsContentElement> create(Document&);
private:
DetailsContentElement(Document& document)
@@ -59,19 +57,19 @@ private:
}
};
-Ref<DetailsContentElement> DetailsContentElement::create(Document& document)
+PassRefPtr<DetailsContentElement> DetailsContentElement::create(Document& document)
{
- return adoptRef(*new DetailsContentElement(document));
+ return adoptRef(new DetailsContentElement(document));
}
-class DetailsSummaryElement final : public InsertionPoint {
+class DetailsSummaryElement : public InsertionPoint {
public:
- static Ref<DetailsSummaryElement> create(Document&);
+ static PassRefPtr<DetailsSummaryElement> create(Document&);
Element* fallbackSummary()
{
ASSERT(firstChild() && firstChild()->hasTagName(summaryTag));
- return downcast<Element>(firstChild());
+ return toElement(firstChild());
}
private:
@@ -88,21 +86,21 @@ private:
}
};
-Ref<DetailsSummaryElement> DetailsSummaryElement::create(Document& document)
+PassRefPtr<DetailsSummaryElement> DetailsSummaryElement::create(Document& document)
{
RefPtr<HTMLSummaryElement> summary = HTMLSummaryElement::create(summaryTag, document);
summary->appendChild(Text::create(document, defaultDetailsSummaryText()), ASSERT_NO_EXCEPTION);
- Ref<DetailsSummaryElement> detailsSummary = adoptRef(*new DetailsSummaryElement(document));
+ RefPtr<DetailsSummaryElement> detailsSummary = adoptRef(new DetailsSummaryElement(document));
detailsSummary->appendChild(summary);
- return detailsSummary;
+ return detailsSummary.release();
}
-Ref<HTMLDetailsElement> HTMLDetailsElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLDetailsElement> HTMLDetailsElement::create(const QualifiedName& tagName, Document& document)
{
- Ref<HTMLDetailsElement> details = adoptRef(*new HTMLDetailsElement(tagName, document));
+ RefPtr<HTMLDetailsElement> details = adoptRef(new HTMLDetailsElement(tagName, document));
details->ensureUserAgentShadowRoot();
- return details;
+ return details.release();
}
HTMLDetailsElement::HTMLDetailsElement(const QualifiedName& tagName, Document& document)
@@ -112,9 +110,9 @@ HTMLDetailsElement::HTMLDetailsElement(const QualifiedName& tagName, Document& d
ASSERT(hasTagName(detailsTag));
}
-RenderPtr<RenderElement> HTMLDetailsElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLDetailsElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderBlockFlow>(*this, WTF::move(style));
+ return createRenderer<RenderBlockFlow>(*this, std::move(style));
}
void HTMLDetailsElement::didAddUserAgentShadowRoot(ShadowRoot* root)
@@ -123,10 +121,12 @@ void HTMLDetailsElement::didAddUserAgentShadowRoot(ShadowRoot* root)
root->appendChild(DetailsContentElement::create(document()), ASSERT_NO_EXCEPTION);
}
-const Element* HTMLDetailsElement::findMainSummary() const
+Element* HTMLDetailsElement::findMainSummary() const
{
- if (auto summary = childrenOfType<HTMLSummaryElement>(*this).first())
- return summary;
+ for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->hasTagName(summaryTag))
+ return toElement(child);
+ }
return static_cast<DetailsSummaryElement*>(userAgentShadowRoot()->firstChild())->fallbackSummary();
}
@@ -162,10 +162,6 @@ bool HTMLDetailsElement::childShouldCreateRenderer(const Node& child) const
void HTMLDetailsElement::toggleOpen()
{
setAttribute(openAttr, m_isOpen ? nullAtom : emptyAtom);
-
- // We need to post to the document because toggling this element will delete it.
- if (AXObjectCache* cache = document().existingAXObjectCache())
- cache->postNotification(nullptr, &document(), AXObjectCache::AXExpandedChanged);
}
}
diff --git a/Source/WebCore/html/HTMLDetailsElement.h b/Source/WebCore/html/HTMLDetailsElement.h
index 4f594e197..a0a18a654 100644
--- a/Source/WebCore/html/HTMLDetailsElement.h
+++ b/Source/WebCore/html/HTMLDetailsElement.h
@@ -27,16 +27,15 @@ namespace WebCore {
class HTMLDetailsElement final : public HTMLElement {
public:
- static Ref<HTMLDetailsElement> create(const QualifiedName& tagName, Document&);
+ static PassRefPtr<HTMLDetailsElement> create(const QualifiedName& tagName, Document& document);
void toggleOpen();
- const Element* findMainSummary() const;
- bool isOpen() const { return m_isOpen; }
-
+ Element* findMainSummary() const;
+
private:
HTMLDetailsElement(const QualifiedName&, Document&);
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual bool childShouldCreateRenderer(const Node&) const override;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
@@ -45,6 +44,8 @@ private:
bool m_isOpen;
};
+NODE_TYPE_CASTS(HTMLDetailsElement)
+
} // namespace WebCore
#endif // HTMLDetailsElement_h
diff --git a/Source/WebCore/html/HTMLDirectoryElement.cpp b/Source/WebCore/html/HTMLDirectoryElement.cpp
index bb77d35b2..5c3d15ebc 100644
--- a/Source/WebCore/html/HTMLDirectoryElement.cpp
+++ b/Source/WebCore/html/HTMLDirectoryElement.cpp
@@ -35,9 +35,9 @@ inline HTMLDirectoryElement::HTMLDirectoryElement(const QualifiedName& tagName,
ASSERT(hasTagName(dirTag));
}
-Ref<HTMLDirectoryElement> HTMLDirectoryElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLDirectoryElement> HTMLDirectoryElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLDirectoryElement(tagName, document));
+ return adoptRef(new HTMLDirectoryElement(tagName, document));
}
}
diff --git a/Source/WebCore/html/HTMLDirectoryElement.h b/Source/WebCore/html/HTMLDirectoryElement.h
index 113602655..f1759af37 100644
--- a/Source/WebCore/html/HTMLDirectoryElement.h
+++ b/Source/WebCore/html/HTMLDirectoryElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLDirectoryElement final : public HTMLElement {
public:
- static Ref<HTMLDirectoryElement> create(const QualifiedName& tagName, Document&);
+ static PassRefPtr<HTMLDirectoryElement> create(const QualifiedName& tagName, Document&);
private:
HTMLDirectoryElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLDivElement.cpp b/Source/WebCore/html/HTMLDivElement.cpp
index 06b18926e..a9ac0bfc9 100644
--- a/Source/WebCore/html/HTMLDivElement.cpp
+++ b/Source/WebCore/html/HTMLDivElement.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLDivElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
@@ -37,14 +38,14 @@ HTMLDivElement::HTMLDivElement(const QualifiedName& tagName, Document& document)
ASSERT(hasTagName(divTag));
}
-Ref<HTMLDivElement> HTMLDivElement::create(Document& document)
+PassRefPtr<HTMLDivElement> HTMLDivElement::create(Document& document)
{
- return adoptRef(*new HTMLDivElement(divTag, document));
+ return adoptRef(new HTMLDivElement(divTag, document));
}
-Ref<HTMLDivElement> HTMLDivElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLDivElement> HTMLDivElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLDivElement(tagName, document));
+ return adoptRef(new HTMLDivElement(tagName, document));
}
bool HTMLDivElement::isPresentationAttribute(const QualifiedName& name) const
diff --git a/Source/WebCore/html/HTMLDivElement.h b/Source/WebCore/html/HTMLDivElement.h
index bcc0e9821..ff81b9b82 100644
--- a/Source/WebCore/html/HTMLDivElement.h
+++ b/Source/WebCore/html/HTMLDivElement.h
@@ -29,8 +29,8 @@ namespace WebCore {
class HTMLDivElement : public HTMLElement {
public:
- static Ref<HTMLDivElement> create(Document&);
- static Ref<HTMLDivElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLDivElement> create(Document&);
+ static PassRefPtr<HTMLDivElement> create(const QualifiedName&, Document&);
protected:
HTMLDivElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLDocument.cpp b/Source/WebCore/html/HTMLDocument.cpp
index 07ebc9a29..c6067d88a 100644
--- a/Source/WebCore/html/HTMLDocument.cpp
+++ b/Source/WebCore/html/HTMLDocument.cpp
@@ -57,7 +57,6 @@
#include "CookieJar.h"
#include "DocumentLoader.h"
#include "DocumentType.h"
-#include "ElementChildIterator.h"
#include "ExceptionCode.h"
#include "FocusController.h"
#include "Frame.h"
@@ -70,7 +69,6 @@
#include "HTMLElementFactory.h"
#include "HTMLFrameOwnerElement.h"
#include "HTMLFrameSetElement.h"
-#include "HTMLHtmlElement.h"
#include "HTMLNames.h"
#include "JSDOMBinding.h"
#include "Page.h"
@@ -107,19 +105,19 @@ int HTMLDocument::height()
return frameView ? frameView->contentsHeight() : 0;
}
-const AtomicString& HTMLDocument::dir() const
+String HTMLDocument::dir()
{
- auto* documentElement = this->documentElement();
- if (!is<HTMLHtmlElement>(documentElement))
- return nullAtom;
- return downcast<HTMLHtmlElement>(*documentElement).dir();
+ HTMLElement* b = body();
+ if (!b)
+ return String();
+ return b->getAttribute(dirAttr);
}
-void HTMLDocument::setDir(const AtomicString& value)
+void HTMLDocument::setDir(const String& value)
{
- auto* documentElement = this->documentElement();
- if (is<HTMLHtmlElement>(documentElement))
- downcast<HTMLHtmlElement>(*documentElement).setDir(value);
+ HTMLElement* b = body();
+ if (b)
+ b->setAttribute(dirAttr, value);
}
String HTMLDocument::designMode() const
@@ -139,74 +137,106 @@ void HTMLDocument::setDesignMode(const String& value)
Document::setDesignMode(mode);
}
+Element* HTMLDocument::activeElement()
+{
+ document().updateStyleIfNeeded();
+ if (Element* element = treeScope().focusedElement())
+ return element;
+ return body();
+}
+
+bool HTMLDocument::hasFocus()
+{
+ Page* page = this->page();
+ if (!page)
+ return false;
+ if (!page->focusController().isActive())
+ return false;
+ if (Frame* focusedFrame = page->focusController().focusedFrame()) {
+ if (focusedFrame->tree().isDescendantOf(frame()))
+ return true;
+ }
+ return false;
+}
+
const AtomicString& HTMLDocument::bgColor() const
{
- auto* bodyElement = body();
- if (!bodyElement)
+ HTMLElement* bodyElement = body();
+ if (!bodyElement || !isHTMLBodyElement(bodyElement))
return emptyAtom;
return bodyElement->fastGetAttribute(bgcolorAttr);
}
void HTMLDocument::setBgColor(const String& value)
{
- if (auto* bodyElement = body())
- bodyElement->setAttribute(bgcolorAttr, value);
+ HTMLElement* bodyElement = body();
+ if (!bodyElement || !isHTMLBodyElement(bodyElement))
+ return;
+ bodyElement->setAttribute(bgcolorAttr, value);
}
const AtomicString& HTMLDocument::fgColor() const
{
- auto* bodyElement = body();
- if (!bodyElement)
+ HTMLElement* bodyElement = body();
+ if (!bodyElement || !isHTMLBodyElement(bodyElement))
return emptyAtom;
return bodyElement->fastGetAttribute(textAttr);
}
void HTMLDocument::setFgColor(const String& value)
{
- if (auto* bodyElement = body())
- bodyElement->setAttribute(textAttr, value);
+ HTMLElement* bodyElement = body();
+ if (!bodyElement || !isHTMLBodyElement(bodyElement))
+ return;
+ bodyElement->setAttribute(textAttr, value);
}
const AtomicString& HTMLDocument::alinkColor() const
{
- auto* bodyElement = body();
- if (!bodyElement)
+ HTMLElement* bodyElement = body();
+ if (!bodyElement || !isHTMLBodyElement(bodyElement))
return emptyAtom;
return bodyElement->fastGetAttribute(alinkAttr);
}
void HTMLDocument::setAlinkColor(const String& value)
{
- if (auto* bodyElement = body())
- bodyElement->setAttribute(alinkAttr, value);
+ HTMLElement* bodyElement = body();
+ if (!bodyElement || !isHTMLBodyElement(bodyElement))
+ return;
+ bodyElement->setAttribute(alinkAttr, value);
}
const AtomicString& HTMLDocument::linkColor() const
{
- auto* bodyElement = body();
- if (!bodyElement)
+ HTMLElement* bodyElement = body();
+ if (!bodyElement || !isHTMLBodyElement(bodyElement))
return emptyAtom;
return bodyElement->fastGetAttribute(linkAttr);
}
void HTMLDocument::setLinkColor(const String& value)
{
- if (auto* bodyElement = body())
- bodyElement->setAttribute(linkAttr, value);
+ HTMLElement* bodyElement = body();
+ if (!bodyElement || !isHTMLBodyElement(bodyElement))
+ return;
+ return bodyElement->setAttribute(linkAttr, value);
}
const AtomicString& HTMLDocument::vlinkColor() const
{
- auto* bodyElement = body();
- if (!bodyElement)
+ HTMLElement* bodyElement = body();
+ if (!bodyElement || !isHTMLBodyElement(bodyElement))
return emptyAtom;
return bodyElement->fastGetAttribute(vlinkAttr);
}
void HTMLDocument::setVlinkColor(const String& value)
{
- if (auto* bodyElement = body())
- bodyElement->setAttribute(vlinkAttr, value);
+ HTMLElement* bodyElement = body();
+ if (!bodyElement || !isHTMLBodyElement(bodyElement))
+ return;
+ return bodyElement->setAttribute(vlinkAttr, value);
}
void HTMLDocument::captureEvents()
@@ -217,7 +247,7 @@ void HTMLDocument::releaseEvents()
{
}
-Ref<DocumentParser> HTMLDocument::createParser()
+PassRefPtr<DocumentParser> HTMLDocument::createParser()
{
return HTMLDocumentParser::create(*this);
}
@@ -226,7 +256,7 @@ Ref<DocumentParser> HTMLDocument::createParser()
// not part of the DOM
// --------------------------------------------------------------------------
-RefPtr<Element> HTMLDocument::createElement(const AtomicString& name, ExceptionCode& ec)
+PassRefPtr<Element> HTMLDocument::createElement(const AtomicString& name, ExceptionCode& ec)
{
if (!isValidName(name)) {
ec = INVALID_CHARACTER_ERR;
@@ -332,12 +362,11 @@ void HTMLDocument::clear()
bool HTMLDocument::isFrameSet() const
{
- if (!documentElement())
- return false;
- return !!childrenOfType<HTMLFrameSetElement>(*documentElement()).first();
+ HTMLElement* bodyElement = body();
+ return bodyElement && isHTMLFrameSetElement(bodyElement);
}
-Ref<Document> HTMLDocument::cloneDocumentWithoutChildren() const
+PassRefPtr<Document> HTMLDocument::cloneDocumentWithoutChildren() const
{
return create(nullptr, url());
}
diff --git a/Source/WebCore/html/HTMLDocument.h b/Source/WebCore/html/HTMLDocument.h
index 318dc7f8f..b42d320f1 100644
--- a/Source/WebCore/html/HTMLDocument.h
+++ b/Source/WebCore/html/HTMLDocument.h
@@ -31,14 +31,14 @@ namespace WebCore {
class HTMLDocument : public Document, public CachedResourceClient {
public:
- static Ref<HTMLDocument> create(Frame* frame, const URL& url)
+ static PassRefPtr<HTMLDocument> create(Frame* frame, const URL& url)
{
- return adoptRef(*new HTMLDocument(frame, url, HTMLDocumentClass));
+ return adoptRef(new HTMLDocument(frame, url, HTMLDocumentClass));
}
- static Ref<HTMLDocument> createSynthesizedDocument(Frame* frame, const URL& url)
+ static PassRefPtr<HTMLDocument> createSynthesizedDocument(Frame* frame, const URL& url)
{
- return adoptRef(*new HTMLDocument(frame, url, HTMLDocumentClass, Synthesized));
+ return adoptRef(new HTMLDocument(frame, url, HTMLDocumentClass, Synthesized));
}
virtual ~HTMLDocument();
@@ -46,12 +46,15 @@ public:
int width();
int height();
- const AtomicString& dir() const;
- void setDir(const AtomicString&);
+ String dir();
+ void setDir(const String&);
String designMode() const;
void setDesignMode(const String&);
+ Element* activeElement();
+ bool hasFocus();
+
const AtomicString& bgColor() const;
void setBgColor(const String&);
const AtomicString& fgColor() const;
@@ -86,21 +89,22 @@ protected:
HTMLDocument(Frame*, const URL&, DocumentClassFlags = 0, unsigned constructionFlags = 0);
private:
- virtual RefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&) override;
+ virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&) override;
virtual bool isFrameSet() const override;
- virtual Ref<DocumentParser> createParser() override;
- virtual Ref<Document> cloneDocumentWithoutChildren() const override final;
+ virtual PassRefPtr<DocumentParser> createParser() override;
+
+ virtual PassRefPtr<Document> cloneDocumentWithoutChildren() const override final;
DocumentOrderedMap m_documentNamedItem;
DocumentOrderedMap m_windowNamedItem;
};
-} // namespace WebCore
+inline bool isHTMLDocument(const Document& document) { return document.isHTMLDocument(); }
+void isHTMLDocument(const HTMLDocument&); // Catch unnecessary runtime check of type known at compile time.
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLDocument)
- static bool isType(const WebCore::Document& document) { return document.isHTMLDocument(); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::Document>(node) && isType(downcast<WebCore::Document>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+DOCUMENT_TYPE_CASTS(HTMLDocument)
+
+} // namespace WebCore
#endif // HTMLDocument_h
diff --git a/Source/WebCore/html/HTMLDocument.idl b/Source/WebCore/html/HTMLDocument.idl
index a673acde2..5e889ec22 100644
--- a/Source/WebCore/html/HTMLDocument.idl
+++ b/Source/WebCore/html/HTMLDocument.idl
@@ -19,11 +19,10 @@
*/
[
- CustomGetOwnPropertySlot,
CustomNamedGetter,
NewImpurePropertyFiresWatchpoints,
] interface HTMLDocument : Document {
- [Custom, ForwardDeclareInHeader] void open();
+ [Custom] void open();
void close();
[Custom] void write([Default=Undefined] optional DOMString text);
[Custom] void writeln([Default=Undefined] optional DOMString text);
@@ -50,6 +49,9 @@
[TreatNullAs=NullString] attribute DOMString designMode;
readonly attribute DOMString compatMode;
+ readonly attribute Element activeElement;
+ boolean hasFocus();
+
// Deprecated attributes
[TreatNullAs=NullString] attribute DOMString bgColor;
[TreatNullAs=NullString] attribute DOMString fgColor;
diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp
index aae427440..3ce325d29 100644
--- a/Source/WebCore/html/HTMLElement.cpp
+++ b/Source/WebCore/html/HTMLElement.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "HTMLElement.h"
+#include "Attribute.h"
#include "CSSParser.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
@@ -39,7 +40,6 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameView.h"
-#include "HTMLBDIElement.h"
#include "HTMLBRElement.h"
#include "HTMLCollection.h"
#include "HTMLDocument.h"
@@ -47,14 +47,16 @@
#include "HTMLFormElement.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
+#include "HTMLTemplateElement.h"
#include "HTMLTextFormControlElement.h"
#include "NodeTraversal.h"
-#include "RenderElement.h"
+#include "RenderLineBreak.h"
#include "ScriptController.h"
#include "Settings.h"
#include "StyleProperties.h"
#include "SubframeLoader.h"
#include "Text.h"
+#include "TextIterator.h"
#include "XMLNames.h"
#include "markup.h"
#include <wtf/NeverDestroyed.h>
@@ -66,9 +68,9 @@ namespace WebCore {
using namespace HTMLNames;
using namespace WTF;
-Ref<HTMLElement> HTMLElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLElement> HTMLElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLElement(tagName, document));
+ return adoptRef(new HTMLElement(tagName, document));
}
String HTMLElement::nodeName() const
@@ -90,28 +92,28 @@ bool HTMLElement::ieForbidsInsertHTML() const
// This is also called from editing and assumed to be the list of tags
// for which no end tag should be serialized. It's unclear if the list for
// IE compat and the list for serialization sanity are the same.
- if (hasTagName(areaTag)
- || hasTagName(baseTag)
- || hasTagName(basefontTag)
- || hasTagName(brTag)
- || hasTagName(colTag)
- || hasTagName(embedTag)
- || hasTagName(frameTag)
- || hasTagName(hrTag)
- || hasTagName(imageTag)
- || hasTagName(imgTag)
- || hasTagName(inputTag)
- || hasTagName(isindexTag)
- || hasTagName(linkTag)
- || hasTagName(metaTag)
- || hasTagName(paramTag)
- || hasTagName(sourceTag)
- || hasTagName(wbrTag))
+ if (hasLocalName(areaTag)
+ || hasLocalName(baseTag)
+ || hasLocalName(basefontTag)
+ || hasLocalName(brTag)
+ || hasLocalName(colTag)
+ || hasLocalName(embedTag)
+ || hasLocalName(frameTag)
+ || hasLocalName(hrTag)
+ || hasLocalName(imageTag)
+ || hasLocalName(imgTag)
+ || hasLocalName(inputTag)
+ || hasLocalName(isindexTag)
+ || hasLocalName(linkTag)
+ || hasLocalName(metaTag)
+ || hasLocalName(paramTag)
+ || hasLocalName(sourceTag)
+ || hasLocalName(wbrTag))
return true;
// FIXME: I'm not sure why dashboard mode would want to change the
// serialization of <canvas>, that seems like a bad idea.
#if ENABLE(DASHBOARD_SUPPORT)
- if (hasTagName(canvasTag)) {
+ if (hasLocalName(canvasTag)) {
Settings* settings = document().settings();
if (settings && settings->usesDashboardBackwardCompatibilityMode())
return true;
@@ -122,7 +124,7 @@ bool HTMLElement::ieForbidsInsertHTML() const
static inline CSSValueID unicodeBidiAttributeForDirAuto(HTMLElement& element)
{
- if (element.hasTagName(preTag) || element.hasTagName(textareaTag))
+ if (element.hasLocalName(preTag) || element.hasLocalName(textareaTag))
return CSSValueWebkitPlaintext;
// FIXME: For bdo element, dir="auto" should result in "bidi-override isolate" but we don't support having multiple values in unicode-bidi yet.
// See https://bugs.webkit.org/show_bug.cgi?id=73164.
@@ -133,7 +135,7 @@ unsigned HTMLElement::parseBorderWidthAttribute(const AtomicString& value) const
{
unsigned borderWidth = 0;
if (value.isEmpty() || !parseHTMLNonNegativeInteger(value, borderWidth))
- return hasTagName(tableTag) ? 1 : borderWidth;
+ return hasLocalName(tableTag) ? 1 : borderWidth;
return borderWidth;
}
@@ -166,32 +168,6 @@ static bool isLTROrRTLIgnoringCase(const AtomicString& dirAttributeValue)
return equalIgnoringCase(dirAttributeValue, "rtl") || equalIgnoringCase(dirAttributeValue, "ltr");
}
-enum class ContentEditableType {
- Inherit,
- True,
- False,
- PlaintextOnly
-};
-
-static inline ContentEditableType contentEditableType(const AtomicString& value)
-{
- if (value.isNull())
- return ContentEditableType::Inherit;
- if (value.isEmpty() || equalIgnoringCase(value, "true"))
- return ContentEditableType::True;
- if (equalIgnoringCase(value, "false"))
- return ContentEditableType::False;
- if (equalIgnoringCase(value, "plaintext-only"))
- return ContentEditableType::PlaintextOnly;
-
- return ContentEditableType::Inherit;
-}
-
-static ContentEditableType contentEditableType(const HTMLElement& element)
-{
- return contentEditableType(element.fastGetAttribute(contenteditableAttr));
-}
-
void HTMLElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
{
if (name == alignAttr) {
@@ -200,26 +176,24 @@ void HTMLElement::collectStyleForPresentationAttribute(const QualifiedName& name
else
addPropertyToPresentationAttributeStyle(style, CSSPropertyTextAlign, value);
} else if (name == contenteditableAttr) {
- CSSValueID userModifyValue = CSSValueReadWrite;
- switch (contentEditableType(value)) {
- case ContentEditableType::Inherit:
- return;
- case ContentEditableType::False:
- userModifyValue = CSSValueReadOnly;
- break;
- case ContentEditableType::PlaintextOnly:
- userModifyValue = CSSValueReadWritePlaintextOnly;
- FALLTHROUGH;
- case ContentEditableType::True:
+ if (value.isEmpty() || equalIgnoringCase(value, "true")) {
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitUserModify, CSSValueReadWrite);
addPropertyToPresentationAttributeStyle(style, CSSPropertyWordWrap, CSSValueBreakWord);
addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitNbspMode, CSSValueSpace);
addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);
#if PLATFORM(IOS)
addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitTextSizeAdjust, CSSValueNone);
#endif
- break;
- }
- addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitUserModify, userModifyValue);
+ } else if (equalIgnoringCase(value, "plaintext-only")) {
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitUserModify, CSSValueReadWritePlaintextOnly);
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyWordWrap, CSSValueBreakWord);
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitNbspMode, CSSValueSpace);
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);
+#if PLATFORM(IOS)
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitTextSizeAdjust, CSSValueNone);
+#endif
+ } else if (equalIgnoringCase(value, "false"))
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitUserModify, CSSValueReadOnly);
} else if (name == hiddenAttr) {
addPropertyToPresentationAttributeStyle(style, CSSPropertyDisplay, CSSValueNone);
} else if (name == draggableAttr) {
@@ -247,20 +221,12 @@ void HTMLElement::collectStyleForPresentationAttribute(const QualifiedName& name
StyledElement::collectStyleForPresentationAttribute(name, value, style);
}
-HTMLElement::EventHandlerNameMap HTMLElement::createEventHandlerNameMap()
+static NEVER_INLINE void populateEventNameForAttributeLocalNameMap(HashMap<AtomicStringImpl*, AtomicString>& map)
{
- EventHandlerNameMap map;
-
- static const QualifiedName* const table[] = {
+ static const QualifiedName* const simpleTable[] = {
&onabortAttr,
- &onanimationendAttr,
- &onanimationiterationAttr,
- &onanimationstartAttr,
- &onautocompleteAttr,
- &onautocompleteerrorAttr,
&onbeforecopyAttr,
&onbeforecutAttr,
- &onbeforeloadAttr,
&onbeforepasteAttr,
&onblurAttr,
&oncanplayAttr,
@@ -285,9 +251,6 @@ HTMLElement::EventHandlerNameMap HTMLElement::createEventHandlerNameMap()
&onfocusAttr,
&onfocusinAttr,
&onfocusoutAttr,
- &ongesturechangeAttr,
- &ongestureendAttr,
- &ongesturestartAttr,
&oninputAttr,
&oninvalidAttr,
&onkeydownAttr,
@@ -313,7 +276,6 @@ HTMLElement::EventHandlerNameMap HTMLElement::createEventHandlerNameMap()
&onratechangeAttr,
&onresetAttr,
&onscrollAttr,
- &onsearchAttr,
&onseekedAttr,
&onseekingAttr,
&onselectAttr,
@@ -326,154 +288,143 @@ HTMLElement::EventHandlerNameMap HTMLElement::createEventHandlerNameMap()
&ontouchendAttr,
&ontouchmoveAttr,
&ontouchstartAttr,
- &ontransitionendAttr,
&onvolumechangeAttr,
&onwaitingAttr,
- &onwebkitbeginfullscreenAttr,
- &onwebkitcurrentplaybacktargetiswirelesschangedAttr,
- &onwebkitendfullscreenAttr,
+ &onwheelAttr,
+#if ENABLE(IOS_GESTURE_EVENTS)
+ &ongesturechangeAttr,
+ &ongestureendAttr,
+ &ongesturestartAttr,
+#endif
+#if ENABLE(FULLSCREEN_API)
&onwebkitfullscreenchangeAttr,
&onwebkitfullscreenerrorAttr,
- &onwebkitkeyaddedAttr,
- &onwebkitkeyerrorAttr,
- &onwebkitkeymessageAttr,
- &onwebkitmouseforcechangedAttr,
- &onwebkitmouseforcedownAttr,
- &onwebkitmouseforcewillbeginAttr,
- &onwebkitmouseforceupAttr,
- &onwebkitneedkeyAttr,
- &onwebkitplaybacktargetavailabilitychangedAttr,
- &onwebkitpresentationmodechangedAttr,
- &onwebkitwillrevealbottomAttr,
- &onwebkitwillrevealleftAttr,
- &onwebkitwillrevealrightAttr,
- &onwebkitwillrevealtopAttr,
- &onwheelAttr,
+#endif
};
- populateEventHandlerNameMap(map, table);
+ for (unsigned i = 0, size = WTF_ARRAY_LENGTH(simpleTable); i < size; ++i) {
+ // FIXME: Would be nice to check these against the actual event names in eventNames().
+ // Not obvious how to do that simply, though.
+ const AtomicString& attributeName = simpleTable[i]->localName();
+
+ // Remove the "on" prefix. Requires some memory allocation and computing a hash, but
+ // by not using pointers from eventNames(), simpleTable can be initialized at compile time.
+ AtomicString eventName = attributeName.string().substring(2);
- struct UnusualMapping {
+ map.add(attributeName.impl(), eventName);
+ }
+
+ struct CustomMapping {
const QualifiedName& attributeName;
const AtomicString& eventName;
};
- const UnusualMapping unusualPairsTable[] = {
+ const CustomMapping customTable[] = {
+ { ontransitionendAttr, eventNames().webkitTransitionEndEvent },
{ onwebkitanimationendAttr, eventNames().webkitAnimationEndEvent },
{ onwebkitanimationiterationAttr, eventNames().webkitAnimationIterationEvent },
{ onwebkitanimationstartAttr, eventNames().webkitAnimationStartEvent },
{ onwebkittransitionendAttr, eventNames().webkitTransitionEndEvent },
};
- for (auto& entry : unusualPairsTable)
- map.add(entry.attributeName.localName().impl(), entry.eventName);
-
- return map;
+ for (unsigned i = 0, size = WTF_ARRAY_LENGTH(customTable); i < size; ++i)
+ map.add(customTable[i].attributeName.localName().impl(), customTable[i].eventName);
}
-void HTMLElement::populateEventHandlerNameMap(EventHandlerNameMap& map, const QualifiedName* const table[], size_t tableSize)
+void HTMLElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- for (size_t i = 0; i < tableSize; ++i) {
- auto* entry = table[i];
+ if (isIdAttributeName(name) || name == classAttr || name == styleAttr)
+ return StyledElement::parseAttribute(name, value);
- // FIXME: Would be nice to check these against the actual event names in eventNames().
- // Not obvious how to do that simply, though.
- auto& attributeName = entry->localName();
-
- // Remove the "on" prefix. Requires some memory allocation and computing a hash, but by not
- // using pointers from eventNames(), the passed-in table can be initialized at compile time.
- AtomicString eventName = attributeName.string().substring(2);
-
- map.add(attributeName.impl(), WTF::move(eventName));
+ if (name == dirAttr)
+ dirAttributeChanged(value);
+ else if (name == tabindexAttr) {
+ int tabindex = 0;
+ if (value.isEmpty())
+ clearTabIndexExplicitlyIfNeeded();
+ else if (parseHTMLInteger(value, tabindex)) {
+ // Clamp tabindex to the range of 'short' to match Firefox's behavior.
+ setTabIndexExplicitly(std::max(static_cast<int>(std::numeric_limits<short>::min()), std::min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
+ }
+ } else if (name.namespaceURI().isNull()) {
+ // FIXME: Can we do this even faster by checking the local name "on" prefix before we do anything with the map?
+ static NeverDestroyed<HashMap<AtomicStringImpl*, AtomicString>> eventNamesGlobal;
+ auto& eventNames = eventNamesGlobal.get();
+ if (eventNames.isEmpty())
+ populateEventNameForAttributeLocalNameMap(eventNames);
+ const AtomicString& eventName = eventNames.get(name.localName().impl());
+ if (!eventName.isNull())
+ setAttributeEventListener(eventName, name, value);
}
}
-const AtomicString& HTMLElement::eventNameForEventHandlerAttribute(const QualifiedName& attributeName, const EventHandlerNameMap& map)
+String HTMLElement::innerHTML() const
{
- ASSERT(!attributeName.localName().isNull());
-
- // Event handler attributes have no namespace.
- if (!attributeName.namespaceURI().isNull())
- return nullAtom;
-
- // Fast early return for names that don't start with "on".
- AtomicStringImpl& localName = *attributeName.localName().impl();
- if (localName.length() < 3 || localName[0] != 'o' || localName[1] != 'n')
- return nullAtom;
-
- auto it = map.find(&localName);
- return it == map.end() ? nullAtom : it->value;
+ return createMarkup(*this, ChildrenOnly);
}
-const AtomicString& HTMLElement::eventNameForEventHandlerAttribute(const QualifiedName& attributeName)
+String HTMLElement::outerHTML() const
{
- static NeverDestroyed<EventHandlerNameMap> map = createEventHandlerNameMap();
- return eventNameForEventHandlerAttribute(attributeName, map.get());
+ return createMarkup(*this);
}
-Node::Editability HTMLElement::editabilityFromContentEditableAttr(const Node& node)
+void HTMLElement::setInnerHTML(const String& html, ExceptionCode& ec)
{
- if (auto* startElement = is<Element>(node) ? &downcast<Element>(node) : node.parentElement()) {
- for (auto& element : lineageOfType<HTMLElement>(*startElement)) {
- switch (contentEditableType(element)) {
- case ContentEditableType::True:
- return Editability::CanEditRichly;
- case ContentEditableType::PlaintextOnly:
- return Editability::CanEditPlainText;
- case ContentEditableType::False:
- return Editability::ReadOnly;
- case ContentEditableType::Inherit:
- break;
- }
- }
+ if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, ec)) {
+ ContainerNode* container = this;
+#if ENABLE(TEMPLATE_ELEMENT)
+ if (hasLocalName(templateTag))
+ container = toHTMLTemplateElement(this)->content();
+#endif
+ replaceChildrenWithFragment(*container, fragment.release(), ec);
}
-
- auto& document = node.document();
- if (is<HTMLDocument>(document))
- return downcast<HTMLDocument>(document).inDesignMode() ? Editability::CanEditRichly : Editability::ReadOnly;
-
- return Editability::ReadOnly;
}
-bool HTMLElement::matchesReadWritePseudoClass() const
+static void mergeWithNextTextNode(Text& node, ExceptionCode& ec)
{
- return editabilityFromContentEditableAttr(*this) != Editability::ReadOnly;
+ Node* next = node.nextSibling();
+ if (!next || !next->isTextNode())
+ return;
+
+ Ref<Text> textNode(node);
+ Ref<Text> textNext(toText(*next));
+ textNode->appendData(textNext->data(), ec);
+ if (ec)
+ return;
+ textNext->remove(ec);
}
-void HTMLElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
+void HTMLElement::setOuterHTML(const String& html, ExceptionCode& ec)
{
- if (name == dirAttr) {
- dirAttributeChanged(value);
+ Element* p = parentElement();
+ if (!p || !p->isHTMLElement()) {
+ ec = NO_MODIFICATION_ALLOWED_ERR;
return;
}
+ RefPtr<HTMLElement> parent = toHTMLElement(p);
+ RefPtr<Node> prev = previousSibling();
+ RefPtr<Node> next = nextSibling();
- if (name == tabindexAttr) {
- int tabIndex = 0;
- if (value.isEmpty())
- clearTabIndexExplicitlyIfNeeded();
- else if (parseHTMLInteger(value, tabIndex)) {
- // Clamp tab index to a 16-bit value to match Firefox's behavior.
- setTabIndexExplicitly(std::max(-0x8000, std::min(tabIndex, 0x7FFF)));
- }
+ RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, parent.get(), AllowScriptingContent, ec);
+ if (ec)
return;
- }
-
- auto& eventName = eventNameForEventHandlerAttribute(name);
- if (!eventName.isNull())
- setAttributeEventListener(eventName, name, value);
+
+ parent->replaceChild(fragment.release(), this, ec);
+ RefPtr<Node> node = next ? next->previousSibling() : nullptr;
+ if (!ec && node && node->isTextNode())
+ mergeWithNextTextNode(toText(*node), ec);
+ if (!ec && prev && prev->isTextNode())
+ mergeWithNextTextNode(toText(*prev), ec);
}
-Ref<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionCode& ec)
+PassRefPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionCode& ec)
{
- ec = 0;
-
- auto fragment = DocumentFragment::create(document());
-
- for (unsigned start = 0, length = text.length(); start < length; ) {
+ RefPtr<DocumentFragment> fragment = DocumentFragment::create(document());
+ unsigned int i, length = text.length();
+ UChar c = 0;
+ for (unsigned int start = 0; start < length; ) {
// Find next line break.
- UChar c;
- unsigned i;
for (i = start; i < length; i++) {
c = text[i];
if (c == '\r' || c == '\n')
@@ -482,18 +433,16 @@ Ref<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionC
fragment->appendChild(Text::create(document(), text.substring(start, i - start)), ec);
if (ec)
- break;
-
- if (i == length)
- break;
-
- fragment->appendChild(HTMLBRElement::create(document()), ec);
- if (ec)
- break;
+ return nullptr;
- // Make sure \r\n doesn't result in two line breaks.
- if (c == '\r' && i + 1 < length && text[i + 1] == '\n')
- ++i;
+ if (c == '\r' || c == '\n') {
+ fragment->appendChild(HTMLBRElement::create(document()), ec);
+ if (ec)
+ return nullptr;
+ // Make sure \r\n doesn't result in two line breaks.
+ if (c == '\r' && i + 1 < length && text[i + 1] == '\n')
+ i++;
+ }
start = i + 1; // Character after line break.
}
@@ -501,56 +450,16 @@ Ref<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionC
return fragment;
}
-static inline bool shouldProhibitSetInnerOuterText(const HTMLElement& element)
-{
- return element.hasTagName(colTag)
- || element.hasTagName(colgroupTag)
- || element.hasTagName(framesetTag)
- || element.hasTagName(headTag)
- || element.hasTagName(htmlTag)
- || element.hasTagName(tableTag)
- || element.hasTagName(tbodyTag)
- || element.hasTagName(tfootTag)
- || element.hasTagName(theadTag)
- || element.hasTagName(trTag);
-}
-
-// Returns the conforming 'dir' value associated with the state the attribute is in (in its canonical case), if any,
-// or the empty string if the attribute is in a state that has no associated keyword value or if the attribute is
-// not in a defined state (e.g. the attribute is missing and there is no missing value default).
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#limited-to-only-known-values
-static inline const AtomicString& toValidDirValue(const AtomicString& value)
-{
- static NeverDestroyed<AtomicString> ltrValue("ltr", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> rtlValue("rtl", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> autoValue("auto", AtomicString::ConstructFromLiteral);
-
- if (equalIgnoringCase(value, ltrValue))
- return ltrValue;
- if (equalIgnoringCase(value, rtlValue))
- return rtlValue;
- if (equalIgnoringCase(value, autoValue))
- return autoValue;
- return nullAtom;
-}
-
-const AtomicString& HTMLElement::dir() const
-{
- return toValidDirValue(fastGetAttribute(dirAttr));
-}
-
-void HTMLElement::setDir(const AtomicString& value)
-{
- setAttribute(dirAttr, value);
-}
-
void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
{
if (ieForbidsInsertHTML()) {
ec = NO_MODIFICATION_ALLOWED_ERR;
return;
}
- if (shouldProhibitSetInnerOuterText(*this)) {
+ if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) ||
+ hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag) ||
+ hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTag) ||
+ hasLocalName(trTag)) {
ec = NO_MODIFICATION_ALLOWED_ERR;
return;
}
@@ -595,7 +504,10 @@ void HTMLElement::setOuterText(const String& text, ExceptionCode& ec)
ec = NO_MODIFICATION_ALLOWED_ERR;
return;
}
- if (shouldProhibitSetInnerOuterText(*this)) {
+ if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) ||
+ hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag) ||
+ hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTag) ||
+ hasLocalName(trTag)) {
ec = NO_MODIFICATION_ALLOWED_ERR;
return;
}
@@ -617,17 +529,17 @@ void HTMLElement::setOuterText(const String& text, ExceptionCode& ec)
else
newChild = Text::create(document(), text);
- if (!parentNode())
+ if (!this || !parentNode())
ec = HIERARCHY_REQUEST_ERR;
if (ec)
return;
parent->replaceChild(newChild.release(), this, ec);
RefPtr<Node> node = next ? next->previousSibling() : nullptr;
- if (!ec && is<Text>(node.get()))
- mergeWithNextTextNode(downcast<Text>(*node), ec);
- if (!ec && is<Text>(prev.get()))
- mergeWithNextTextNode(downcast<Text>(*prev), ec);
+ if (!ec && node && node->isTextNode())
+ mergeWithNextTextNode(toText(*node), ec);
+ if (!ec && prev && prev->isTextNode())
+ mergeWithNextTextNode(toText(*prev), ec);
}
Node* HTMLElement::insertAdjacent(const String& where, Node* newChild, ExceptionCode& ec)
@@ -669,8 +581,8 @@ Element* HTMLElement::insertAdjacentElement(const String& where, Element* newChi
}
Node* returnValue = insertAdjacent(where, newChild, ec);
- ASSERT_WITH_SECURITY_IMPLICATION(!returnValue || is<Element>(*returnValue));
- return downcast<Element>(returnValue);
+ ASSERT_WITH_SECURITY_IMPLICATION(!returnValue || returnValue->isElementNode());
+ return toElement(returnValue);
}
// Step 3 of http://www.whatwg.org/specs/web-apps/current-work/multipage/apis-in-html-documents.html#insertadjacenthtml()
@@ -678,12 +590,12 @@ static Element* contextElementForInsertion(const String& where, Element* element
{
if (equalIgnoringCase(where, "beforeBegin") || equalIgnoringCase(where, "afterEnd")) {
ContainerNode* parent = element->parentNode();
- if (parent && !is<Element>(*parent)) {
+ if (parent && !parent->isElementNode()) {
ec = NO_MODIFICATION_ALLOWED_ERR;
return nullptr;
}
- ASSERT_WITH_SECURITY_IMPLICATION(!parent || is<Element>(*parent));
- return downcast<Element>(parent);
+ ASSERT_WITH_SECURITY_IMPLICATION(!parent || parent->isElementNode());
+ return toElement(parent);
}
if (equalIgnoringCase(where, "afterBegin") || equalIgnoringCase(where, "beforeEnd"))
return element;
@@ -755,16 +667,17 @@ bool HTMLElement::supportsFocus() const
String HTMLElement::contentEditable() const
{
- switch (contentEditableType(*this)) {
- case ContentEditableType::Inherit:
+ const AtomicString& value = fastGetAttribute(contenteditableAttr);
+
+ if (value.isNull())
return ASCIILiteral("inherit");
- case ContentEditableType::True:
+ if (value.isEmpty() || equalIgnoringCase(value, "true"))
return ASCIILiteral("true");
- case ContentEditableType::False:
+ if (equalIgnoringCase(value, "false"))
return ASCIILiteral("false");
- case ContentEditableType::PlaintextOnly:
+ if (equalIgnoringCase(value, "plaintext-only"))
return ASCIILiteral("plaintext-only");
- }
+
return ASCIILiteral("inherit");
}
@@ -828,6 +741,11 @@ short HTMLElement::tabIndex() const
return -1;
}
+void HTMLElement::setTabIndex(int value)
+{
+ setIntegralAttribute(tabindexAttr, value);
+}
+
TranslateAttributeMode HTMLElement::translateAttributeMode() const
{
const AtomicString& value = fastGetAttribute(translateAttr);
@@ -861,23 +779,30 @@ void HTMLElement::setTranslate(bool enable)
setAttribute(translateAttr, enable ? "yes" : "no");
}
+PassRefPtr<HTMLCollection> HTMLElement::children()
+{
+ return ensureCachedHTMLCollection(NodeChildren);
+}
+
bool HTMLElement::rendererIsNeeded(const RenderStyle& style)
{
- if (hasTagName(noscriptTag)) {
+ if (hasLocalName(noscriptTag)) {
Frame* frame = document().frame();
if (frame && frame->script().canExecuteScripts(NotAboutToExecuteScript))
return false;
- } else if (hasTagName(noembedTag)) {
+ } else if (hasLocalName(noembedTag)) {
Frame* frame = document().frame();
- if (frame && frame->loader().subframeLoader().allowPlugins())
+ if (frame && frame->loader().subframeLoader().allowPlugins(NotAboutToInstantiatePlugin))
return false;
}
return StyledElement::rendererIsNeeded(style);
}
-RenderPtr<RenderElement> HTMLElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return RenderElement::createFor(*this, WTF::move(style));
+ if (hasLocalName(wbrTag))
+ return createRenderer<RenderLineBreak>(*this, std::move(style));
+ return RenderElement::createFor(*this, std::move(style));
}
HTMLFormElement* HTMLElement::virtualForm() const
@@ -887,10 +812,7 @@ HTMLFormElement* HTMLElement::virtualForm() const
static inline bool elementAffectsDirectionality(const Node& node)
{
- if (!is<HTMLElement>(node))
- return false;
- const HTMLElement& element = downcast<HTMLElement>(node);
- return is<HTMLBDIElement>(element) || element.fastHasAttribute(dirAttr);
+ return node.isHTMLElement() && (node.hasTagName(bdiTag) || toHTMLElement(node).hasAttribute(dirAttr));
}
static void setHasDirAutoFlagRecursively(Node* firstNode, bool flag, Node* lastNode = nullptr)
@@ -906,13 +828,13 @@ static void setHasDirAutoFlagRecursively(Node* firstNode, bool flag, Node* lastN
if (elementAffectsDirectionality(*node)) {
if (node == lastNode)
return;
- node = NodeTraversal::nextSkippingChildren(*node, firstNode);
+ node = NodeTraversal::nextSkippingChildren(node, firstNode);
continue;
}
node->setSelfOrAncestorHasDirAutoAttribute(flag);
if (node == lastNode)
return;
- node = NodeTraversal::next(*node, firstNode);
+ node = NodeTraversal::next(node, firstNode);
}
}
@@ -941,12 +863,12 @@ TextDirection HTMLElement::directionalityIfhasDirAutoAttribute(bool& isAuto) con
TextDirection HTMLElement::directionality(Node** strongDirectionalityTextNode) const
{
- if (is<HTMLTextFormControlElement>(*this)) {
- HTMLTextFormControlElement& textElement = downcast<HTMLTextFormControlElement>(const_cast<HTMLElement&>(*this));
+ if (isHTMLTextFormControlElement(*this)) {
+ HTMLTextFormControlElement* textElement = toHTMLTextFormControlElement(const_cast<HTMLElement*>(this));
bool hasStrongDirectionality;
- UCharDirection textDirection = textElement.value().defaultWritingDirection(&hasStrongDirectionality);
+ UCharDirection textDirection = textElement->value().defaultWritingDirection(&hasStrongDirectionality);
if (strongDirectionalityTextNode)
- *strongDirectionalityTextNode = hasStrongDirectionality ? &textElement : nullptr;
+ *strongDirectionalityTextNode = hasStrongDirectionality ? textElement : nullptr;
return (textDirection == U_LEFT_TO_RIGHT) ? LTR : RTL;
}
@@ -954,16 +876,16 @@ TextDirection HTMLElement::directionality(Node** strongDirectionalityTextNode) c
while (node) {
// Skip bdi, script, style and text form controls.
if (equalIgnoringCase(node->nodeName(), "bdi") || node->hasTagName(scriptTag) || node->hasTagName(styleTag)
- || (is<Element>(*node) && downcast<Element>(*node).isTextFormControl())) {
- node = NodeTraversal::nextSkippingChildren(*node, this);
+ || (node->isElementNode() && toElement(node)->isTextFormControl())) {
+ node = NodeTraversal::nextSkippingChildren(node, this);
continue;
}
// Skip elements with valid dir attribute
- if (is<Element>(*node)) {
- AtomicString dirAttributeValue = downcast<Element>(*node).fastGetAttribute(dirAttr);
+ if (node->isElementNode()) {
+ AtomicString dirAttributeValue = toElement(node)->fastGetAttribute(dirAttr);
if (isLTROrRTLIgnoringCase(dirAttributeValue) || equalIgnoringCase(dirAttributeValue, "auto")) {
- node = NodeTraversal::nextSkippingChildren(*node, this);
+ node = NodeTraversal::nextSkippingChildren(node, this);
continue;
}
}
@@ -977,7 +899,7 @@ TextDirection HTMLElement::directionality(Node** strongDirectionalityTextNode) c
return (textDirection == U_LEFT_TO_RIGHT) ? LTR : RTL;
}
}
- node = NodeTraversal::next(*node, this);
+ node = NodeTraversal::next(node, this);
}
if (strongDirectionalityTextNode)
*strongDirectionalityTextNode = nullptr;
@@ -988,8 +910,8 @@ void HTMLElement::dirAttributeChanged(const AtomicString& value)
{
Element* parent = parentElement();
- if (is<HTMLElement>(parent) && parent->selfOrAncestorHasDirAutoAttribute())
- downcast<HTMLElement>(*parent).adjustDirectionalityIfNeededAfterChildAttributeChanged(this);
+ if (parent && parent->isHTMLElement() && parent->selfOrAncestorHasDirAutoAttribute())
+ toHTMLElement(parent)->adjustDirectionalityIfNeededAfterChildAttributeChanged(this);
if (equalIgnoringCase(value, "auto"))
calculateAndAdjustDirectionality();
@@ -1023,13 +945,22 @@ void HTMLElement::calculateAndAdjustDirectionality()
void HTMLElement::adjustDirectionalityIfNeededAfterChildrenChanged(Element* beforeChange, ChildChangeType changeType)
{
// FIXME: This function looks suspicious.
+ if (document().renderView() && (changeType == ElementRemoved || changeType == TextRemoved)) {
+ Node* node = beforeChange ? beforeChange->nextSibling() : nullptr;
+ for (; node; node = node->nextSibling()) {
+ if (elementAffectsDirectionality(*node))
+ continue;
+
+ setHasDirAutoFlagRecursively(node, false);
+ }
+ }
if (!selfOrAncestorHasDirAutoAttribute())
return;
Node* oldMarkedNode = nullptr;
if (beforeChange)
- oldMarkedNode = changeType == ElementInserted ? ElementTraversal::nextSibling(*beforeChange) : beforeChange->nextSibling();
+ oldMarkedNode = changeType == ElementInserted ? ElementTraversal::nextSibling(beforeChange) : beforeChange->nextSibling();
while (oldMarkedNode && elementAffectsDirectionality(*oldMarkedNode))
oldMarkedNode = oldMarkedNode->nextSibling();
@@ -1044,6 +975,11 @@ void HTMLElement::adjustDirectionalityIfNeededAfterChildrenChanged(Element* befo
}
}
+bool HTMLElement::isURLAttribute(const Attribute& attribute) const
+{
+ return StyledElement::isURLAttribute(attribute);
+}
+
void HTMLElement::addHTMLLengthToStyle(MutableStyleProperties& style, CSSPropertyID propertyID, const String& value)
{
// FIXME: This function should not spin up the CSS parser, but should instead just figure out the correct
diff --git a/Source/WebCore/html/HTMLElement.h b/Source/WebCore/html/HTMLElement.h
index 30e3775a0..0080677d4 100644
--- a/Source/WebCore/html/HTMLElement.h
+++ b/Source/WebCore/html/HTMLElement.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004-2009, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -40,12 +40,19 @@ enum TranslateAttributeMode {
class HTMLElement : public StyledElement {
public:
- static Ref<HTMLElement> create(const QualifiedName& tagName, Document&);
+ static PassRefPtr<HTMLElement> create(const QualifiedName& tagName, Document&);
- WEBCORE_EXPORT virtual String title() const override final;
+ PassRefPtr<HTMLCollection> children();
+
+ virtual String title() const override final;
virtual short tabIndex() const override;
+ void setTabIndex(int);
+ String innerHTML() const;
+ String outerHTML() const;
+ void setInnerHTML(const String&, ExceptionCode&);
+ void setOuterHTML(const String&, ExceptionCode&);
void setInnerText(const String&, ExceptionCode&);
void setOuterText(const String&, ExceptionCode&);
@@ -59,8 +66,6 @@ public:
String contentEditable() const;
void setContentEditable(const String&, ExceptionCode&);
- static Editability editabilityFromContentEditableAttr(const Node&);
-
virtual bool draggable() const;
void setDraggable(bool);
@@ -77,13 +82,10 @@ public:
bool ieForbidsInsertHTML() const;
virtual bool rendererIsNeeded(const RenderStyle&) override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
HTMLFormElement* form() const { return virtualForm(); }
- const AtomicString& dir() const;
- void setDir(const AtomicString&);
-
bool hasDirectionAuto() const;
TextDirection directionalityIfhasDirAutoAttribute(bool& isAuto) const;
@@ -97,10 +99,6 @@ public:
virtual bool isLabelable() const { return false; }
virtual FormNamedItem* asFormNamedItem() { return 0; }
- bool hasTagName(const HTMLQualifiedName& name) const { return hasLocalName(name.localName()); }
-
- static const AtomicString& eventNameForEventHandlerAttribute(const QualifiedName& attributeName);
-
protected:
HTMLElement(const QualifiedName& tagName, Document&, ConstructionType);
@@ -110,7 +108,6 @@ protected:
void applyAlignmentAttributeToStyle(const AtomicString&, MutableStyleProperties&);
void applyBorderAttributeToStyle(const AtomicString&, MutableStyleProperties&);
- virtual bool matchesReadWritePseudoClass() const override;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
virtual bool isPresentationAttribute(const QualifiedName&) const override;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
@@ -119,9 +116,7 @@ protected:
virtual void childrenChanged(const ChildChange&) override;
void calculateAndAdjustDirectionality();
- typedef HashMap<AtomicStringImpl*, AtomicString> EventHandlerNameMap;
- template<size_t tableSize> static void populateEventHandlerNameMap(EventHandlerNameMap&, const QualifiedName* const (&table)[tableSize]);
- static const AtomicString& eventNameForEventHandlerAttribute(const QualifiedName& attributeName, const EventHandlerNameMap&);
+ virtual bool isURLAttribute(const Attribute&) const override;
private:
virtual String nodeName() const override final;
@@ -131,7 +126,7 @@ private:
virtual HTMLFormElement* virtualForm() const;
Node* insertAdjacent(const String& where, Node* newChild, ExceptionCode&);
- Ref<DocumentFragment> textToFragment(const String&, ExceptionCode&);
+ PassRefPtr<DocumentFragment> textToFragment(const String&, ExceptionCode&);
void dirAttributeChanged(const AtomicString&);
void adjustDirectionalityIfNeededAfterChildAttributeChanged(Element* child);
@@ -139,9 +134,6 @@ private:
TextDirection directionality(Node** strongDirectionalityTextNode= 0) const;
TranslateAttributeMode translateAttributeMode() const;
-
- static void populateEventHandlerNameMap(EventHandlerNameMap&, const QualifiedName* const table[], size_t tableSize);
- static EventHandlerNameMap createEventHandlerNameMap();
};
inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document& document, ConstructionType type = CreateHTMLElement)
@@ -150,21 +142,16 @@ inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document& document
ASSERT(tagName.localName().impl());
}
-template<size_t tableSize> inline void HTMLElement::populateEventHandlerNameMap(EventHandlerNameMap& map, const QualifiedName* const (&table)[tableSize])
-{
- populateEventHandlerNameMap(map, table, tableSize);
-}
+template <typename Type> bool isElementOfType(const HTMLElement&);
-inline bool Node::hasTagName(const HTMLQualifiedName& name) const
-{
- return is<HTMLElement>(*this) && downcast<HTMLElement>(*this).hasTagName(name);
-}
+void isHTMLElement(const HTMLElement&); // Catch unnecessary runtime check of type known at compile time.
+inline bool isHTMLElement(const Node& node) { return node.isHTMLElement(); }
+template <> inline bool isElementOfType<const HTMLElement>(const HTMLElement&) { return true; }
+template <> inline bool isElementOfType<const HTMLElement>(const Element& element) { return element.isHTMLElement(); }
-} // namespace WebCore
+NODE_TYPE_CASTS(HTMLElement)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLElement)
- static bool isType(const WebCore::Node& node) { return node.isHTMLElement(); }
-SPECIALIZE_TYPE_TRAITS_END()
+} // namespace WebCore
#include "HTMLElementTypeHelpers.h"
diff --git a/Source/WebCore/html/HTMLElement.idl b/Source/WebCore/html/HTMLElement.idl
index 2cdf72fea..99767fc15 100644
--- a/Source/WebCore/html/HTMLElement.idl
+++ b/Source/WebCore/html/HTMLElement.idl
@@ -29,7 +29,7 @@
[Reflect] attribute DOMString title;
[Reflect] attribute DOMString lang;
attribute boolean translate;
- attribute DOMString dir;
+ [Reflect] attribute DOMString dir;
attribute long tabIndex;
attribute boolean draggable;
@@ -38,9 +38,11 @@
[Reflect] attribute DOMString accessKey;
// Extensions
- [TreatNullAs=NullString, SetterRaisesException] attribute DOMString innerText;
- [TreatNullAs=NullString, SetterRaisesException] attribute DOMString outerText;
-
+ [TreatNullAs=NullString, SetterRaisesException] attribute DOMString innerHTML;
+ [TreatNullAs=NullString, SetterRaisesException] attribute DOMString innerText;
+ [TreatNullAs=NullString, SetterRaisesException] attribute DOMString outerHTML;
+ [TreatNullAs=NullString, SetterRaisesException] attribute DOMString outerText;
+
[RaisesException] Element insertAdjacentElement([Default=Undefined] optional DOMString where,
[Default=Undefined] optional Element element);
[RaisesException] void insertAdjacentHTML([Default=Undefined] optional DOMString where,
@@ -48,9 +50,7 @@
[RaisesException] void insertAdjacentText([Default=Undefined] optional DOMString where,
[Default=Undefined] optional DOMString text);
-#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
readonly attribute HTMLCollection children;
-#endif
[TreatNullAs=NullString, SetterRaisesException] attribute DOMString contentEditable;
readonly attribute boolean isContentEditable;
diff --git a/Source/WebCore/html/HTMLElementsAllInOne.cpp b/Source/WebCore/html/HTMLElementsAllInOne.cpp
deleted file mode 100644
index 94f9a2d6e..000000000
--- a/Source/WebCore/html/HTMLElementsAllInOne.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2009, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// This source file coalesces the HTML elements into a single object file to
-// reduce bloat and allow us to link release builds on 32-bit Windows.
-
-// This file comes first due to the inclusion of conflicting X11 headers
-#include "HTMLPlugInElement.cpp"
-
-#include "HTMLAnchorElement.cpp"
-#include "HTMLAppletElement.cpp"
-#include "HTMLAreaElement.cpp"
-#include "HTMLAttachmentElement.cpp"
-#include "HTMLAudioElement.cpp"
-#include "HTMLBRElement.cpp"
-#include "HTMLBaseElement.cpp"
-#include "HTMLBaseFontElement.cpp"
-#include "HTMLBodyElement.cpp"
-#include "HTMLButtonElement.cpp"
-#include "HTMLCanvasElement.cpp"
-#include "HTMLDataListElement.cpp"
-#include "HTMLDetailsElement.cpp"
-#include "HTMLDListElement.cpp"
-#include "HTMLDirectoryElement.cpp"
-#include "HTMLDivElement.cpp"
-#include "HTMLElement.cpp"
-#include "HTMLEmbedElement.cpp"
-#include "HTMLFieldSetElement.cpp"
-#include "HTMLFontElement.cpp"
-#include "HTMLFormControlElement.cpp"
-#include "HTMLFormControlElementWithState.cpp"
-#include "HTMLFormElement.cpp"
-#include "HTMLFrameElement.cpp"
-#include "HTMLFrameElementBase.cpp"
-#include "HTMLFrameOwnerElement.cpp"
-#include "HTMLFrameSetElement.cpp"
-#include "HTMLHRElement.cpp"
-#include "HTMLHeadElement.cpp"
-#include "HTMLHeadingElement.cpp"
-#include "HTMLHtmlElement.cpp"
-#include "HTMLIFrameElement.cpp"
-#include "HTMLImageElement.cpp"
-#include "HTMLInputElement.cpp"
-#include "HTMLKeygenElement.cpp"
-#include "HTMLLIElement.cpp"
-#include "HTMLLabelElement.cpp"
-#include "HTMLLegendElement.cpp"
-#include "HTMLLinkElement.cpp"
-#include "HTMLMapElement.cpp"
-#include "HTMLMarqueeElement.cpp"
-#include "HTMLMediaElement.cpp"
-#include "HTMLMenuElement.cpp"
-#include "HTMLMetaElement.cpp"
-#include "HTMLMeterElement.cpp"
-#include "HTMLModElement.cpp"
-#include "HTMLOListElement.cpp"
-#include "HTMLObjectElement.cpp"
-#include "HTMLOptGroupElement.cpp"
-#include "HTMLOptionElement.cpp"
-#include "HTMLOutputElement.cpp"
-#include "HTMLParagraphElement.cpp"
-#include "HTMLParamElement.cpp"
-#include "HTMLPlugInImageElement.cpp"
-#include "HTMLPreElement.cpp"
-#include "HTMLProgressElement.cpp"
-#include "HTMLQuoteElement.cpp"
-#include "HTMLScriptElement.cpp"
-#include "HTMLSelectElement.cpp"
-#include "HTMLSourceElement.cpp"
-#include "HTMLSpanElement.cpp"
-#include "HTMLStyleElement.cpp"
-#include "HTMLSummaryElement.cpp"
-#include "HTMLTableCaptionElement.cpp"
-#include "HTMLTableCellElement.cpp"
-#include "HTMLTableColElement.cpp"
-#include "HTMLTableElement.cpp"
-#include "HTMLTablePartElement.cpp"
-#include "HTMLTableRowElement.cpp"
-#include "HTMLTableSectionElement.cpp"
-#include "HTMLTemplateElement.cpp"
-#include "HTMLTextAreaElement.cpp"
-#include "HTMLTextFormControlElement.cpp"
-#include "HTMLTitleElement.cpp"
-#include "HTMLTrackElement.cpp"
-#include "HTMLUListElement.cpp"
-#include "HTMLVideoElement.cpp"
-#include "HTMLWBRElement.cpp"
-
diff --git a/Source/WebCore/html/HTMLEmbedElement.cpp b/Source/WebCore/html/HTMLEmbedElement.cpp
index 405655719..d014fa4d2 100644
--- a/Source/WebCore/html/HTMLEmbedElement.cpp
+++ b/Source/WebCore/html/HTMLEmbedElement.cpp
@@ -24,6 +24,7 @@
#include "config.h"
#include "HTMLEmbedElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "Frame.h"
#include "FrameLoader.h"
@@ -49,33 +50,32 @@ inline HTMLEmbedElement::HTMLEmbedElement(const QualifiedName& tagName, Document
ASSERT(hasTagName(embedTag));
}
-Ref<HTMLEmbedElement> HTMLEmbedElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
+PassRefPtr<HTMLEmbedElement> HTMLEmbedElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
{
- return adoptRef(*new HTMLEmbedElement(tagName, document, createdByParser));
+ return adoptRef(new HTMLEmbedElement(tagName, document, createdByParser));
}
-static inline RenderWidget* findWidgetRenderer(const Node* node)
+static inline RenderWidget* findWidgetRenderer(const Node* n)
{
- if (!node->renderer()) {
- do {
- node = node->parentNode();
- } while (node && !is<HTMLObjectElement>(*node));
- }
+ if (!n->renderer())
+ do
+ n = n->parentNode();
+ while (n && !n->hasTagName(objectTag));
- if (node && is<RenderWidget>(node->renderer()))
- return downcast<RenderWidget>(node->renderer());
+ if (n && n->renderer() && n->renderer()->isWidget())
+ return toRenderWidget(n->renderer());
- return nullptr;
+ return 0;
}
-RenderWidget* HTMLEmbedElement::renderWidgetLoadingPlugin() const
+RenderWidget* HTMLEmbedElement::renderWidgetForJSBindings() const
{
FrameView* view = document().view();
if (!view || (!view->isInLayout() && !view->isPainting())) {
// Needs to load the plugin immediatedly because this function is called
// when JavaScript code accesses the plugin.
// FIXME: <rdar://16893708> Check if dispatching events here is safe.
- document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
+ document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasksSynchronously);
}
return findWidgetRenderer(this);
}
@@ -101,23 +101,20 @@ void HTMLEmbedElement::collectStyleForPresentationAttribute(const QualifiedName&
void HTMLEmbedElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == typeAttr) {
- m_serviceType = value.string().left(value.find(';')).lower();
- // FIXME: The only difference between this and HTMLObjectElement's corresponding
- // code is that HTMLObjectElement does setNeedsWidgetUpdate(true). Consider moving
- // this up to the HTMLPlugInImageElement to be shared.
- } else if (name == codeAttr) {
+ m_serviceType = value.string().lower();
+ size_t pos = m_serviceType.find(";");
+ if (pos != notFound)
+ m_serviceType = m_serviceType.left(pos);
+ } else if (name == codeAttr)
m_url = stripLeadingAndTrailingHTMLSpaces(value);
- // FIXME: Why no call to the image loader?
- // FIXME: If both code and src attributes are specified, last one parsed/changed wins. That can't be right!
- } else if (name == srcAttr) {
+ else if (name == srcAttr) {
m_url = stripLeadingAndTrailingHTMLSpaces(value);
document().updateStyleIfNeeded();
if (renderer() && isImageType()) {
if (!m_imageLoader)
- m_imageLoader = std::make_unique<HTMLImageLoader>(*this);
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
m_imageLoader->updateFromElementIgnoringPreviousError();
}
- // FIXME: If both code and src attributes are specified, last one parsed/changed wins. That can't be right!
} else
HTMLPlugInImageElement::parseAttribute(name, value);
}
@@ -166,11 +163,11 @@ void HTMLEmbedElement::updateWidget(PluginCreationOption pluginCreationOption)
Ref<HTMLEmbedElement> protect(*this); // Loading the plugin might remove us from the document.
bool beforeLoadAllowedLoad = guardedDispatchBeforeLoadEvent(m_url);
if (!beforeLoadAllowedLoad) {
- if (is<PluginDocument>(document())) {
+ if (document().isPluginDocument()) {
// Plugins inside plugin documents load differently than other plugins. By the time
// we are here in a plugin document, the load of the plugin (which is the plugin document's
// main resource) has already started. We need to explicitly cancel the main resource load here.
- downcast<PluginDocument>(document()).cancelManualPluginLoad();
+ toPluginDocument(&document())->cancelManualPluginLoad();
}
return;
}
@@ -188,12 +185,12 @@ bool HTMLEmbedElement::rendererIsNeeded(const RenderStyle& style)
// If my parent is an <object> and is not set to use fallback content, I
// should be ignored and not get a renderer.
- ContainerNode* parent = parentNode();
- if (is<HTMLObjectElement>(parent)) {
- if (!parent->renderer())
+ ContainerNode* p = parentNode();
+ if (p && p->hasTagName(objectTag)) {
+ if (!p->renderer())
return false;
- if (!downcast<HTMLObjectElement>(*parent).useFallbackContent()) {
- ASSERT(!parent->renderer()->isEmbeddedObject());
+ if (!toHTMLObjectElement(p)->useFallbackContent()) {
+ ASSERT(!p->renderer()->isEmbeddedObject());
return false;
}
}
@@ -214,14 +211,14 @@ bool HTMLEmbedElement::isURLAttribute(const Attribute& attribute) const
const AtomicString& HTMLEmbedElement::imageSourceURL() const
{
- return fastGetAttribute(srcAttr);
+ return getAttribute(srcAttr);
}
void HTMLEmbedElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
{
HTMLPlugInImageElement::addSubresourceAttributeURLs(urls);
- addSubresourceURL(urls, document().completeURL(fastGetAttribute(srcAttr)));
+ addSubresourceURL(urls, document().completeURL(getAttribute(srcAttr)));
}
}
diff --git a/Source/WebCore/html/HTMLEmbedElement.h b/Source/WebCore/html/HTMLEmbedElement.h
index 4607e3eb1..d9fd4523e 100644
--- a/Source/WebCore/html/HTMLEmbedElement.h
+++ b/Source/WebCore/html/HTMLEmbedElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLEmbedElement final : public HTMLPlugInImageElement {
public:
- static Ref<HTMLEmbedElement> create(const QualifiedName&, Document&, bool createdByParser);
+ static PassRefPtr<HTMLEmbedElement> create(const QualifiedName&, Document&, bool createdByParser);
private:
HTMLEmbedElement(const QualifiedName&, Document&, bool createdByParser);
@@ -43,7 +43,7 @@ private:
virtual bool isURLAttribute(const Attribute&) const override;
virtual const AtomicString& imageSourceURL() const override;
- virtual RenderWidget* renderWidgetLoadingPlugin() const override;
+ virtual RenderWidget* renderWidgetForJSBindings() const override;
virtual void updateWidget(PluginCreationOption) override;
@@ -52,6 +52,8 @@ private:
void parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues);
};
+NODE_TYPE_CASTS(HTMLEmbedElement)
+
}
#endif
diff --git a/Source/WebCore/html/HTMLEmbedElement.idl b/Source/WebCore/html/HTMLEmbedElement.idl
index 6ea0764f5..f209e86c5 100644
--- a/Source/WebCore/html/HTMLEmbedElement.idl
+++ b/Source/WebCore/html/HTMLEmbedElement.idl
@@ -38,8 +38,10 @@
[Reflect] attribute long width;
#endif
+#if defined(ENABLE_SVG) && ENABLE_SVG
#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
[CheckSecurityForNode, RaisesException] SVGDocument getSVGDocument();
#endif
+#endif
};
diff --git a/Source/WebCore/html/HTMLFieldSetElement.cpp b/Source/WebCore/html/HTMLFieldSetElement.cpp
index ac332e870..0dab60d55 100644
--- a/Source/WebCore/html/HTMLFieldSetElement.cpp
+++ b/Source/WebCore/html/HTMLFieldSetElement.cpp
@@ -44,98 +44,30 @@ inline HTMLFieldSetElement::HTMLFieldSetElement(const QualifiedName& tagName, Do
ASSERT(hasTagName(fieldsetTag));
}
-HTMLFieldSetElement::~HTMLFieldSetElement()
+PassRefPtr<HTMLFieldSetElement> HTMLFieldSetElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
{
- if (fastHasAttribute(disabledAttr))
- document().removeDisabledFieldsetElement();
+ return adoptRef(new HTMLFieldSetElement(tagName, document, form));
}
-Ref<HTMLFieldSetElement> HTMLFieldSetElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
+void HTMLFieldSetElement::invalidateDisabledStateUnder(Element* base)
{
- return adoptRef(*new HTMLFieldSetElement(tagName, document, form));
-}
-
-static void updateFromControlElementsAncestorDisabledStateUnder(HTMLElement& startNode, bool isDisabled)
-{
- HTMLFormControlElement* control;
- if (is<HTMLFormControlElement>(startNode))
- control = &downcast<HTMLFormControlElement>(startNode);
- else
- control = Traversal<HTMLFormControlElement>::firstWithin(startNode);
- while (control) {
- control->setAncestorDisabled(isDisabled);
- // Don't call setAncestorDisabled(false) on form contorls inside disabled fieldsets.
- if (is<HTMLFieldSetElement>(*control) && control->fastHasAttribute(disabledAttr))
- control = Traversal<HTMLFormControlElement>::nextSkippingChildren(*control, &startNode);
- else
- control = Traversal<HTMLFormControlElement>::next(*control, &startNode);
- }
+ for (auto& control : descendantsOfType<HTMLFormControlElement>(*base))
+ control.ancestorDisabledStateWasChanged();
}
void HTMLFieldSetElement::disabledAttributeChanged()
{
- if (fastHasAttribute(disabledAttr))
- document().addDisabledFieldsetElement();
- else
- document().removeDisabledFieldsetElement();
-
- HTMLFormControlElement::disabledAttributeChanged();
-}
-
-void HTMLFieldSetElement::disabledStateChanged()
-{
// This element must be updated before the style of nodes in its subtree gets recalculated.
- HTMLFormControlElement::disabledStateChanged();
-
- if (disabledByAncestorFieldset())
- return;
-
- bool thisFieldsetIsDisabled = fastHasAttribute(disabledAttr);
- bool hasSeenFirstLegendElement = false;
- for (HTMLElement* control = Traversal<HTMLElement>::firstChild(*this); control; control = Traversal<HTMLElement>::nextSibling(*control)) {
- if (!hasSeenFirstLegendElement && is<HTMLLegendElement>(*control)) {
- hasSeenFirstLegendElement = true;
- updateFromControlElementsAncestorDisabledStateUnder(*control, false /* isDisabled */);
- continue;
- }
- updateFromControlElementsAncestorDisabledStateUnder(*control, thisFieldsetIsDisabled);
- }
+ HTMLFormControlElement::disabledAttributeChanged();
+ invalidateDisabledStateUnder(this);
}
void HTMLFieldSetElement::childrenChanged(const ChildChange& change)
{
HTMLFormControlElement::childrenChanged(change);
- if (!fastHasAttribute(disabledAttr))
- return;
-
- HTMLLegendElement* legend = Traversal<HTMLLegendElement>::firstChild(*this);
- if (!legend)
- return;
- // We only care about the first legend element (in which form contorls are not disabled by this element) changing here.
- updateFromControlElementsAncestorDisabledStateUnder(*legend, false /* isDisabled */);
- while ((legend = Traversal<HTMLLegendElement>::nextSibling(*legend)))
- updateFromControlElementsAncestorDisabledStateUnder(*legend, true);
-}
-
-void HTMLFieldSetElement::didMoveToNewDocument(Document* oldDocument)
-{
- HTMLFormControlElement::didMoveToNewDocument(oldDocument);
- if (fastHasAttribute(disabledAttr)) {
- if (oldDocument)
- oldDocument->removeDisabledFieldsetElement();
- document().addDisabledFieldsetElement();
- }
-}
-
-bool HTMLFieldSetElement::matchesValidPseudoClass() const
-{
- return m_invalidDescendants.isEmpty();
-}
-
-bool HTMLFieldSetElement::matchesInvalidPseudoClass() const
-{
- return !m_invalidDescendants.isEmpty();
+ for (auto& legend : childrenOfType<HTMLLegendElement>(*this))
+ invalidateDisabledStateUnder(&legend);
}
bool HTMLFieldSetElement::supportsFocus() const
@@ -145,21 +77,21 @@ bool HTMLFieldSetElement::supportsFocus() const
const AtomicString& HTMLFieldSetElement::formControlType() const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, fieldset, ("fieldset", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, fieldset, ("fieldset", AtomicString::ConstructFromLiteral));
return fieldset;
}
-RenderPtr<RenderElement> HTMLFieldSetElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLFieldSetElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderFieldset>(*this, WTF::move(style));
+ return createRenderer<RenderFieldset>(*this, std::move(style));
}
HTMLLegendElement* HTMLFieldSetElement::legend() const
{
- return const_cast<HTMLLegendElement*>(childrenOfType<HTMLLegendElement>(*this).first());
+ return const_cast<HTMLLegendElement*>(descendantsOfType<HTMLLegendElement>(*this).first());
}
-Ref<HTMLCollection> HTMLFieldSetElement::elements()
+PassRefPtr<HTMLCollection> HTMLFieldSetElement::elements()
{
return ensureCachedHTMLCollection(FormControls);
}
@@ -176,9 +108,9 @@ void HTMLFieldSetElement::refreshElementsIfNeeded() const
for (auto& element : descendantsOfType<Element>(const_cast<HTMLFieldSetElement&>(*this))) {
if (element.hasTagName(objectTag))
- m_associatedElements.append(&downcast<HTMLObjectElement>(element));
- else if (is<HTMLFormControlElement>(element))
- m_associatedElements.append(&downcast<HTMLFormControlElement>(element));
+ m_associatedElements.append(&toHTMLObjectElement(element));
+ else if (element.isFormControlElement())
+ m_associatedElements.append(&toHTMLFormControlElement(element));
}
}
@@ -199,25 +131,4 @@ unsigned HTMLFieldSetElement::length() const
return length;
}
-void HTMLFieldSetElement::addInvalidDescendant(const HTMLFormControlElement& invalidFormControlElement)
-{
- ASSERT_WITH_MESSAGE(!is<HTMLFieldSetElement>(invalidFormControlElement), "FieldSet are never candidates for constraint validation.");
- ASSERT(static_cast<const Element&>(invalidFormControlElement).matchesInvalidPseudoClass());
- ASSERT_WITH_MESSAGE(!m_invalidDescendants.contains(&invalidFormControlElement), "Updating the fieldset on validity change is not an efficient operation, it should only be done when necessary.");
-
- if (m_invalidDescendants.isEmpty())
- setNeedsStyleRecalc();
- m_invalidDescendants.add(&invalidFormControlElement);
-}
-
-void HTMLFieldSetElement::removeInvalidDescendant(const HTMLFormControlElement& formControlElement)
-{
- ASSERT_WITH_MESSAGE(!is<HTMLFieldSetElement>(formControlElement), "FieldSet are never candidates for constraint validation.");
- ASSERT_WITH_MESSAGE(m_invalidDescendants.contains(&formControlElement), "Updating the fieldset on validity change is not an efficient operation, it should only be done when necessary.");
-
- m_invalidDescendants.remove(&formControlElement);
- if (m_invalidDescendants.isEmpty())
- setNeedsStyleRecalc();
-}
-
} // namespace
diff --git a/Source/WebCore/html/HTMLFieldSetElement.h b/Source/WebCore/html/HTMLFieldSetElement.h
index 0d4e36706..0cf0d0ed2 100644
--- a/Source/WebCore/html/HTMLFieldSetElement.h
+++ b/Source/WebCore/html/HTMLFieldSetElement.h
@@ -25,7 +25,6 @@
#define HTMLFieldSetElement_h
#include "HTMLFormControlElement.h"
-#include <wtf/HashSet.h>
namespace WebCore {
@@ -34,42 +33,38 @@ class HTMLCollection;
class HTMLFieldSetElement final : public HTMLFormControlElement {
public:
- static Ref<HTMLFieldSetElement> create(const QualifiedName&, Document&, HTMLFormElement*);
+ static PassRefPtr<HTMLFieldSetElement> create(const QualifiedName&, Document&, HTMLFormElement*);
HTMLLegendElement* legend() const;
- Ref<HTMLCollection> elements();
+ PassRefPtr<HTMLCollection> elements();
const Vector<FormAssociatedElement*>& associatedElements() const;
unsigned length() const;
- void addInvalidDescendant(const HTMLFormControlElement&);
- void removeInvalidDescendant(const HTMLFormControlElement&);
+protected:
+ virtual void disabledAttributeChanged() override;
private:
HTMLFieldSetElement(const QualifiedName&, Document&, HTMLFormElement*);
- ~HTMLFieldSetElement();
virtual bool isEnumeratable() const override { return true; }
virtual bool supportsFocus() const override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual const AtomicString& formControlType() const override;
- virtual bool computeWillValidate() const override { return false; }
- virtual void disabledAttributeChanged() override;
- virtual void disabledStateChanged() override;
+ virtual bool recalcWillValidate() const override { return false; }
virtual void childrenChanged(const ChildChange&) override;
- virtual void didMoveToNewDocument(Document* oldDocument) override;
-
- virtual bool matchesValidPseudoClass() const override;
- virtual bool matchesInvalidPseudoClass() const override;
+ virtual bool areAuthorShadowsAllowed() const override { return false; }
+ static void invalidateDisabledStateUnder(Element*);
void refreshElementsIfNeeded() const;
mutable Vector<FormAssociatedElement*> m_associatedElements;
// When dom tree is modified, we have to refresh the m_associatedElements array.
mutable uint64_t m_documentVersion;
- HashSet<const HTMLFormControlElement*> m_invalidDescendants;
};
+NODE_TYPE_CASTS(HTMLFieldSetElement)
+
} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLFieldSetElement.idl b/Source/WebCore/html/HTMLFieldSetElement.idl
index 6c5a6114f..4e77da909 100644
--- a/Source/WebCore/html/HTMLFieldSetElement.idl
+++ b/Source/WebCore/html/HTMLFieldSetElement.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
diff --git a/Source/WebCore/html/HTMLFontElement.cpp b/Source/WebCore/html/HTMLFontElement.cpp
index f38f5e9e8..7d27ffd07 100644
--- a/Source/WebCore/html/HTMLFontElement.cpp
+++ b/Source/WebCore/html/HTMLFontElement.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLFontElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "CSSStyleSheet.h"
#include "CSSValueKeywords.h"
@@ -45,9 +46,9 @@ HTMLFontElement::HTMLFontElement(const QualifiedName& tagName, Document& documen
ASSERT(hasTagName(fontTag));
}
-Ref<HTMLFontElement> HTMLFontElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLFontElement> HTMLFontElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLFontElement(tagName, document));
+ return adoptRef(new HTMLFontElement(tagName, document));
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#fonts-and-colors
diff --git a/Source/WebCore/html/HTMLFontElement.h b/Source/WebCore/html/HTMLFontElement.h
index 00df80234..e5c3daa63 100644
--- a/Source/WebCore/html/HTMLFontElement.h
+++ b/Source/WebCore/html/HTMLFontElement.h
@@ -30,7 +30,7 @@ namespace WebCore {
class HTMLFontElement final : public HTMLElement {
public:
- static Ref<HTMLFontElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLFontElement> create(const QualifiedName&, Document&);
static bool cssValueFromFontSizeNumber(const String&, CSSValueID&);
diff --git a/Source/WebCore/html/HTMLFormControlElement.cpp b/Source/WebCore/html/HTMLFormControlElement.cpp
index 6217fbd74..e61022993 100644
--- a/Source/WebCore/html/HTMLFormControlElement.cpp
+++ b/Source/WebCore/html/HTMLFormControlElement.cpp
@@ -25,11 +25,11 @@
#include "config.h"
#include "HTMLFormControlElement.h"
-#include "ControlStates.h"
-#include "ElementAncestorIterator.h"
+#include "Attribute.h"
#include "Event.h"
#include "EventHandler.h"
#include "EventNames.h"
+#include "FeatureObserver.h"
#include "Frame.h"
#include "HTMLFieldSetElement.h"
#include "HTMLFormElement.h"
@@ -52,7 +52,7 @@ HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Doc
, m_isReadOnly(false)
, m_isRequired(false)
, m_valueMatchesRenderer(false)
- , m_disabledByAncestorFieldset(false)
+ , m_ancestorDisabledState(AncestorDisabledStateUnknown)
, m_dataListAncestorState(Unknown)
, m_willValidateInitialized(false)
, m_willValidate(true)
@@ -60,15 +60,12 @@ HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Doc
, m_wasChangedSinceLastFormControlChangeEvent(false)
, m_hasAutofocused(false)
{
- setForm(form);
+ setForm(form ? form : HTMLFormElement::findClosestFormAncestor(*this));
setHasCustomStyleResolveCallbacks();
}
HTMLFormControlElement::~HTMLFormControlElement()
{
- // The calls willChangeForm() and didChangeForm() are virtual, we want the
- // form to be reset while this object still exists.
- setForm(nullptr);
}
String HTMLFormControlElement::formEnctype() const
@@ -102,34 +99,33 @@ bool HTMLFormControlElement::formNoValidate() const
return fastHasAttribute(formnovalidateAttr);
}
-bool HTMLFormControlElement::computeIsDisabledByFieldsetAncestor() const
+void HTMLFormControlElement::updateAncestorDisabledState() const
{
- Element* previousAncestor = nullptr;
- for (Element* ancestor = parentElement(); ancestor; ancestor = ancestor->parentElement()) {
- if (is<HTMLFieldSetElement>(*ancestor) && ancestor->fastHasAttribute(disabledAttr)) {
- HTMLFieldSetElement& fieldSetAncestor = downcast<HTMLFieldSetElement>(*ancestor);
- bool isInFirstLegend = is<HTMLLegendElement>(previousAncestor) && previousAncestor == fieldSetAncestor.legend();
- return !isInFirstLegend;
+ HTMLFieldSetElement* fieldSetAncestor = 0;
+ ContainerNode* legendAncestor = 0;
+ for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
+ if (!legendAncestor && ancestor->hasTagName(legendTag))
+ legendAncestor = ancestor;
+ if (ancestor->hasTagName(fieldsetTag)) {
+ fieldSetAncestor = toHTMLFieldSetElement(ancestor);
+ break;
}
- previousAncestor = ancestor;
}
- return false;
+ m_ancestorDisabledState = (fieldSetAncestor && fieldSetAncestor->isDisabledFormControl() && !(legendAncestor && legendAncestor == fieldSetAncestor->legend())) ? AncestorDisabledStateDisabled : AncestorDisabledStateEnabled;
}
-void HTMLFormControlElement::setAncestorDisabled(bool isDisabled)
+void HTMLFormControlElement::ancestorDisabledStateWasChanged()
{
- ASSERT(computeIsDisabledByFieldsetAncestor() == isDisabled);
- bool oldValue = m_disabledByAncestorFieldset;
- m_disabledByAncestorFieldset = isDisabled;
- if (oldValue != m_disabledByAncestorFieldset)
- disabledStateChanged();
+ m_ancestorDisabledState = AncestorDisabledStateUnknown;
+ disabledAttributeChanged();
}
void HTMLFormControlElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- if (name == formAttr)
+ if (name == formAttr) {
formAttributeChanged();
- else if (name == disabledAttr) {
+ FeatureObserver::observe(&document(), FeatureObserver::FormAttribute);
+ } else if (name == disabledAttr) {
bool oldDisabled = m_disabled;
m_disabled = !value.isNull();
if (oldDisabled != m_disabled)
@@ -137,39 +133,36 @@ void HTMLFormControlElement::parseAttribute(const QualifiedName& name, const Ato
} else if (name == readonlyAttr) {
bool wasReadOnly = m_isReadOnly;
m_isReadOnly = !value.isNull();
- if (wasReadOnly != m_isReadOnly)
- readOnlyAttributeChanged();
+ if (wasReadOnly != m_isReadOnly) {
+ setNeedsWillValidateCheck();
+ setNeedsStyleRecalc();
+ if (renderer() && renderer()->style().hasAppearance())
+ renderer()->theme().stateChanged(renderer(), ReadOnlyState);
+ }
} else if (name == requiredAttr) {
bool wasRequired = m_isRequired;
m_isRequired = !value.isNull();
if (wasRequired != m_isRequired)
requiredAttributeChanged();
+ FeatureObserver::observe(&document(), FeatureObserver::RequiredAttribute);
+ } else if (name == autofocusAttr) {
+ HTMLElement::parseAttribute(name, value);
+ FeatureObserver::observe(&document(), FeatureObserver::AutoFocusAttribute);
} else
HTMLElement::parseAttribute(name, value);
}
void HTMLFormControlElement::disabledAttributeChanged()
{
- disabledStateChanged();
-}
-
-void HTMLFormControlElement::disabledStateChanged()
-{
setNeedsWillValidateCheck();
- setNeedsStyleRecalc();
+ didAffectSelector(AffectedSelectorDisabled | AffectedSelectorEnabled);
if (renderer() && renderer()->style().hasAppearance())
- renderer()->theme().stateChanged(*renderer(), ControlStates::EnabledState);
-}
-
-void HTMLFormControlElement::readOnlyAttributeChanged()
-{
- setNeedsWillValidateCheck();
- setNeedsStyleRecalc();
+ renderer()->theme().stateChanged(renderer(), EnabledState);
}
void HTMLFormControlElement::requiredAttributeChanged()
{
- updateValidity();
+ setNeedsValidityCheck();
// Style recalculation is needed because style selectors may include
// :required and :optional pseudo-classes.
setNeedsStyleRecalc();
@@ -183,9 +176,11 @@ static bool shouldAutofocus(HTMLFormControlElement* element)
return false;
if (!element->inDocument() || !element->document().renderView())
return false;
+ if (element->document().ignoreAutofocus())
+ return false;
if (element->document().isSandboxed(SandboxAutomaticFeatures)) {
// FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
- element->document().addConsoleMessage(MessageSource::Security, MessageLevel::Error, ASCIILiteral("Blocked autofocusing on a form control because the form's frame is sandboxed and the 'allow-scripts' permission is not set."));
+ element->document().addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked autofocusing on a form control because the form's frame is sandboxed and the 'allow-scripts' permission is not set.");
return false;
}
if (element->hasAutofocused())
@@ -193,20 +188,26 @@ static bool shouldAutofocus(HTMLFormControlElement* element)
// FIXME: Should this set of hasTagName checks be replaced by a
// virtual member function?
- if (is<HTMLInputElement>(*element))
- return !downcast<HTMLInputElement>(*element).isInputTypeHidden();
+ if (isHTMLInputElement(element))
+ return !toHTMLInputElement(element)->isInputTypeHidden();
if (element->hasTagName(selectTag))
return true;
if (element->hasTagName(keygenTag))
return true;
if (element->hasTagName(buttonTag))
return true;
- if (is<HTMLTextAreaElement>(*element))
+ if (isHTMLTextAreaElement(element))
return true;
return false;
}
+static void focusPostAttach(Node& element, unsigned)
+{
+ toElement(element).focus();
+ element.deref();
+}
+
void HTMLFormControlElement::didAttachRenderers()
{
// The call to updateFromElement() needs to go after the call through
@@ -217,11 +218,8 @@ void HTMLFormControlElement::didAttachRenderers()
if (shouldAutofocus(this)) {
setAutofocused();
-
- RefPtr<HTMLFormControlElement> element = this;
- Style::queuePostResolutionCallback([element] {
- element->focus();
- });
+ ref();
+ queuePostAttachCallback(focusPostAttach, *this);
}
}
@@ -231,56 +229,23 @@ void HTMLFormControlElement::didMoveToNewDocument(Document* oldDocument)
HTMLElement::didMoveToNewDocument(oldDocument);
}
-static void addInvalidElementToAncestorFromInsertionPoint(const HTMLFormControlElement& element, ContainerNode* insertionPoint)
-{
- if (!is<Element>(insertionPoint))
- return;
-
- for (auto& ancestor : lineageOfType<HTMLFieldSetElement>(downcast<Element>(*insertionPoint)))
- ancestor.addInvalidDescendant(element);
-}
-
-static void removeInvalidElementToAncestorFromInsertionPoint(const HTMLFormControlElement& element, ContainerNode* insertionPoint)
-{
- if (!is<Element>(insertionPoint))
- return;
-
- for (auto& ancestor : lineageOfType<HTMLFieldSetElement>(downcast<Element>(*insertionPoint)))
- ancestor.removeInvalidDescendant(element);
-}
-
Node::InsertionNotificationRequest HTMLFormControlElement::insertedInto(ContainerNode& insertionPoint)
{
- if (willValidate() && !isValidFormControlElement())
- addInvalidElementToAncestorFromInsertionPoint(*this, &insertionPoint);
-
- if (document().hasDisabledFieldsetElement())
- setAncestorDisabled(computeIsDisabledByFieldsetAncestor());
+ m_ancestorDisabledState = AncestorDisabledStateUnknown;
m_dataListAncestorState = Unknown;
setNeedsWillValidateCheck();
HTMLElement::insertedInto(insertionPoint);
FormAssociatedElement::insertedInto(insertionPoint);
- return InsertionShouldCallFinishedInsertingSubtree;
-}
-
-void HTMLFormControlElement::finishedInsertingSubtree()
-{
- resetFormOwner();
+ return InsertionDone;
}
void HTMLFormControlElement::removedFrom(ContainerNode& insertionPoint)
{
- bool wasMatchingInvalidPseudoClass = willValidate() && !isValidFormControlElement();
-
m_validationMessage = nullptr;
- if (m_disabledByAncestorFieldset)
- setAncestorDisabled(computeIsDisabledByFieldsetAncestor());
+ m_ancestorDisabledState = AncestorDisabledStateUnknown;
m_dataListAncestorState = Unknown;
HTMLElement::removedFrom(insertionPoint);
FormAssociatedElement::removedFrom(insertionPoint);
-
- if (wasMatchingInvalidPseudoClass)
- removeInvalidElementToAncestorFromInsertionPoint(*this, &insertionPoint);
}
void HTMLFormControlElement::setChangedSinceLastFormControlChangeEvent(bool changed)
@@ -307,7 +272,14 @@ void HTMLFormControlElement::dispatchFormControlInputEvent()
bool HTMLFormControlElement::isDisabledFormControl() const
{
- return m_disabled || m_disabledByAncestorFieldset;
+ if (m_disabled)
+ return true;
+
+ if (m_ancestorDisabledState == AncestorDisabledStateUnknown)
+ updateAncestorDisabledState();
+ if (m_ancestorDisabledState == AncestorDisabledStateDisabled)
+ return true;
+ return HTMLElement::isDisabledFormControl();
}
bool HTMLFormControlElement::isRequired() const
@@ -315,17 +287,18 @@ bool HTMLFormControlElement::isRequired() const
return m_isRequired;
}
+static void updateFromElementCallback(Node& node, unsigned)
+{
+ if (auto renderer = toHTMLFormControlElement(node).renderer())
+ renderer->updateFromElement();
+}
+
void HTMLFormControlElement::didRecalcStyle(Style::Change)
{
// updateFromElement() can cause the selection to change, and in turn
// trigger synchronous layout, so it must not be called during style recalc.
- if (renderer()) {
- RefPtr<HTMLFormControlElement> element = this;
- Style::queuePostResolutionCallback([element]{
- if (auto* renderer = element->renderer())
- renderer->updateFromElement();
- });
- }
+ if (renderer())
+ queuePostAttachCallback(updateFromElementCallback, *this);
}
bool HTMLFormControlElement::supportsFocus() const
@@ -337,7 +310,7 @@ bool HTMLFormControlElement::isFocusable() const
{
// If there's a renderer, make sure the size isn't empty, but if there's no renderer,
// it might still be focusable if it's in a canvas subtree (handled in Node::isFocusable).
- if (renderer() && (!is<RenderBox>(*renderer()) || downcast<RenderBox>(*renderer()).size().isEmpty()))
+ if (renderer() && (!renderer()->isBox() || toRenderBox(renderer())->size().isEmpty()))
return false;
// HTMLElement::isFocusable handles visibility and calls suportsFocus which
// will cover the disabled case.
@@ -361,23 +334,13 @@ bool HTMLFormControlElement::isMouseFocusable() const
#endif
}
-bool HTMLFormControlElement::matchesValidPseudoClass() const
-{
- return willValidate() && isValidFormControlElement();
-}
-
-bool HTMLFormControlElement::matchesInvalidPseudoClass() const
-{
- return willValidate() && !isValidFormControlElement();
-}
-
short HTMLFormControlElement::tabIndex() const
{
// Skip the supportsFocus check in HTMLElement.
return Element::tabIndex();
}
-bool HTMLFormControlElement::computeWillValidate() const
+bool HTMLFormControlElement::recalcWillValidate() const
{
if (m_dataListAncestorState == Unknown) {
for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
@@ -396,14 +359,16 @@ bool HTMLFormControlElement::willValidate() const
{
if (!m_willValidateInitialized || m_dataListAncestorState == Unknown) {
m_willValidateInitialized = true;
- bool newWillValidate = computeWillValidate();
- if (m_willValidate != newWillValidate)
+ bool newWillValidate = recalcWillValidate();
+ if (m_willValidate != newWillValidate) {
m_willValidate = newWillValidate;
+ const_cast<HTMLFormControlElement*>(this)->setNeedsValidityCheck();
+ }
} else {
// If the following assertion fails, setNeedsWillValidateCheck() is not
- // called correctly when something which changes computeWillValidate() result
+ // called correctly when something which changes recalcWillValidate() result
// is updated.
- ASSERT(m_willValidate == computeWillValidate());
+ ASSERT(m_willValidate == recalcWillValidate());
}
return m_willValidate;
}
@@ -411,24 +376,13 @@ bool HTMLFormControlElement::willValidate() const
void HTMLFormControlElement::setNeedsWillValidateCheck()
{
// We need to recalculate willValidate immediately because willValidate change can causes style change.
- bool newWillValidate = computeWillValidate();
+ bool newWillValidate = recalcWillValidate();
if (m_willValidateInitialized && m_willValidate == newWillValidate)
return;
-
- bool wasValid = m_isValid;
-
m_willValidateInitialized = true;
m_willValidate = newWillValidate;
-
- updateValidity();
+ setNeedsValidityCheck();
setNeedsStyleRecalc();
-
- if (!m_willValidate && !wasValid) {
- removeInvalidElementToAncestorFromInsertionPoint(*this, parentNode());
- if (HTMLFormElement* form = this->form())
- form->removeInvalidAssociatedFormControlIfNeeded(*this);
- }
-
if (!m_willValidate)
hideVisibleValidationMessage();
}
@@ -442,7 +396,7 @@ void HTMLFormControlElement::updateVisibleValidationMessage()
if (renderer() && willValidate())
message = validationMessage().stripWhiteSpace();
if (!m_validationMessage)
- m_validationMessage = std::make_unique<ValidationMessage>(this);
+ m_validationMessage = ValidationMessage::create(this);
m_validationMessage->updateValidationMessage(message);
}
@@ -460,56 +414,27 @@ bool HTMLFormControlElement::checkValidity(Vector<RefPtr<FormAssociatedElement>>
Ref<HTMLFormControlElement> protect(*this);
Ref<Document> originalDocument(document());
bool needsDefaultAction = dispatchEvent(Event::create(eventNames().invalidEvent, false, true));
- if (needsDefaultAction && unhandledInvalidControls && inDocument() && originalDocument.ptr() == &document())
+ if (needsDefaultAction && unhandledInvalidControls && inDocument() && &originalDocument.get() == &document())
unhandledInvalidControls->append(this);
return false;
}
-inline bool HTMLFormControlElement::isValidFormControlElement() const
+bool HTMLFormControlElement::isValidFormControlElement()
{
- // If the following assertion fails, updateValidity() is not called
+ // If the following assertion fails, setNeedsValidityCheck() is not called
// correctly when something which changes validity is updated.
ASSERT(m_isValid == valid());
return m_isValid;
}
-void HTMLFormControlElement::willChangeForm()
-{
- if (HTMLFormElement* form = this->form())
- form->removeInvalidAssociatedFormControlIfNeeded(*this);
- FormAssociatedElement::willChangeForm();
-}
-
-void HTMLFormControlElement::didChangeForm()
+void HTMLFormControlElement::setNeedsValidityCheck()
{
- FormAssociatedElement::didChangeForm();
- if (HTMLFormElement* form = this->form()) {
- if (m_willValidateInitialized && m_willValidate && !isValidFormControlElement())
- form->registerInvalidAssociatedFormControl(*this);
- }
-}
-
-void HTMLFormControlElement::updateValidity()
-{
- bool willValidate = this->willValidate();
- bool wasValid = m_isValid;
-
- m_isValid = valid();
-
- if (willValidate && m_isValid != wasValid) {
+ bool newIsValid = valid();
+ if (willValidate() && newIsValid != m_isValid) {
// Update style for pseudo classes such as :valid :invalid.
setNeedsStyleRecalc();
-
- if (!m_isValid) {
- addInvalidElementToAncestorFromInsertionPoint(*this, parentNode());
- if (HTMLFormElement* form = this->form())
- form->registerInvalidAssociatedFormControl(*this);
- } else {
- removeInvalidElementToAncestorFromInsertionPoint(*this, parentNode());
- if (HTMLFormElement* form = this->form())
- form->removeInvalidAssociatedFormControlIfNeeded(*this);
- }
}
+ m_isValid = newIsValid;
// Updates only if this control already has a validtion message.
if (m_validationMessage && m_validationMessage->isVisible()) {
@@ -522,7 +447,7 @@ void HTMLFormControlElement::updateValidity()
void HTMLFormControlElement::setCustomValidity(const String& error)
{
FormAssociatedElement::setCustomValidity(error);
- updateValidity();
+ setNeedsValidityCheck();
}
bool HTMLFormControlElement::validationMessageShadowTreeContains(const Node& node) const
@@ -530,9 +455,9 @@ bool HTMLFormControlElement::validationMessageShadowTreeContains(const Node& nod
return m_validationMessage && m_validationMessage->shadowTreeContains(node);
}
-void HTMLFormControlElement::dispatchBlurEvent(RefPtr<Element>&& newFocusedElement)
+void HTMLFormControlElement::dispatchBlurEvent(PassRefPtr<Element> newFocusedElement)
{
- HTMLElement::dispatchBlurEvent(WTF::move(newFocusedElement));
+ HTMLElement::dispatchBlurEvent(newFocusedElement);
hideVisibleValidationMessage();
}
@@ -588,10 +513,10 @@ void HTMLFormControlElement::setAutocapitalize(const AtomicString& value)
HTMLFormControlElement* HTMLFormControlElement::enclosingFormControlElement(Node* node)
{
for (; node; node = node->parentNode()) {
- if (is<HTMLFormControlElement>(*node))
- return downcast<HTMLFormControlElement>(node);
+ if (node->isElementNode() && toElement(node)->isFormControlElement())
+ return toHTMLFormControlElement(node);
}
- return nullptr;
+ return 0;
}
} // namespace Webcore
diff --git a/Source/WebCore/html/HTMLFormControlElement.h b/Source/WebCore/html/HTMLFormControlElement.h
index 3e6054ead..98398f005 100644
--- a/Source/WebCore/html/HTMLFormControlElement.h
+++ b/Source/WebCore/html/HTMLFormControlElement.h
@@ -54,12 +54,12 @@ public:
void setFormMethod(const String&);
bool formNoValidate() const;
- void setAncestorDisabled(bool isDisabled);
+ void ancestorDisabledStateWasChanged();
virtual void reset() { }
- bool formControlValueMatchesRenderer() const { return m_valueMatchesRenderer; }
- void setFormControlValueMatchesRenderer(bool b) { m_valueMatchesRenderer = b; }
+ virtual bool formControlValueMatchesRenderer() const { return m_valueMatchesRenderer; }
+ virtual void setFormControlValueMatchesRenderer(bool b) { m_valueMatchesRenderer = b; }
bool wasChangedSinceLastFormControlChangeEvent() const { return m_wasChangedSinceLastFormControlChangeEvent; }
void setChangedSinceLastFormControlChangeEvent(bool);
@@ -90,20 +90,20 @@ public:
virtual void setActivatedSubmit(bool) { }
#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
- WEBCORE_EXPORT bool autocorrect() const;
+ bool autocorrect() const;
void setAutocorrect(bool);
- WEBCORE_EXPORT WebAutocapitalizeType autocapitalizeType() const;
+ WebAutocapitalizeType autocapitalizeType() const;
const AtomicString& autocapitalize() const;
void setAutocapitalize(const AtomicString&);
#endif
- virtual bool willValidate() const override final;
+ virtual bool willValidate() const override;
void updateVisibleValidationMessage();
void hideVisibleValidationMessage();
bool checkValidity(Vector<RefPtr<FormAssociatedElement>>* unhandledInvalidControls = 0);
// This must be called when a validation constraint or control value is changed.
- void updateValidity();
+ void setNeedsValidityCheck();
virtual void setCustomValidity(const String&) override;
bool isReadOnly() const { return m_isReadOnly; }
@@ -120,16 +120,11 @@ public:
protected:
HTMLFormControlElement(const QualifiedName& tagName, Document&, HTMLFormElement*);
- bool disabledByAncestorFieldset() const { return m_disabledByAncestorFieldset; }
-
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
- virtual void disabledAttributeChanged();
- virtual void disabledStateChanged();
- virtual void readOnlyAttributeChanged();
virtual void requiredAttributeChanged();
+ virtual void disabledAttributeChanged();
virtual void didAttachRenderers() override;
virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
- void finishedInsertingSubtree() override;
virtual void removedFrom(ContainerNode&) override;
virtual void didMoveToNewDocument(Document* oldDocument) override;
@@ -139,46 +134,40 @@ protected:
virtual void didRecalcStyle(Style::Change) override;
- virtual void dispatchBlurEvent(RefPtr<Element>&& newFocusedElement) override;
+ virtual void dispatchBlurEvent(PassRefPtr<Element> newFocusedElement) override;
// This must be called any time the result of willValidate() has changed.
void setNeedsWillValidateCheck();
- virtual bool computeWillValidate() const;
+ virtual bool recalcWillValidate() const;
bool validationMessageShadowTreeContains(const Node&) const;
- virtual void willChangeForm() override;
- virtual void didChangeForm() override;
-
private:
virtual void refFormAssociatedElement() override { ref(); }
virtual void derefFormAssociatedElement() override { deref(); }
- virtual bool matchesValidPseudoClass() const override;
- virtual bool matchesInvalidPseudoClass() const override;
-
- virtual bool isFormControlElement() const override final { return true; }
+ virtual bool isFormControlElement() const override { return true; }
virtual bool alwaysCreateUserAgentShadowRoot() const override { return true; }
virtual short tabIndex() const override final;
virtual HTMLFormElement* virtualForm() const override;
virtual bool isDefaultButtonForForm() const override;
- bool isValidFormControlElement() const;
-
- bool computeIsDisabledByFieldsetAncestor() const;
+ virtual bool isValidFormControlElement() override;
+ void updateAncestorDisabledState() const;
virtual HTMLElement& asHTMLElement() override final { return *this; }
virtual const HTMLFormControlElement& asHTMLElement() const override final { return *this; }
virtual HTMLFormControlElement* asFormNamedItem() override final { return this; }
- std::unique_ptr<ValidationMessage> m_validationMessage;
+ OwnPtr<ValidationMessage> m_validationMessage;
bool m_disabled : 1;
bool m_isReadOnly : 1;
bool m_isRequired : 1;
bool m_valueMatchesRenderer : 1;
- bool m_disabledByAncestorFieldset : 1;
+ enum AncestorDisabledState { AncestorDisabledStateUnknown, AncestorDisabledStateEnabled, AncestorDisabledStateDisabled };
+ mutable AncestorDisabledState m_ancestorDisabledState;
enum DataListAncestorState { Unknown, InsideDataList, NotInsideDataList };
mutable enum DataListAncestorState m_dataListAncestorState;
@@ -197,12 +186,15 @@ private:
bool m_hasAutofocused : 1;
};
-} // namespace WebCore
+void isHTMLFormControlElement(const HTMLFormControlElement&); // Catch unnecessary runtime check of type known at compile time.
+inline bool isHTMLFormControlElement(const Element& element) { return element.isFormControlElement(); }
+inline bool isHTMLFormControlElement(const Node& node) { return node.isElementNode() && toElement(node).isFormControlElement(); }
+template <> inline bool isElementOfType<const HTMLFormControlElement>(const Element& element) { return isHTMLFormControlElement(element); }
+
+NODE_TYPE_CASTS(HTMLFormControlElement)
+
+FORM_ASSOCIATED_ELEMENT_TYPE_CASTS(HTMLFormControlElement, isFormControlElement())
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLFormControlElement)
- static bool isType(const WebCore::Element& element) { return element.isFormControlElement(); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); }
- static bool isType(const WebCore::FormAssociatedElement& element) { return element.isFormControlElement(); }
-SPECIALIZE_TYPE_TRAITS_END()
+} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLFormControlElementWithState.cpp b/Source/WebCore/html/HTMLFormControlElementWithState.cpp
index 57b238ec5..d16577f0a 100644
--- a/Source/WebCore/html/HTMLFormControlElementWithState.cpp
+++ b/Source/WebCore/html/HTMLFormControlElementWithState.cpp
@@ -64,6 +64,16 @@ bool HTMLFormControlElementWithState::shouldAutocomplete() const
return form()->shouldAutocomplete();
}
+void HTMLFormControlElementWithState::notifyFormStateChanged()
+{
+ Frame* frame = document().frame();
+ if (!frame)
+ return;
+
+ if (Page* page = frame->page())
+ page->chrome().client().formStateDidChange(this);
+}
+
bool HTMLFormControlElementWithState::shouldSaveAndRestoreFormControlState() const
{
// We don't save/restore control state in a form with autocomplete=off.
diff --git a/Source/WebCore/html/HTMLFormControlElementWithState.h b/Source/WebCore/html/HTMLFormControlElementWithState.h
index 323caddcb..99f04e053 100644
--- a/Source/WebCore/html/HTMLFormControlElementWithState.h
+++ b/Source/WebCore/html/HTMLFormControlElementWithState.h
@@ -40,6 +40,7 @@ public:
virtual FormControlState saveFormControlState() const;
// The specified FormControlState must have at least one string value.
virtual void restoreFormControlState(const FormControlState&) { }
+ void notifyFormStateChanged();
protected:
HTMLFormControlElementWithState(const QualifiedName& tagName, Document&, HTMLFormElement*);
diff --git a/Source/WebCore/html/HTMLFormControlsCollection.cpp b/Source/WebCore/html/HTMLFormControlsCollection.cpp
index 0deecc24e..54587306c 100644
--- a/Source/WebCore/html/HTMLFormControlsCollection.cpp
+++ b/Source/WebCore/html/HTMLFormControlsCollection.cpp
@@ -40,12 +40,12 @@ HTMLFormControlsCollection::HTMLFormControlsCollection(ContainerNode& ownerNode)
, m_cachedElement(nullptr)
, m_cachedElementOffsetInArray(0)
{
- ASSERT(is<HTMLFormElement>(ownerNode) || is<HTMLFieldSetElement>(ownerNode));
+ ASSERT(isHTMLFormElement(ownerNode) || isHTMLFieldSetElement(ownerNode));
}
-Ref<HTMLFormControlsCollection> HTMLFormControlsCollection::create(ContainerNode& ownerNode, CollectionType)
+PassRefPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(ContainerNode& ownerNode, CollectionType)
{
- return adoptRef(*new HTMLFormControlsCollection(ownerNode));
+ return adoptRef(new HTMLFormControlsCollection(ownerNode));
}
HTMLFormControlsCollection::~HTMLFormControlsCollection()
@@ -54,16 +54,16 @@ HTMLFormControlsCollection::~HTMLFormControlsCollection()
const Vector<FormAssociatedElement*>& HTMLFormControlsCollection::formControlElements() const
{
- ASSERT(is<HTMLFormElement>(ownerNode()) || is<HTMLFieldSetElement>(ownerNode()));
- if (is<HTMLFormElement>(ownerNode()))
- return downcast<HTMLFormElement>(ownerNode()).associatedElements();
- return downcast<HTMLFieldSetElement>(ownerNode()).associatedElements();
+ ASSERT(isHTMLFormElement(ownerNode()) || ownerNode().hasTagName(fieldsetTag));
+ if (isHTMLFormElement(ownerNode()))
+ return toHTMLFormElement(ownerNode()).associatedElements();
+ return toHTMLFieldSetElement(ownerNode()).associatedElements();
}
const Vector<HTMLImageElement*>& HTMLFormControlsCollection::formImageElements() const
{
- ASSERT(is<HTMLFormElement>(ownerNode()));
- return downcast<HTMLFormElement>(ownerNode()).imageElements();
+ ASSERT(isHTMLFormElement(ownerNode()));
+ return toHTMLFormElement(ownerNode()).imageElements();
}
static unsigned findFormAssociatedElement(const Vector<FormAssociatedElement*>& elements, const Element& element)
@@ -121,65 +121,65 @@ static HTMLElement* firstNamedItem(const Vector<FormAssociatedElement*>& element
return nullptr;
}
-HTMLElement* HTMLFormControlsCollection::namedItem(const AtomicString& name) const
+Node* HTMLFormControlsCollection::namedItem(const AtomicString& name) const
{
// http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp
// This method first searches for an object with a matching id
// attribute. If a match is not found, the method then searches for an
// object with a matching name attribute, but only on those elements
// that are allowed a name attribute.
- auto* imageElements = is<HTMLFieldSetElement>(ownerNode()) ? nullptr : &formImageElements();
- if (HTMLElement* item = firstNamedItem(formControlElements(), imageElements, idAttr, name))
+ const Vector<HTMLImageElement*>* imagesElements = ownerNode().hasTagName(fieldsetTag) ? nullptr : &formImageElements();
+ if (HTMLElement* item = firstNamedItem(formControlElements(), imagesElements, idAttr, name))
return item;
- return firstNamedItem(formControlElements(), imageElements, nameAttr, name);
+
+ return firstNamedItem(formControlElements(), imagesElements, nameAttr, name);
}
-void HTMLFormControlsCollection::updateNamedElementCache() const
+void HTMLFormControlsCollection::updateNameCache() const
{
- if (hasNamedElementCache())
+ if (hasNameCache())
return;
- auto cache = std::make_unique<CollectionNamedElementCache>();
-
- bool ownerIsFormElement = is<HTMLFormElement>(ownerNode());
HashSet<AtomicStringImpl*> foundInputElements;
- for (auto& elementPtr : formControlElements()) {
- FormAssociatedElement& associatedElement = *elementPtr;
+ const Vector<FormAssociatedElement*>& elementsArray = formControlElements();
+
+ for (unsigned i = 0; i < elementsArray.size(); ++i) {
+ FormAssociatedElement& associatedElement = *elementsArray[i];
if (associatedElement.isEnumeratable()) {
HTMLElement& element = associatedElement.asHTMLElement();
- const AtomicString& id = element.getIdAttribute();
- if (!id.isEmpty()) {
- cache->appendToIdCache(id, element);
- if (ownerIsFormElement)
- foundInputElements.add(id.impl());
+ const AtomicString& idAttrVal = element.getIdAttribute();
+ const AtomicString& nameAttrVal = element.getNameAttribute();
+ if (!idAttrVal.isEmpty()) {
+ appendIdCache(idAttrVal, &element);
+ foundInputElements.add(idAttrVal.impl());
}
- const AtomicString& name = element.getNameAttribute();
- if (!name.isEmpty() && id != name) {
- cache->appendToNameCache(name, element);
- if (ownerIsFormElement)
- foundInputElements.add(name.impl());
+ if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal) {
+ appendNameCache(nameAttrVal, &element);
+ foundInputElements.add(nameAttrVal.impl());
}
}
}
- if (ownerIsFormElement) {
- for (auto* elementPtr : formImageElements()) {
- HTMLImageElement& element = *elementPtr;
- const AtomicString& id = element.getIdAttribute();
- if (!id.isEmpty() && !foundInputElements.contains(id.impl()))
- cache->appendToIdCache(id, element);
- const AtomicString& name = element.getNameAttribute();
- if (!name.isEmpty() && id != name && !foundInputElements.contains(name.impl()))
- cache->appendToNameCache(name, element);
+
+ if (isHTMLFormElement(ownerNode())) {
+ const Vector<HTMLImageElement*>& imageElementsArray = formImageElements();
+ for (unsigned i = 0; i < imageElementsArray.size(); ++i) {
+ HTMLImageElement& element = *imageElementsArray[i];
+ const AtomicString& idAttrVal = element.getIdAttribute();
+ const AtomicString& nameAttrVal = element.getNameAttribute();
+ if (!idAttrVal.isEmpty() && !foundInputElements.contains(idAttrVal.impl()))
+ appendIdCache(idAttrVal, &element);
+ if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && !foundInputElements.contains(nameAttrVal.impl()))
+ appendNameCache(nameAttrVal, &element);
}
}
- setNamedItemCache(WTF::move(cache));
+ setHasNameCache();
}
-void HTMLFormControlsCollection::invalidateCache(Document& document) const
+void HTMLFormControlsCollection::invalidateCache() const
{
- HTMLCollection::invalidateCache(document);
+ HTMLCollection::invalidateCache();
m_cachedElement = nullptr;
m_cachedElementOffsetInArray = 0;
}
diff --git a/Source/WebCore/html/HTMLFormControlsCollection.h b/Source/WebCore/html/HTMLFormControlsCollection.h
index b168ad9c0..a4cfd2d18 100644
--- a/Source/WebCore/html/HTMLFormControlsCollection.h
+++ b/Source/WebCore/html/HTMLFormControlsCollection.h
@@ -24,27 +24,30 @@
#define HTMLFormControlsCollection_h
#include "HTMLCollection.h"
-#include "HTMLElement.h"
namespace WebCore {
class FormAssociatedElement;
+class HTMLElement;
class HTMLImageElement;
+class QualifiedName;
// This class is just a big hack to find form elements even in malformed HTML elements.
// The famous <table><tr><form><td> problem.
-class HTMLFormControlsCollection final : public HTMLCollection {
+class HTMLFormControlsCollection : public HTMLCollection {
public:
- static Ref<HTMLFormControlsCollection> create(ContainerNode&, CollectionType);
+ static PassRefPtr<HTMLFormControlsCollection> create(ContainerNode&, CollectionType);
+
virtual ~HTMLFormControlsCollection();
+ virtual Node* namedItem(const AtomicString& name) const override;
+
private:
explicit HTMLFormControlsCollection(ContainerNode&);
- virtual HTMLElement* namedItem(const AtomicString& name) const override;
- virtual void invalidateCache(Document&) const override;
- virtual void updateNamedElementCache() const override;
+ virtual void invalidateCache() const override;
+ virtual void updateNameCache() const override;
const Vector<FormAssociatedElement*>& formControlElements() const;
const Vector<HTMLImageElement*>& formImageElements() const;
@@ -54,8 +57,6 @@ private:
mutable unsigned m_cachedElementOffsetInArray;
};
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_HTMLCOLLECTION(HTMLFormControlsCollection, FormControls)
+} // namespace
-#endif // HTMLFormControlsCollection_h
+#endif
diff --git a/Source/WebCore/html/HTMLFormElement.cpp b/Source/WebCore/html/HTMLFormElement.cpp
index 5ffa3a8a7..0c301ebe1 100644
--- a/Source/WebCore/html/HTMLFormElement.cpp
+++ b/Source/WebCore/html/HTMLFormElement.cpp
@@ -25,9 +25,7 @@
#include "config.h"
#include "HTMLFormElement.h"
-#include "AutocompleteErrorEvent.h"
-#include "DOMFormData.h"
-#include "DOMWindow.h"
+#include "Attribute.h"
#include "Document.h"
#include "ElementIterator.h"
#include "Event.h"
@@ -62,21 +60,18 @@ HTMLFormElement::HTMLFormElement(const QualifiedName& tagName, Document& documen
, m_shouldSubmit(false)
, m_isInResetFunction(false)
, m_wasDemoted(false)
-#if ENABLE(REQUEST_AUTOCOMPLETE)
- , m_requestAutocompletetimer(*this, &HTMLFormElement::requestAutocompleteTimerFired)
-#endif
{
ASSERT(hasTagName(formTag));
}
-Ref<HTMLFormElement> HTMLFormElement::create(Document& document)
+PassRefPtr<HTMLFormElement> HTMLFormElement::create(Document& document)
{
- return adoptRef(*new HTMLFormElement(formTag, document));
+ return adoptRef(new HTMLFormElement(formTag, document));
}
-Ref<HTMLFormElement> HTMLFormElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLFormElement> HTMLFormElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLFormElement(tagName, document));
+ return adoptRef(new HTMLFormElement(tagName, document));
}
HTMLFormElement::~HTMLFormElement()
@@ -108,7 +103,7 @@ bool HTMLFormElement::rendererIsNeeded(const RenderStyle& style)
return false;
// FIXME: Shouldn't we also check for table caption (see |formIsTablePart| below).
- bool parentIsTableElementPart = (parentRenderer->isTable() && is<HTMLTableElement>(*parent))
+ bool parentIsTableElementPart = (parentRenderer->isTable() && isHTMLTableElement(parent))
|| (parentRenderer->isTableRow() && parent->hasTagName(trTag))
|| (parentRenderer->isTableSection() && parent->hasTagName(tbodyTag))
|| (parentRenderer->isRenderTableCol() && parent->hasTagName(colTag))
@@ -180,15 +175,15 @@ void HTMLFormElement::submitImplicitly(Event* event, bool fromImplicitSubmission
unsigned submissionTriggerCount = 0;
for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
FormAssociatedElement* formAssociatedElement = m_associatedElements[i];
- if (!is<HTMLFormControlElement>(*formAssociatedElement))
+ if (!formAssociatedElement->isFormControlElement())
continue;
- HTMLFormControlElement& formElement = downcast<HTMLFormControlElement>(*formAssociatedElement);
- if (formElement.isSuccessfulSubmitButton()) {
- if (formElement.renderer()) {
- formElement.dispatchSimulatedClick(event);
+ HTMLFormControlElement* formElement = toHTMLFormControlElement(formAssociatedElement);
+ if (formElement->isSuccessfulSubmitButton()) {
+ if (formElement->renderer()) {
+ formElement->dispatchSimulatedClick(event);
return;
}
- } else if (formElement.canTriggerImplicitSubmission())
+ } else if (formElement->canTriggerImplicitSubmission())
++submissionTriggerCount;
}
@@ -204,10 +199,10 @@ void HTMLFormElement::submitImplicitly(Event* event, bool fromImplicitSubmission
static inline HTMLFormControlElement* submitElementFromEvent(const Event* event)
{
for (Node* node = event->target()->toNode(); node; node = node->parentNode()) {
- if (is<HTMLFormControlElement>(*node))
- return downcast<HTMLFormControlElement>(node);
+ if (node->isElementNode() && toElement(node)->isFormControlElement())
+ return toHTMLFormControlElement(node);
}
- return nullptr;
+ return 0;
}
bool HTMLFormElement::validateInteractively(Event* event)
@@ -221,8 +216,8 @@ bool HTMLFormElement::validateInteractively(Event* event)
return true;
for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- if (is<HTMLFormControlElement>(*m_associatedElements[i]))
- downcast<HTMLFormControlElement>(*m_associatedElements[i]).hideVisibleValidationMessage();
+ if (m_associatedElements[i]->isFormControlElement())
+ toHTMLFormControlElement(m_associatedElements[i])->hideVisibleValidationMessage();
}
Vector<RefPtr<FormAssociatedElement>> unhandledInvalidControls;
@@ -243,8 +238,8 @@ bool HTMLFormElement::validateInteractively(Event* event)
if (element.inDocument() && element.isFocusable()) {
element.scrollIntoViewIfNeeded(false);
element.focus();
- if (is<HTMLFormControlElement>(element))
- downcast<HTMLFormControlElement>(element).updateVisibleValidationMessage();
+ if (element.isFormControlElement())
+ toHTMLFormControlElement(element).updateVisibleValidationMessage();
break;
}
}
@@ -258,18 +253,18 @@ bool HTMLFormElement::validateInteractively(Event* event)
continue;
String message("An invalid form control with name='%name' is not focusable.");
message.replace("%name", control.name());
- document().addConsoleMessage(MessageSource::Rendering, MessageLevel::Error, message);
+ document().addConsoleMessage(RenderingMessageSource, ErrorMessageLevel, message);
}
}
return false;
}
-void HTMLFormElement::prepareForSubmission(Event* event)
+bool HTMLFormElement::prepareForSubmission(Event* event)
{
Frame* frame = document().frame();
if (m_isSubmittingOrPreparingForSubmission || !frame)
- return;
+ return m_isSubmittingOrPreparingForSubmission;
m_isSubmittingOrPreparingForSubmission = true;
m_shouldSubmit = false;
@@ -277,7 +272,7 @@ void HTMLFormElement::prepareForSubmission(Event* event)
// Interactive validation must be done before dispatching the submit event.
if (!validateInteractively(event)) {
m_isSubmittingOrPreparingForSubmission = false;
- return;
+ return false;
}
StringPairVector controlNamesAndValues;
@@ -286,7 +281,6 @@ void HTMLFormElement::prepareForSubmission(Event* event)
frame->loader().client().dispatchWillSendSubmitEvent(formState.release());
Ref<HTMLFormElement> protect(*this);
- // Event handling can result in m_shouldSubmit becoming true, regardless of dispatchEvent() return value.
if (dispatchEvent(Event::create(eventNames().submitEvent, true, true)))
m_shouldSubmit = true;
@@ -294,6 +288,8 @@ void HTMLFormElement::prepareForSubmission(Event* event)
if (m_shouldSubmit)
submit(event, true, true, NotSubmittedByJavaScript);
+
+ return m_shouldSubmit;
}
void HTMLFormElement::submit()
@@ -314,9 +310,9 @@ void HTMLFormElement::getTextFieldValues(StringPairVector& fieldNamesAndValues)
for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
FormAssociatedElement& control = *m_associatedElements[i];
HTMLElement& element = control.asHTMLElement();
- if (!is<HTMLInputElement>(element))
+ if (!isHTMLInputElement(element))
continue;
- HTMLInputElement& input = downcast<HTMLInputElement>(element);
+ HTMLInputElement& input = toHTMLInputElement(element);
if (!input.isTextField())
continue;
fieldNamesAndValues.append(std::make_pair(input.name().string(), input.value()));
@@ -343,21 +339,21 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool proce
for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
FormAssociatedElement* associatedElement = m_associatedElements[i];
- if (!is<HTMLFormControlElement>(*associatedElement))
+ if (!associatedElement->isFormControlElement())
continue;
if (needButtonActivation) {
- HTMLFormControlElement& control = downcast<HTMLFormControlElement>(*associatedElement);
- if (control.isActivatedSubmit())
+ HTMLFormControlElement* control = toHTMLFormControlElement(associatedElement);
+ if (control->isActivatedSubmit())
needButtonActivation = false;
- else if (!firstSuccessfulSubmitButton && control.isSuccessfulSubmitButton())
- firstSuccessfulSubmitButton = &control;
+ else if (firstSuccessfulSubmitButton == 0 && control->isSuccessfulSubmitButton())
+ firstSuccessfulSubmitButton = control;
}
}
if (needButtonActivation && firstSuccessfulSubmitButton)
firstSuccessfulSubmitButton->setActivatedSubmit(true);
- LockHistory lockHistory = processingUserGesture ? LockHistory::No : LockHistory::Yes;
+ bool lockHistory = !processingUserGesture;
Ref<HTMLFormElement> protect(*this); // Form submission can execute arbitary JavaScript.
frame->loader().submitForm(FormSubmission::create(this, m_attributes, event, lockHistory, formSubmissionTrigger));
@@ -382,8 +378,8 @@ void HTMLFormElement::reset()
}
for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- if (is<HTMLFormControlElement>(*m_associatedElements[i]))
- downcast<HTMLFormControlElement>(*m_associatedElements[i]).reset();
+ if (m_associatedElements[i]->isFormControlElement())
+ toHTMLFormControlElement(m_associatedElements[i])->reset();
}
m_isInResetFunction = false;
@@ -421,63 +417,6 @@ void HTMLFormElement::setAutocapitalize(const AtomicString& value)
{
setAttribute(autocapitalizeAttr, value);
}
-
-#endif
-
-#if ENABLE(REQUEST_AUTOCOMPLETE)
-
-void HTMLFormElement::requestAutocomplete()
-{
- Frame* frame = document().frame();
- if (!frame)
- return;
-
- if (!shouldAutocomplete() || !ScriptController::processingUserGesture()) {
- finishRequestAutocomplete(AutocompleteResult::ErrorDisabled);
- return;
- }
-
- StringPairVector controlNamesAndValues;
- getTextFieldValues(controlNamesAndValues);
-
- RefPtr<FormState> formState = FormState::create(this, controlNamesAndValues, &document(), SubmittedByJavaScript);
- frame->loader().client().didRequestAutocomplete(formState.release());
-}
-
-void HTMLFormElement::finishRequestAutocomplete(AutocompleteResult result)
-{
- RefPtr<Event> event;
- switch (result) {
- case AutocompleteResult::Success:
- event = Event::create(eventNames().autocompleteEvent, false, false);
- break;
- case AutocompleteResult::ErrorDisabled:
- event = AutocompleteErrorEvent::create("disabled");
- break;
- case AutocompleteResult::ErrorCancel:
- event = AutocompleteErrorEvent::create("cancel");
- break;
- case AutocompleteResult::ErrorInvalid:
- event = AutocompleteErrorEvent::create("invalid");
- break;
- }
-
- event->setTarget(this);
- m_pendingAutocompleteEvents.append(event.release());
-
- // Dispatch events later as this API is meant to work asynchronously in all situations and implementations.
- if (!m_requestAutocompleteTimer.isActive())
- m_requestAutocompleteTimer.startOneShot(0);
-}
-
-void HTMLFormElement::requestAutocompleteTimerFired()
-{
- Vector<RefPtr<Event>> pendingEvents;
- m_pendingAutocompleteEvents.swap(pendingEvents);
- for (auto& pendingEvent : pendingEvents)
- dispatchEvent(pendingEvent.release());
-}
-
#endif
void HTMLFormElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -502,6 +441,16 @@ void HTMLFormElement::parseAttribute(const QualifiedName& name, const AtomicStri
HTMLElement::parseAttribute(name, value);
}
+template<class T, size_t n> static void removeFromVector(Vector<T*, n> & vec, T* item)
+{
+ size_t size = vec.size();
+ for (size_t i = 0; i != size; ++i)
+ if (vec[i] == item) {
+ vec.remove(i);
+ break;
+ }
+}
+
unsigned HTMLFormElement::formElementIndexWithFormAttribute(Element* element, unsigned rangeStart, unsigned rangeEnd)
{
if (m_associatedElements.isEmpty())
@@ -574,7 +523,7 @@ unsigned HTMLFormElement::formElementIndex(FormAssociatedElement* associatedElem
for (auto& element : descendants) {
if (&element == &associatedHTMLElement)
return i;
- if (!is<HTMLFormControlElement>(element) && !is<HTMLObjectElement>(element))
+ if (!isHTMLFormControlElement(element) && !isHTMLObjectElement(element))
continue;
if (element.form() != this)
continue;
@@ -590,32 +539,18 @@ void HTMLFormElement::registerFormElement(FormAssociatedElement* e)
void HTMLFormElement::removeFormElement(FormAssociatedElement* e)
{
- unsigned index = m_associatedElements.find(e);
+ unsigned index;
+ for (index = 0; index < m_associatedElements.size(); ++index) {
+ if (m_associatedElements[index] == e)
+ break;
+ }
ASSERT_WITH_SECURITY_IMPLICATION(index < m_associatedElements.size());
if (index < m_associatedElementsBeforeIndex)
--m_associatedElementsBeforeIndex;
if (index < m_associatedElementsAfterIndex)
--m_associatedElementsAfterIndex;
removeFromPastNamesMap(e);
- m_associatedElements.remove(index);
-}
-
-void HTMLFormElement::registerInvalidAssociatedFormControl(const HTMLFormControlElement& formControlElement)
-{
- ASSERT_WITH_MESSAGE(!is<HTMLFieldSetElement>(formControlElement), "FieldSet are never candidates for constraint validation.");
- ASSERT(static_cast<const Element&>(formControlElement).matchesInvalidPseudoClass());
-
- if (m_invalidAssociatedFormControls.isEmpty())
- setNeedsStyleRecalc();
- m_invalidAssociatedFormControls.add(&formControlElement);
-}
-
-void HTMLFormElement::removeInvalidAssociatedFormControlIfNeeded(const HTMLFormControlElement& formControlElement)
-{
- if (m_invalidAssociatedFormControls.remove(&formControlElement)) {
- if (m_invalidAssociatedFormControls.isEmpty())
- setNeedsStyleRecalc();
- }
+ removeFromVector(m_associatedElements, e);
}
bool HTMLFormElement::isURLAttribute(const Attribute& attribute) const
@@ -631,12 +566,12 @@ void HTMLFormElement::registerImgElement(HTMLImageElement* e)
void HTMLFormElement::removeImgElement(HTMLImageElement* e)
{
+ ASSERT(m_imageElements.find(e) != notFound);
removeFromPastNamesMap(e);
- bool removed = m_imageElements.removeFirst(e);
- ASSERT_UNUSED(removed, removed);
+ removeFromVector(m_imageElements, e);
}
-Ref<HTMLCollection> HTMLFormElement::elements()
+PassRefPtr<HTMLCollection> HTMLFormElement::elements()
{
return ensureCachedHTMLCollection(FormControls);
}
@@ -656,7 +591,7 @@ bool HTMLFormElement::noValidate() const
// (Darin Adler) removed this, someone added it back, so I am leaving it in for now.
String HTMLFormElement::action() const
{
- return fastGetAttribute(actionAttr);
+ return getAttribute(actionAttr);
}
void HTMLFormElement::setAction(const String &value)
@@ -692,14 +627,14 @@ bool HTMLFormElement::wasUserSubmitted() const
HTMLFormControlElement* HTMLFormElement::defaultButton() const
{
for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- if (!is<HTMLFormControlElement>(*m_associatedElements[i]))
+ if (!m_associatedElements[i]->isFormControlElement())
continue;
- HTMLFormControlElement& control = downcast<HTMLFormControlElement>(*m_associatedElements[i]);
- if (control.isSuccessfulSubmitButton())
- return &control;
+ HTMLFormControlElement* control = toHTMLFormControlElement(m_associatedElements[i]);
+ if (control->isSuccessfulSubmitButton())
+ return control;
}
- return nullptr;
+ return 0;
}
bool HTMLFormElement::checkValidity()
@@ -719,9 +654,9 @@ bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<Form
elements.append(m_associatedElements[i]);
bool hasInvalidControls = false;
for (unsigned i = 0; i < elements.size(); ++i) {
- if (elements[i]->form() == this && is<HTMLFormControlElement>(*elements[i])) {
- HTMLFormControlElement& control = downcast<HTMLFormControlElement>(*elements[i]);
- if (!control.checkValidity(&unhandledInvalidControls) && control.form() == this)
+ if (elements[i]->form() == this && elements[i]->isFormControlElement()) {
+ HTMLFormControlElement* control = toHTMLFormControlElement(elements[i].get());
+ if (!control->checkValidity(&unhandledInvalidControls) && control->form() == this)
hasInvalidControls = true;
}
}
@@ -741,7 +676,7 @@ void HTMLFormElement::assertItemCanBeInPastNamesMap(FormNamedItem* item) const
}
ASSERT_WITH_SECURITY_IMPLICATION(element.hasTagName(imgTag));
- ASSERT_WITH_SECURITY_IMPLICATION(m_imageElements.find(&downcast<HTMLImageElement>(element)) != notFound);
+ ASSERT_WITH_SECURITY_IMPLICATION(m_imageElements.find(&toHTMLImageElement(element)) != notFound);
}
#else
inline void HTMLFormElement::assertItemCanBeInPastNamesMap(FormNamedItem*) const
@@ -766,7 +701,7 @@ void HTMLFormElement::addToPastNamesMap(FormNamedItem* item, const AtomicString&
if (pastName.isEmpty())
return;
if (!m_pastNamesMap)
- m_pastNamesMap = std::make_unique<PastNamesMap>();
+ m_pastNamesMap = adoptPtr(new PastNamesMap);
m_pastNamesMap->set(pastName.impl(), item);
}
@@ -783,34 +718,22 @@ void HTMLFormElement::removeFromPastNamesMap(FormNamedItem* item)
}
}
-bool HTMLFormElement::matchesValidPseudoClass() const
-{
- return m_invalidAssociatedFormControls.isEmpty();
-}
-
-bool HTMLFormElement::matchesInvalidPseudoClass() const
-{
- return !m_invalidAssociatedFormControls.isEmpty();
-}
-
bool HTMLFormElement::hasNamedElement(const AtomicString& name)
{
return elements()->hasNamedItem(name) || elementFromPastNamesMap(name);
}
-// FIXME: Use Ref<HTMLElement> for the function result since there are no non-HTML elements returned here.
-Vector<Ref<Element>> HTMLFormElement::namedElements(const AtomicString& name)
+// FIXME: Use RefPtr<HTMLElement> for namedItems. elements()->namedItems never return non-HTMLElement nodes.
+void HTMLFormElement::getNamedElements(const AtomicString& name, Vector<Ref<Element>>& namedItems)
{
// http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#dom-form-nameditem
- Vector<Ref<Element>> namedItems = elements()->namedItems(name);
+ elements()->namedItems(name, namedItems);
HTMLElement* elementFromPast = elementFromPastNamesMap(name);
- if (namedItems.size() == 1 && namedItems.first().ptr() != elementFromPast)
- addToPastNamesMap(downcast<HTMLElement>(namedItems.first().get()).asFormNamedItem(), name);
+ if (namedItems.size() == 1 && &namedItems.first().get() != elementFromPast)
+ addToPastNamesMap(toHTMLElement(&namedItems.first().get())->asFormNamedItem(), name);
else if (elementFromPast && namedItems.isEmpty())
namedItems.append(*elementFromPast);
-
- return namedItems;
}
void HTMLFormElement::documentDidResumeFromPageCache()
@@ -818,8 +741,8 @@ void HTMLFormElement::documentDidResumeFromPageCache()
ASSERT(!shouldAutocomplete());
for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- if (is<HTMLFormControlElement>(*m_associatedElements[i]))
- downcast<HTMLFormControlElement>(*m_associatedElements[i]).reset();
+ if (m_associatedElements[i]->isFormControlElement())
+ toHTMLFormControlElement(m_associatedElements[i])->reset();
}
}
diff --git a/Source/WebCore/html/HTMLFormElement.h b/Source/WebCore/html/HTMLFormElement.h
index 00515a3b4..e63898455 100644
--- a/Source/WebCore/html/HTMLFormElement.h
+++ b/Source/WebCore/html/HTMLFormElement.h
@@ -28,7 +28,7 @@
#include "FormState.h"
#include "FormSubmission.h"
#include "HTMLElement.h"
-#include <memory>
+#include <wtf/OwnPtr.h>
#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
#include "Autocapitalize.h"
@@ -46,13 +46,13 @@ class TextEncoding;
class HTMLFormElement final : public HTMLElement {
public:
- static Ref<HTMLFormElement> create(Document&);
- static Ref<HTMLFormElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLFormElement> create(Document&);
+ static PassRefPtr<HTMLFormElement> create(const QualifiedName&, Document&);
virtual ~HTMLFormElement();
- Ref<HTMLCollection> elements();
+ PassRefPtr<HTMLCollection> elements();
bool hasNamedElement(const AtomicString&);
- Vector<Ref<Element>> namedElements(const AtomicString&);
+ void getNamedElements(const AtomicString&, Vector<Ref<Element>>&);
unsigned length() const;
Node* item(unsigned index);
@@ -66,10 +66,10 @@ public:
bool shouldAutocomplete() const;
#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
- WEBCORE_EXPORT bool autocorrect() const;
+ bool autocorrect() const;
void setAutocorrect(bool);
- WEBCORE_EXPORT WebAutocapitalizeType autocapitalizeType() const;
+ WebAutocapitalizeType autocapitalizeType() const;
const AtomicString& autocapitalize() const;
void setAutocapitalize(const AtomicString&);
#endif
@@ -78,13 +78,10 @@ public:
void registerFormElement(FormAssociatedElement*);
void removeFormElement(FormAssociatedElement*);
- void registerInvalidAssociatedFormControl(const HTMLFormControlElement&);
- void removeInvalidAssociatedFormControlIfNeeded(const HTMLFormControlElement&);
-
void registerImgElement(HTMLImageElement*);
void removeImgElement(HTMLImageElement*);
- void prepareForSubmission(Event*); // FIXME: This function doesn't only prepare, it sometimes calls submit() itself.
+ bool prepareForSubmission(Event*);
void submit();
void submitFromJavaScript();
void reset();
@@ -115,18 +112,6 @@ public:
bool checkValidity();
-#if ENABLE(REQUEST_AUTOCOMPLETE)
- enum class AutocompleteResult {
- Success,
- ErrorDisabled,
- ErrorCancel,
- ErrorInvalid,
- };
-
- void requestAutocomplete();
- void finishRequestAutocomplete(AutocompleteResult);
-#endif
-
CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
const Vector<FormAssociatedElement*>& associatedElements() const { return m_associatedElements; }
@@ -173,13 +158,10 @@ private:
void assertItemCanBeInPastNamesMap(FormNamedItem*) const;
void removeFromPastNamesMap(FormNamedItem*);
- virtual bool matchesValidPseudoClass() const override;
- virtual bool matchesInvalidPseudoClass() const override;
-
typedef HashMap<RefPtr<AtomicStringImpl>, FormNamedItem*> PastNamesMap;
FormSubmission::Attributes m_attributes;
- std::unique_ptr<PastNamesMap> m_pastNamesMap;
+ OwnPtr<PastNamesMap> m_pastNamesMap;
CheckedRadioButtons m_checkedRadioButtons;
@@ -187,7 +169,6 @@ private:
unsigned m_associatedElementsAfterIndex;
Vector<FormAssociatedElement*> m_associatedElements;
Vector<HTMLImageElement*> m_imageElements;
- HashSet<const HTMLFormControlElement*> m_invalidAssociatedFormControls;
bool m_wasUserSubmitted;
bool m_isSubmittingOrPreparingForSubmission;
@@ -196,15 +177,10 @@ private:
bool m_isInResetFunction;
bool m_wasDemoted;
-
-#if ENABLE(REQUEST_AUTOCOMPLETE)
- void requestAutocompleteTimerFired();
-
- Vector<RefPtr<Event>> m_pendingAutocompleteEvents;
- Timer m_requestAutocompleteTimer;
-#endif
};
+NODE_TYPE_CASTS(HTMLFormElement)
+
} // namespace WebCore
#endif // HTMLFormElement_h
diff --git a/Source/WebCore/html/HTMLFormElement.idl b/Source/WebCore/html/HTMLFormElement.idl
index 2b7276de5..8493f7ad8 100644
--- a/Source/WebCore/html/HTMLFormElement.idl
+++ b/Source/WebCore/html/HTMLFormElement.idl
@@ -46,6 +46,4 @@
#endif
void reset();
boolean checkValidity();
-
- [Conditional=REQUEST_AUTOCOMPLETE] void requestAutocomplete();
};
diff --git a/Source/WebCore/html/HTMLFrameElement.cpp b/Source/WebCore/html/HTMLFrameElement.cpp
index af1a522bc..c961d2fa5 100644
--- a/Source/WebCore/html/HTMLFrameElement.cpp
+++ b/Source/WebCore/html/HTMLFrameElement.cpp
@@ -24,6 +24,7 @@
#include "config.h"
#include "HTMLFrameElement.h"
+#include "Attribute.h"
#include "Frame.h"
#include "HTMLFrameSetElement.h"
#include "HTMLNames.h"
@@ -42,9 +43,9 @@ inline HTMLFrameElement::HTMLFrameElement(const QualifiedName& tagName, Document
setHasCustomStyleResolveCallbacks();
}
-Ref<HTMLFrameElement> HTMLFrameElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLFrameElement> HTMLFrameElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLFrameElement(tagName, document));
+ return adoptRef(new HTMLFrameElement(tagName, document));
}
bool HTMLFrameElement::rendererIsNeeded(const RenderStyle&)
@@ -53,14 +54,14 @@ bool HTMLFrameElement::rendererIsNeeded(const RenderStyle&)
return isURLAllowed();
}
-RenderPtr<RenderElement> HTMLFrameElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLFrameElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderFrame>(*this, WTF::move(style));
+ return createRenderer<RenderFrame>(*this, std::move(style));
}
bool HTMLFrameElement::noResize() const
{
- return fastHasAttribute(noresizeAttr);
+ return hasAttribute(noresizeAttr);
}
void HTMLFrameElement::didAttachRenderers()
diff --git a/Source/WebCore/html/HTMLFrameElement.h b/Source/WebCore/html/HTMLFrameElement.h
index 87688c07e..5579c9848 100644
--- a/Source/WebCore/html/HTMLFrameElement.h
+++ b/Source/WebCore/html/HTMLFrameElement.h
@@ -30,7 +30,7 @@ namespace WebCore {
class HTMLFrameElement final : public HTMLFrameElementBase {
public:
- static Ref<HTMLFrameElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLFrameElement> create(const QualifiedName&, Document&);
bool hasFrameBorder() const { return m_frameBorder; }
@@ -42,14 +42,20 @@ private:
virtual void didAttachRenderers() override;
virtual bool rendererIsNeeded(const RenderStyle&) override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
+#if ENABLE(FULLSCREEN_API)
+ virtual bool allowFullScreen() const { return false; }
+#endif
+
bool m_frameBorder;
bool m_frameBorderSet;
};
+NODE_TYPE_CASTS(HTMLFrameElement)
+
} // namespace WebCore
#endif // HTMLFrameElement_h
diff --git a/Source/WebCore/html/HTMLFrameElement.idl b/Source/WebCore/html/HTMLFrameElement.idl
index e81d0cb76..5a4324810 100644
--- a/Source/WebCore/html/HTMLFrameElement.idl
+++ b/Source/WebCore/html/HTMLFrameElement.idl
@@ -35,9 +35,11 @@ interface HTMLFrameElement : HTMLElement {
// Extensions
readonly attribute DOMWindow contentWindow;
+#if defined(ENABLE_SVG) && ENABLE_SVG
#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
[CheckSecurityForNode, RaisesException] SVGDocument getSVGDocument();
#endif
+#endif
[TreatNullAs=NullString, CustomSetter] attribute DOMString location;
diff --git a/Source/WebCore/html/HTMLFrameElementBase.cpp b/Source/WebCore/html/HTMLFrameElementBase.cpp
index 7361c5b79..3b34af5bb 100644
--- a/Source/WebCore/html/HTMLFrameElementBase.cpp
+++ b/Source/WebCore/html/HTMLFrameElementBase.cpp
@@ -24,6 +24,7 @@
#include "config.h"
#include "HTMLFrameElementBase.h"
+#include "Attribute.h"
#include "Document.h"
#include "EventNames.h"
#include "FocusController.h"
@@ -48,6 +49,7 @@ HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tagName, Documen
, m_scrolling(ScrollbarAuto)
, m_marginWidth(-1)
, m_marginHeight(-1)
+ , m_viewSource(false)
{
setHasCustomStyleResolveCallbacks();
}
@@ -75,7 +77,7 @@ bool HTMLFrameElementBase::isURLAllowed() const
return true;
}
-void HTMLFrameElementBase::openURL(LockHistory lockHistory, LockBackForwardList lockBackForwardList)
+void HTMLFrameElementBase::openURL(bool lockHistory, bool lockBackForwardList)
{
if (!isURLAllowed())
return;
@@ -88,6 +90,8 @@ void HTMLFrameElementBase::openURL(LockHistory lockHistory, LockBackForwardList
return;
parentFrame->loader().subframeLoader().requestFrame(*this, m_URL, m_frameName, lockHistory, lockBackForwardList);
+ if (contentFrame())
+ contentFrame()->setInViewSourceMode(viewSourceMode());
}
void HTMLFrameElementBase::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -96,7 +100,8 @@ void HTMLFrameElementBase::parseAttribute(const QualifiedName& name, const Atomi
setLocation("about:srcdoc");
else if (name == srcAttr && !fastHasAttribute(srcdocAttr))
setLocation(stripLeadingAndTrailingHTMLSpaces(value));
- else if (name == HTMLNames::idAttr) {
+ else if (isIdAttributeName(name)) {
+ // Important to call through to base for the id attribute so the hasID bit gets set.
HTMLFrameOwnerElement::parseAttribute(name, value);
m_frameName = value;
} else if (name == nameAttr) {
@@ -117,6 +122,11 @@ void HTMLFrameElementBase::parseAttribute(const QualifiedName& name, const Atomi
else if (equalIgnoringCase(value, "no"))
m_scrolling = ScrollbarAlwaysOff;
// FIXME: If we are already attached, this has no effect.
+ } else if (name == onbeforeloadAttr)
+ setAttributeEventListener(eventNames().beforeloadEvent, name, value);
+ else if (name == onbeforeunloadAttr) {
+ // FIXME: should <frame> elements have beforeunload handlers?
+ setAttributeEventListener(eventNames().beforeunloadEvent, name, value);
} else
HTMLFrameOwnerElement::parseAttribute(name, value);
}
@@ -133,11 +143,11 @@ Node::InsertionNotificationRequest HTMLFrameElementBase::insertedInto(ContainerN
{
HTMLFrameOwnerElement::insertedInto(insertionPoint);
if (insertionPoint.inDocument())
- return InsertionShouldCallFinishedInsertingSubtree;
+ return InsertionShouldCallDidNotifySubtreeInsertions;
return InsertionDone;
}
-void HTMLFrameElementBase::finishedInsertingSubtree()
+void HTMLFrameElementBase::didNotifySubtreeInsertions(ContainerNode*)
{
if (!inDocument())
return;
@@ -166,7 +176,7 @@ URL HTMLFrameElementBase::location() const
{
if (fastHasAttribute(srcdocAttr))
return URL(ParsedURLString, "about:srcdoc");
- return document().completeURL(fastGetAttribute(srcAttr));
+ return document().completeURL(getAttribute(srcAttr));
}
void HTMLFrameElementBase::setLocation(const String& str)
@@ -178,7 +188,7 @@ void HTMLFrameElementBase::setLocation(const String& str)
m_URL = AtomicString(str);
if (inDocument())
- openURL(LockHistory::No, LockBackForwardList::No);
+ openURL(false, false);
}
bool HTMLFrameElementBase::supportsFocus() const
diff --git a/Source/WebCore/html/HTMLFrameElementBase.h b/Source/WebCore/html/HTMLFrameElementBase.h
index 013cba0b9..007ff548a 100644
--- a/Source/WebCore/html/HTMLFrameElementBase.h
+++ b/Source/WebCore/html/HTMLFrameElementBase.h
@@ -24,7 +24,6 @@
#ifndef HTMLFrameElementBase_h
#define HTMLFrameElementBase_h
-#include "FrameLoaderTypes.h"
#include "HTMLFrameOwnerElement.h"
#include "ScrollTypes.h"
@@ -35,7 +34,7 @@ public:
URL location() const;
void setLocation(const String&);
- virtual ScrollbarMode scrollingMode() const override final { return m_scrolling; }
+ virtual ScrollbarMode scrollingMode() const override { return m_scrolling; }
int marginWidth() const { return m_marginWidth; }
int marginHeight() const { return m_marginHeight; }
@@ -43,7 +42,7 @@ public:
int width();
int height();
- virtual bool canContainRangeEndPoint() const override final { return false; }
+ virtual bool canContainRangeEndPoint() const override { return false; }
protected:
HTMLFrameElementBase(const QualifiedName&, Document&);
@@ -51,21 +50,25 @@ protected:
bool isURLAllowed() const;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
- virtual InsertionNotificationRequest insertedInto(ContainerNode&) override final;
- virtual void finishedInsertingSubtree() override final;
+ virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
+ virtual void didNotifySubtreeInsertions(ContainerNode*) override;
virtual void didAttachRenderers() override;
private:
- virtual bool supportsFocus() const override final;
- virtual void setFocus(bool) override final;
+ virtual bool supportsFocus() const override;
+ virtual void setFocus(bool) override;
- virtual bool isURLAttribute(const Attribute&) const override final;
- virtual bool isHTMLContentAttribute(const Attribute&) const override final;
+ virtual bool isURLAttribute(const Attribute&) const override;
+ virtual bool isHTMLContentAttribute(const Attribute&) const override;
- virtual bool isFrameElementBase() const override final { return true; }
+ virtual bool isFrameElementBase() const override { return true; }
+
+ virtual bool areAuthorShadowsAllowed() const override { return false; }
+
+ bool viewSourceMode() const { return m_viewSource; }
void setNameAndOpenURL();
- void openURL(LockHistory = LockHistory::Yes, LockBackForwardList = LockBackForwardList::Yes);
+ void openURL(bool lockHistory = true, bool lockBackForwardList = true);
AtomicString m_URL;
AtomicString m_frameName;
@@ -74,13 +77,16 @@ private:
int m_marginWidth;
int m_marginHeight;
+
+ bool m_viewSource;
};
-} // namespace WebCore
+void isHTMLFrameElementBase(const HTMLFrameElementBase&); // Catch unnecessary runtime check of type known at compile time.
+inline bool isHTMLFrameElementBase(const Element& element) { return isHTMLFrameElement(element) || isHTMLIFrameElement(element); }
+inline bool isHTMLFrameElementBase(const Node& node) { return node.isElementNode() && isHTMLFrameElementBase(toElement(node)); }
+
+NODE_TYPE_CASTS(HTMLFrameElementBase)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLFrameElementBase)
- static bool isType(const WebCore::HTMLElement& element) { return is<WebCore::HTMLFrameElement>(element) || is<WebCore::HTMLIFrameElement>(element); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::HTMLElement>(node) && isType(downcast<WebCore::HTMLElement>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+} // namespace WebCore
#endif // HTMLFrameElementBase_h
diff --git a/Source/WebCore/html/HTMLFrameOwnerElement.cpp b/Source/WebCore/html/HTMLFrameOwnerElement.cpp
index a85e79dd0..253aaee8f 100644
--- a/Source/WebCore/html/HTMLFrameOwnerElement.cpp
+++ b/Source/WebCore/html/HTMLFrameOwnerElement.cpp
@@ -22,19 +22,22 @@
#include "HTMLFrameOwnerElement.h"
#include "DOMWindow.h"
-#include "ExceptionCode.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "RenderWidget.h"
#include "ShadowRoot.h"
-#include "SVGDocument.h"
#include <wtf/Ref.h>
+#if ENABLE(SVG)
+#include "ExceptionCode.h"
+#include "SVGDocument.h"
+#endif
+
namespace WebCore {
HTMLFrameOwnerElement::HTMLFrameOwnerElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
- , m_contentFrame(nullptr)
+ , m_contentFrame(0)
, m_sandboxFlags(SandboxNone)
{
}
@@ -43,9 +46,9 @@ RenderWidget* HTMLFrameOwnerElement::renderWidget() const
{
// HTMLObjectElement and HTMLEmbedElement may return arbitrary renderers
// when using fallback content.
- if (!is<RenderWidget>(renderer()))
- return nullptr;
- return downcast<RenderWidget>(renderer());
+ if (!renderer() || !renderer()->isWidget())
+ return 0;
+ return toRenderWidget(renderer());
}
void HTMLFrameOwnerElement::setContentFrame(Frame* frame)
@@ -111,24 +114,28 @@ bool HTMLFrameOwnerElement::isKeyboardFocusable(KeyboardEvent* event) const
return m_contentFrame && HTMLElement::isKeyboardFocusable(event);
}
+#if ENABLE(SVG)
SVGDocument* HTMLFrameOwnerElement::getSVGDocument(ExceptionCode& ec) const
{
- Document* document = contentDocument();
- if (is<SVGDocument>(document))
- return downcast<SVGDocument>(document);
+ Document* doc = contentDocument();
+ if (doc && doc->isSVGDocument())
+ return toSVGDocument(doc);
// Spec: http://www.w3.org/TR/SVG/struct.html#InterfaceGetSVGDocument
ec = NOT_SUPPORTED_ERR;
- return nullptr;
+ return 0;
+}
+#endif
+
+static void needsStyleRecalcCallback(Node& node, unsigned data)
+{
+ node.setNeedsStyleRecalc(static_cast<StyleChangeType>(data));
}
void HTMLFrameOwnerElement::scheduleSetNeedsStyleRecalc(StyleChangeType changeType)
{
- if (Style::postResolutionCallbacksAreSuspended()) {
- RefPtr<HTMLFrameOwnerElement> element = this;
- Style::queuePostResolutionCallback([element, changeType]{
- element->setNeedsStyleRecalc(changeType);
- });
- } else
+ if (postAttachCallbacksAreSuspended())
+ queuePostAttachCallback(needsStyleRecalcCallback, *this, static_cast<unsigned>(changeType));
+ else
setNeedsStyleRecalc(changeType);
}
diff --git a/Source/WebCore/html/HTMLFrameOwnerElement.h b/Source/WebCore/html/HTMLFrameOwnerElement.h
index 01fa70021..4e4f973df 100644
--- a/Source/WebCore/html/HTMLFrameOwnerElement.h
+++ b/Source/WebCore/html/HTMLFrameOwnerElement.h
@@ -37,7 +37,7 @@ public:
Frame* contentFrame() const { return m_contentFrame; }
DOMWindow* contentWindow() const;
- WEBCORE_EXPORT Document* contentDocument() const;
+ Document* contentDocument() const;
void setContentFrame(Frame*);
void clearContentFrame();
@@ -49,7 +49,9 @@ public:
// RenderElement when using fallback content.
RenderWidget* renderWidget() const;
+#if ENABLE(SVG)
SVGDocument* getSVGDocument(ExceptionCode&) const;
+#endif
virtual ScrollbarMode scrollingMode() const { return ScrollbarAuto; }
@@ -63,12 +65,16 @@ protected:
private:
virtual bool isKeyboardFocusable(KeyboardEvent*) const override;
- virtual bool isFrameOwnerElement() const override final { return true; }
+ virtual bool isFrameOwnerElement() const override { return true; }
Frame* m_contentFrame;
SandboxFlags m_sandboxFlags;
};
+void isHTMLFrameOwnerElement(const HTMLFrameOwnerElement&); // Catch unnecessary runtime check of type known at compile time.
+inline bool isHTMLFrameOwnerElement(const Node& node) { return node.isFrameOwnerElement(); }
+NODE_TYPE_CASTS(HTMLFrameOwnerElement)
+
class SubframeLoadingDisabler {
public:
explicit SubframeLoadingDisabler(ContainerNode& root)
@@ -87,7 +93,7 @@ public:
private:
static HashCountedSet<ContainerNode*>& disabledSubtreeRoots()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(HashCountedSet<ContainerNode*>, nodes, ());
+ DEFINE_STATIC_LOCAL(HashCountedSet<ContainerNode*>, nodes, ());
return nodes;
}
@@ -96,8 +102,4 @@ private:
} // namespace WebCore
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLFrameOwnerElement)
- static bool isType(const WebCore::Node& node) { return node.isFrameOwnerElement(); }
-SPECIALIZE_TYPE_TRAITS_END()
-
#endif // HTMLFrameOwnerElement_h
diff --git a/Source/WebCore/html/HTMLFrameSetElement.cpp b/Source/WebCore/html/HTMLFrameSetElement.cpp
index 1b7dd18d4..6b793d15e 100644
--- a/Source/WebCore/html/HTMLFrameSetElement.cpp
+++ b/Source/WebCore/html/HTMLFrameSetElement.cpp
@@ -24,6 +24,7 @@
#include "config.h"
#include "HTMLFrameSetElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "Document.h"
#include "ElementIterator.h"
@@ -32,7 +33,6 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
-#include "HTMLBodyElement.h"
#include "HTMLNames.h"
#include "Length.h"
#include "MouseEvent.h"
@@ -58,9 +58,9 @@ HTMLFrameSetElement::HTMLFrameSetElement(const QualifiedName& tagName, Document&
setHasCustomStyleResolveCallbacks();
}
-Ref<HTMLFrameSetElement> HTMLFrameSetElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLFrameSetElement> HTMLFrameSetElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLFrameSetElement(tagName, document));
+ return adoptRef(new HTMLFrameSetElement(tagName, document));
}
bool HTMLFrameSetElement::isPresentationAttribute(const QualifiedName& name) const
@@ -81,28 +81,16 @@ void HTMLFrameSetElement::collectStyleForPresentationAttribute(const QualifiedNa
void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == rowsAttr) {
- // FIXME: What is the right thing to do when removing this attribute?
- // Why not treat it the same way we treat setting it to the empty string?
if (!value.isNull()) {
m_rowLengths = newLengthArray(value.string(), m_totalRows);
- // FIXME: Would be nice to optimize the case where m_rowLengths did not change.
setNeedsStyleRecalc();
}
- return;
- }
-
- if (name == colsAttr) {
- // FIXME: What is the right thing to do when removing this attribute?
- // Why not treat it the same way we treat setting it to the empty string?
+ } else if (name == colsAttr) {
if (!value.isNull()) {
m_colLengths = newLengthArray(value.string(), m_totalCols);
- // FIXME: Would be nice to optimize the case where m_colLengths did not change.
setNeedsStyleRecalc();
}
- return;
- }
-
- if (name == frameborderAttr) {
+ } else if (name == frameborderAttr) {
if (!value.isNull()) {
if (equalIgnoringCase(value, "no") || equalIgnoringCase(value, "0")) {
m_frameborder = false;
@@ -114,40 +102,50 @@ void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const Atomic
m_frameborder = false;
m_frameborderSet = false;
}
- // FIXME: Do we need to trigger repainting?
- return;
- }
-
- if (name == noresizeAttr) {
- // FIXME: This should set m_noresize to false if the value is null.
+ } else if (name == noresizeAttr) {
m_noresize = true;
- return;
- }
-
- if (name == borderAttr) {
+ } else if (name == borderAttr) {
if (!value.isNull()) {
m_border = value.toInt();
m_borderSet = true;
} else
m_borderSet = false;
- // FIXME: Do we need to trigger repainting?
- return;
- }
-
- if (name == bordercolorAttr) {
+ } else if (name == bordercolorAttr)
m_borderColorSet = !value.isEmpty();
- // FIXME: Clearly wrong: This can overwrite the value inherited from the parent frameset.
- // FIXME: Do we need to trigger repainting?
- return;
- }
-
- auto& eventName = HTMLBodyElement::eventNameForWindowEventHandlerAttribute(name);
- if (!eventName.isNull()) {
- document().setWindowAttributeEventListener(eventName, name, value);
- return;
- }
-
- HTMLElement::parseAttribute(name, value);
+ else if (name == onloadAttr)
+ document().setWindowAttributeEventListener(eventNames().loadEvent, name, value);
+ else if (name == onbeforeunloadAttr)
+ document().setWindowAttributeEventListener(eventNames().beforeunloadEvent, name, value);
+ else if (name == onunloadAttr)
+ document().setWindowAttributeEventListener(eventNames().unloadEvent, name, value);
+ else if (name == onblurAttr)
+ document().setWindowAttributeEventListener(eventNames().blurEvent, name, value);
+ else if (name == onfocusAttr)
+ document().setWindowAttributeEventListener(eventNames().focusEvent, name, value);
+ else if (name == onfocusinAttr)
+ document().setWindowAttributeEventListener(eventNames().focusinEvent, name, value);
+ else if (name == onfocusoutAttr)
+ document().setWindowAttributeEventListener(eventNames().focusoutEvent, name, value);
+#if ENABLE(ORIENTATION_EVENTS)
+ else if (name == onorientationchangeAttr)
+ document().setWindowAttributeEventListener(eventNames().orientationchangeEvent, name, value);
+#endif
+ else if (name == onhashchangeAttr)
+ document().setWindowAttributeEventListener(eventNames().hashchangeEvent, name, value);
+ else if (name == onresizeAttr)
+ document().setWindowAttributeEventListener(eventNames().resizeEvent, name, value);
+ else if (name == onscrollAttr)
+ document().setWindowAttributeEventListener(eventNames().scrollEvent, name, value);
+ else if (name == onstorageAttr)
+ document().setWindowAttributeEventListener(eventNames().storageEvent, name, value);
+ else if (name == ononlineAttr)
+ document().setWindowAttributeEventListener(eventNames().onlineEvent, name, value);
+ else if (name == onofflineAttr)
+ document().setWindowAttributeEventListener(eventNames().offlineEvent, name, value);
+ else if (name == onpopstateAttr)
+ document().setWindowAttributeEventListener(eventNames().popstateEvent, name, value);
+ else
+ HTMLElement::parseAttribute(name, value);
}
bool HTMLFrameSetElement::rendererIsNeeded(const RenderStyle& style)
@@ -157,12 +155,12 @@ bool HTMLFrameSetElement::rendererIsNeeded(const RenderStyle& style)
return style.isStyleAvailable();
}
-RenderPtr<RenderElement> HTMLFrameSetElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLFrameSetElement::createElementRenderer(PassRef<RenderStyle> style)
{
if (style.get().hasContent())
- return RenderElement::createFor(*this, WTF::move(style));
+ return RenderElement::createFor(*this, std::move(style));
- return createRenderer<RenderFrameSet>(*this, WTF::move(style));
+ return createRenderer<RenderFrameSet>(*this, std::move(style));
}
HTMLFrameSetElement* HTMLFrameSetElement::findContaining(Element* descendant)
@@ -189,16 +187,15 @@ void HTMLFrameSetElement::willAttachRenderers()
m_noresize = containingFrameSet->noResize();
}
-void HTMLFrameSetElement::defaultEventHandler(Event* event)
+void HTMLFrameSetElement::defaultEventHandler(Event* evt)
{
- ASSERT(event);
- if (is<MouseEvent>(*event) && !m_noresize && is<RenderFrameSet>(renderer())) {
- if (downcast<RenderFrameSet>(*renderer()).userResize(downcast<MouseEvent>(event))) {
- event->setDefaultHandled();
+ if (evt->isMouseEvent() && !m_noresize && renderer() && renderer()->isFrameSet()) {
+ if (toRenderFrameSet(renderer())->userResize(static_cast<MouseEvent*>(evt))) {
+ evt->setDefaultHandled();
return;
}
}
- HTMLElement::defaultEventHandler(event);
+ HTMLElement::defaultEventHandler(evt);
}
bool HTMLFrameSetElement::willRecalcStyle(Style::Change)
diff --git a/Source/WebCore/html/HTMLFrameSetElement.h b/Source/WebCore/html/HTMLFrameSetElement.h
index 6cd85dc47..80e7f2afe 100644
--- a/Source/WebCore/html/HTMLFrameSetElement.h
+++ b/Source/WebCore/html/HTMLFrameSetElement.h
@@ -31,7 +31,7 @@ namespace WebCore {
class HTMLFrameSetElement final : public HTMLElement {
public:
- static Ref<HTMLFrameSetElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLFrameSetElement> create(const QualifiedName&, Document&);
bool hasFrameBorder() const { return m_frameborder; }
bool noResize() const { return m_noresize; }
@@ -47,6 +47,25 @@ public:
static HTMLFrameSetElement* findContaining(Element* descendant);
+ // Declared virtual in Element
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(load);
+
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeunload);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(hashchange);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(message);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(offline);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(online);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(popstate);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload);
+#if ENABLE(ORIENTATION_EVENTS)
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange);
+#endif
+
private:
HTMLFrameSetElement(const QualifiedName&, Document&);
@@ -56,7 +75,7 @@ private:
virtual void willAttachRenderers() override;
virtual bool rendererIsNeeded(const RenderStyle&) override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual void defaultEventHandler(Event*) override;
@@ -81,6 +100,8 @@ private:
bool m_noresize;
};
+NODE_TYPE_CASTS(HTMLFrameSetElement)
+
} // namespace WebCore
#endif // HTMLFrameSetElement_h
diff --git a/Source/WebCore/html/HTMLFrameSetElement.idl b/Source/WebCore/html/HTMLFrameSetElement.idl
index 9bd3159aa..cbf9757ea 100644
--- a/Source/WebCore/html/HTMLFrameSetElement.idl
+++ b/Source/WebCore/html/HTMLFrameSetElement.idl
@@ -24,19 +24,31 @@
[Reflect] attribute DOMString cols;
[Reflect] attribute DOMString rows;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onblur;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onerror;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onfocus;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onfocusin;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onfocusout;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onload;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onresize;
- [NotEnumerable, WindowEventHandler] attribute EventHandler onscroll;
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
+ // Event handler attributes
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onbeforeunload;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onhashchange;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onmessage;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onoffline;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener ononline;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onpopstate;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onresize;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onstorage;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onunload;
- [NotEnumerable, WindowEventHandler, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventHandler onwebkitwillrevealbottom;
- [NotEnumerable, WindowEventHandler, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventHandler onwebkitwillrevealleft;
- [NotEnumerable, WindowEventHandler, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventHandler onwebkitwillrevealright;
- [NotEnumerable, WindowEventHandler, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventHandler onwebkitwillrevealtop;
+ [Conditional=ORIENTATION_EVENTS, NotEnumerable, JSWindowEventListener] attribute EventListener onorientationchange;
+
+ // Overrides of Element attributes (with different implementation in bindings).
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onblur;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onerror;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onfocus;
+ [NotEnumerable, JSWindowEventListener] attribute EventListener onload;
+
+ // Not implemented yet.
+ // [NotEnumerable, JSWindowEventListener] attribute EventListener onafterprint;
+ // [NotEnumerable, JSWindowEventListener] attribute EventListener onbeforeprint;
+ // [NotEnumerable, JSWindowEventListener] attribute EventListener onredo;
+ // [NotEnumerable, JSWindowEventListener] attribute EventListener onundo;
+#endif
};
-HTMLFrameSetElement implements WindowEventHandlers;
diff --git a/Source/WebCore/html/HTMLHRElement.cpp b/Source/WebCore/html/HTMLHRElement.cpp
index 4383704f2..99636ba27 100644
--- a/Source/WebCore/html/HTMLHRElement.cpp
+++ b/Source/WebCore/html/HTMLHRElement.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLHRElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "CSSValuePool.h"
@@ -39,14 +40,14 @@ HTMLHRElement::HTMLHRElement(const QualifiedName& tagName, Document& document)
ASSERT(hasTagName(hrTag));
}
-Ref<HTMLHRElement> HTMLHRElement::create(Document& document)
+PassRefPtr<HTMLHRElement> HTMLHRElement::create(Document& document)
{
- return adoptRef(*new HTMLHRElement(hrTag, document));
+ return adoptRef(new HTMLHRElement(hrTag, document));
}
-Ref<HTMLHRElement> HTMLHRElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLHRElement> HTMLHRElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLHRElement(tagName, document));
+ return adoptRef(new HTMLHRElement(tagName, document));
}
bool HTMLHRElement::isPresentationAttribute(const QualifiedName& name) const
@@ -81,7 +82,7 @@ void HTMLHRElement::collectStyleForPresentationAttribute(const QualifiedName& na
addHTMLColorToStyle(style, CSSPropertyBorderColor, value);
addHTMLColorToStyle(style, CSSPropertyBackgroundColor, value);
} else if (name == noshadeAttr) {
- if (!fastHasAttribute(colorAttr)) {
+ if (!hasAttribute(colorAttr)) {
addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderStyle, CSSValueSolid);
RefPtr<CSSPrimitiveValue> darkGrayValue = cssValuePool().createColorValue(Color::darkGray);
@@ -99,9 +100,4 @@ void HTMLHRElement::collectStyleForPresentationAttribute(const QualifiedName& na
HTMLElement::collectStyleForPresentationAttribute(name, value, style);
}
-bool HTMLHRElement::canContainRangeEndPoint() const
-{
- return hasChildNodes() && HTMLElement::canContainRangeEndPoint();
-}
-
}
diff --git a/Source/WebCore/html/HTMLHRElement.h b/Source/WebCore/html/HTMLHRElement.h
index f159465c2..3d483c4af 100644
--- a/Source/WebCore/html/HTMLHRElement.h
+++ b/Source/WebCore/html/HTMLHRElement.h
@@ -29,15 +29,16 @@ namespace WebCore {
class HTMLHRElement final : public HTMLElement {
public:
- static Ref<HTMLHRElement> create(Document&);
- static Ref<HTMLHRElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLHRElement> create(Document&);
+ static PassRefPtr<HTMLHRElement> create(const QualifiedName&, Document&);
+
+ virtual bool canContainRangeEndPoint() const override { return hasChildNodes(); }
private:
HTMLHRElement(const QualifiedName&, Document&);
virtual bool isPresentationAttribute(const QualifiedName&) const override;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
- virtual bool canContainRangeEndPoint() const override;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLHeadElement.cpp b/Source/WebCore/html/HTMLHeadElement.cpp
index 150ec6195..094ff3c8c 100644
--- a/Source/WebCore/html/HTMLHeadElement.cpp
+++ b/Source/WebCore/html/HTMLHeadElement.cpp
@@ -37,14 +37,14 @@ HTMLHeadElement::HTMLHeadElement(const QualifiedName& tagName, Document& documen
ASSERT(hasTagName(headTag));
}
-Ref<HTMLHeadElement> HTMLHeadElement::create(Document& document)
+PassRefPtr<HTMLHeadElement> HTMLHeadElement::create(Document& document)
{
- return adoptRef(*new HTMLHeadElement(headTag, document));
+ return adoptRef(new HTMLHeadElement(headTag, document));
}
-Ref<HTMLHeadElement> HTMLHeadElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLHeadElement> HTMLHeadElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLHeadElement(tagName, document));
+ return adoptRef(new HTMLHeadElement(tagName, document));
}
}
diff --git a/Source/WebCore/html/HTMLHeadElement.h b/Source/WebCore/html/HTMLHeadElement.h
index 8a1680f43..aaffe102b 100644
--- a/Source/WebCore/html/HTMLHeadElement.h
+++ b/Source/WebCore/html/HTMLHeadElement.h
@@ -30,8 +30,8 @@ namespace WebCore {
class HTMLHeadElement final : public HTMLElement {
public:
- static Ref<HTMLHeadElement> create(Document&);
- static Ref<HTMLHeadElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLHeadElement> create(Document&);
+ static PassRefPtr<HTMLHeadElement> create(const QualifiedName&, Document&);
private:
HTMLHeadElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLHeadingElement.cpp b/Source/WebCore/html/HTMLHeadingElement.cpp
index 9aad0355e..47ec663a2 100644
--- a/Source/WebCore/html/HTMLHeadingElement.cpp
+++ b/Source/WebCore/html/HTMLHeadingElement.cpp
@@ -30,9 +30,9 @@ inline HTMLHeadingElement::HTMLHeadingElement(const QualifiedName& tagName, Docu
{
}
-Ref<HTMLHeadingElement> HTMLHeadingElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLHeadingElement> HTMLHeadingElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLHeadingElement(tagName, document));
+ return adoptRef(new HTMLHeadingElement(tagName, document));
}
}
diff --git a/Source/WebCore/html/HTMLHeadingElement.h b/Source/WebCore/html/HTMLHeadingElement.h
index aeecab271..f75ffe789 100644
--- a/Source/WebCore/html/HTMLHeadingElement.h
+++ b/Source/WebCore/html/HTMLHeadingElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLHeadingElement final : public HTMLElement {
public:
- static Ref<HTMLHeadingElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLHeadingElement> create(const QualifiedName&, Document&);
private:
HTMLHeadingElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLHtmlElement.cpp b/Source/WebCore/html/HTMLHtmlElement.cpp
index c7f517aec..131672e3f 100644
--- a/Source/WebCore/html/HTMLHtmlElement.cpp
+++ b/Source/WebCore/html/HTMLHtmlElement.cpp
@@ -42,14 +42,14 @@ HTMLHtmlElement::HTMLHtmlElement(const QualifiedName& tagName, Document& documen
ASSERT(hasTagName(htmlTag));
}
-Ref<HTMLHtmlElement> HTMLHtmlElement::create(Document& document)
+PassRefPtr<HTMLHtmlElement> HTMLHtmlElement::create(Document& document)
{
- return adoptRef(*new HTMLHtmlElement(htmlTag, document));
+ return adoptRef(new HTMLHtmlElement(htmlTag, document));
}
-Ref<HTMLHtmlElement> HTMLHtmlElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLHtmlElement> HTMLHtmlElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLHtmlElement(tagName, document));
+ return adoptRef(new HTMLHtmlElement(tagName, document));
}
bool HTMLHtmlElement::isURLAttribute(const Attribute& attribute) const
@@ -70,7 +70,7 @@ void HTMLHtmlElement::insertedByParser()
if (!documentLoader)
return;
- const AtomicString& manifest = fastGetAttribute(manifestAttr);
+ const AtomicString& manifest = getAttribute(manifestAttr);
if (manifest.isEmpty())
documentLoader->applicationCacheHost()->selectCacheWithoutManifest();
else
diff --git a/Source/WebCore/html/HTMLHtmlElement.h b/Source/WebCore/html/HTMLHtmlElement.h
index 44d6d60db..b966c870b 100644
--- a/Source/WebCore/html/HTMLHtmlElement.h
+++ b/Source/WebCore/html/HTMLHtmlElement.h
@@ -30,8 +30,8 @@ namespace WebCore {
class HTMLHtmlElement final : public HTMLElement {
public:
- static Ref<HTMLHtmlElement> create(Document&);
- static Ref<HTMLHtmlElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLHtmlElement> create(Document&);
+ static PassRefPtr<HTMLHtmlElement> create(const QualifiedName&, Document&);
void insertedByParser();
@@ -41,6 +41,8 @@ private:
virtual bool isURLAttribute(const Attribute&) const override;
};
+NODE_TYPE_CASTS(HTMLHtmlElement)
+
} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLIFrameElement.cpp b/Source/WebCore/html/HTMLIFrameElement.cpp
index e9d57595e..a2f9d10cd 100644
--- a/Source/WebCore/html/HTMLIFrameElement.cpp
+++ b/Source/WebCore/html/HTMLIFrameElement.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "HTMLIFrameElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "Frame.h"
#include "HTMLDocument.h"
@@ -40,16 +41,17 @@ inline HTMLIFrameElement::HTMLIFrameElement(const QualifiedName& tagName, Docume
: HTMLFrameElementBase(tagName, document)
{
ASSERT(hasTagName(iframeTag));
+ setHasCustomStyleResolveCallbacks();
}
-Ref<HTMLIFrameElement> HTMLIFrameElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLIFrameElement> HTMLIFrameElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLIFrameElement(tagName, document));
+ return adoptRef(new HTMLIFrameElement(tagName, document));
}
bool HTMLIFrameElement::isPresentationAttribute(const QualifiedName& name) const
{
- if (name == widthAttr || name == heightAttr || name == alignAttr || name == frameborderAttr)
+ if (name == widthAttr || name == heightAttr || name == alignAttr || name == frameborderAttr || name == seamlessAttr)
return true;
return HTMLFrameElementBase::isPresentationAttribute(name);
}
@@ -79,7 +81,11 @@ void HTMLIFrameElement::parseAttribute(const QualifiedName& name, const AtomicSt
String invalidTokens;
setSandboxFlags(value.isNull() ? SandboxNone : SecurityContext::parseSandboxPolicy(value, invalidTokens));
if (!invalidTokens.isNull())
- document().addConsoleMessage(MessageSource::Other, MessageLevel::Error, "Error while parsing the 'sandbox' attribute: " + invalidTokens);
+ document().addConsoleMessage(OtherMessageSource, ErrorMessageLevel, "Error while parsing the 'sandbox' attribute: " + invalidTokens);
+ } else if (name == seamlessAttr) {
+ // If we're adding or removing the seamless attribute, we need to force the content document to recalculate its StyleResolver.
+ if (contentDocument())
+ contentDocument()->styleResolverChanged(DeferRecalcStyle);
} else
HTMLFrameElementBase::parseAttribute(name, value);
}
@@ -89,9 +95,23 @@ bool HTMLIFrameElement::rendererIsNeeded(const RenderStyle& style)
return isURLAllowed() && style.display() != NONE;
}
-RenderPtr<RenderElement> HTMLIFrameElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLIFrameElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderIFrame>(*this, WTF::move(style));
+ return createRenderer<RenderIFrame>(*this, std::move(style));
+}
+
+bool HTMLIFrameElement::shouldDisplaySeamlessly() const
+{
+ return contentDocument() && contentDocument()->shouldDisplaySeamlesslyWithParent();
+}
+
+void HTMLIFrameElement::didRecalcStyle(Style::Change styleChange)
+{
+ if (!shouldDisplaySeamlessly())
+ return;
+ Document* childDocument = contentDocument();
+ if (styleChange >= Style::Inherit || childDocument->childNeedsStyleRecalc() || childDocument->needsStyleRecalc())
+ contentDocument()->recalcStyle(styleChange == Style::Detach ? Style::Force : styleChange);
}
}
diff --git a/Source/WebCore/html/HTMLIFrameElement.h b/Source/WebCore/html/HTMLIFrameElement.h
index a2dbd564e..18f68880b 100644
--- a/Source/WebCore/html/HTMLIFrameElement.h
+++ b/Source/WebCore/html/HTMLIFrameElement.h
@@ -30,7 +30,9 @@ namespace WebCore {
class HTMLIFrameElement final : public HTMLFrameElementBase {
public:
- static Ref<HTMLIFrameElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLIFrameElement> create(const QualifiedName&, Document&);
+
+ bool shouldDisplaySeamlessly() const;
private:
HTMLIFrameElement(const QualifiedName&, Document&);
@@ -44,9 +46,13 @@ private:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
virtual bool rendererIsNeeded(const RenderStyle&) override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
+
+ virtual void didRecalcStyle(Style::Change) override;
};
+NODE_TYPE_CASTS(HTMLIFrameElement)
+
} // namespace WebCore
#endif // HTMLIFrameElement_h
diff --git a/Source/WebCore/html/HTMLIFrameElement.idl b/Source/WebCore/html/HTMLIFrameElement.idl
index bc79194c0..7a715825d 100644
--- a/Source/WebCore/html/HTMLIFrameElement.idl
+++ b/Source/WebCore/html/HTMLIFrameElement.idl
@@ -27,6 +27,7 @@ interface HTMLIFrameElement : HTMLElement {
[Reflect] attribute DOMString marginWidth;
[Reflect] attribute DOMString name;
[Reflect] attribute DOMString sandbox;
+ [Reflect, Conditional=IFRAME_SEAMLESS] attribute boolean seamless;
[Reflect] attribute DOMString scrolling;
[Reflect, URL] attribute DOMString src;
[Reflect] attribute DOMString srcdoc;
@@ -38,8 +39,10 @@ interface HTMLIFrameElement : HTMLElement {
// Extensions
readonly attribute DOMWindow contentWindow;
+#if defined(ENABLE_SVG) && ENABLE_SVG
#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
[CheckSecurityForNode, RaisesException] SVGDocument getSVGDocument();
#endif
+#endif
};
diff --git a/Source/WebCore/html/HTMLImageElement.cpp b/Source/WebCore/html/HTMLImageElement.cpp
index 7278ca604..31aeb27d9 100644
--- a/Source/WebCore/html/HTMLImageElement.cpp
+++ b/Source/WebCore/html/HTMLImageElement.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLImageElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "CachedImage.h"
@@ -32,17 +33,8 @@
#include "HTMLDocument.h"
#include "HTMLFormElement.h"
#include "HTMLParserIdioms.h"
-#include "HTMLSrcsetParser.h"
#include "Page.h"
#include "RenderImage.h"
-#include "Settings.h"
-#include "ShadowRoot.h"
-#include "SourceSizeList.h"
-#include <wtf/text/StringBuilder.h>
-
-#if ENABLE(SERVICE_CONTROLS)
-#include "ImageControlsRootElement.h"
-#endif
namespace WebCore {
@@ -50,13 +42,9 @@ using namespace HTMLNames;
HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
: HTMLElement(tagName, document)
- , m_imageLoader(*this)
+ , m_imageLoader(this)
, m_form(form)
, m_compositeOperator(CompositeSourceOver)
- , m_imageDevicePixelRatio(1.0f)
-#if ENABLE(SERVICE_CONTROLS)
- , m_experimentalImageMenuEnabled(false)
-#endif
{
ASSERT(hasTagName(imgTag));
setHasCustomStyleResolveCallbacks();
@@ -64,14 +52,14 @@ HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document& docum
form->registerImgElement(this);
}
-Ref<HTMLImageElement> HTMLImageElement::create(Document& document)
+PassRefPtr<HTMLImageElement> HTMLImageElement::create(Document& document)
{
- return adoptRef(*new HTMLImageElement(imgTag, document));
+ return adoptRef(new HTMLImageElement(imgTag, document));
}
-Ref<HTMLImageElement> HTMLImageElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
+PassRefPtr<HTMLImageElement> HTMLImageElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
{
- return adoptRef(*new HTMLImageElement(tagName, document, form));
+ return adoptRef(new HTMLImageElement(tagName, document, form));
}
HTMLImageElement::~HTMLImageElement()
@@ -80,14 +68,14 @@ HTMLImageElement::~HTMLImageElement()
m_form->removeImgElement(this);
}
-Ref<HTMLImageElement> HTMLImageElement::createForJSConstructor(Document& document, const int* optionalWidth, const int* optionalHeight)
+PassRefPtr<HTMLImageElement> HTMLImageElement::createForJSConstructor(Document& document, const int* optionalWidth, const int* optionalHeight)
{
- Ref<HTMLImageElement> image = adoptRef(*new HTMLImageElement(imgTag, document));
+ RefPtr<HTMLImageElement> image = adoptRef(new HTMLImageElement(imgTag, document));
if (optionalWidth)
image->setWidth(*optionalWidth);
if (optionalHeight)
image->setHeight(*optionalHeight);
- return image;
+ return image.release();
}
bool HTMLImageElement::isPresentationAttribute(const QualifiedName& name) const
@@ -124,29 +112,17 @@ const AtomicString& HTMLImageElement::imageSourceURL() const
return m_bestFitImageURL.isEmpty() ? fastGetAttribute(srcAttr) : m_bestFitImageURL;
}
-void HTMLImageElement::setBestFitURLAndDPRFromImageCandidate(const ImageCandidate& candidate)
-{
- m_bestFitImageURL = candidate.string.toString();
-#if ENABLE(PICTURE_SIZES)
- m_currentSrc = AtomicString(document().completeURL(imageSourceURL()).string());
-#endif
- if (candidate.density >= 0)
- m_imageDevicePixelRatio = 1 / candidate.density;
- if (is<RenderImage>(renderer()))
- downcast<RenderImage>(*renderer()).setImageDevicePixelRatio(m_imageDevicePixelRatio);
-}
-
void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == altAttr) {
- if (is<RenderImage>(renderer()))
- downcast<RenderImage>(*renderer()).updateAltText();
+ if (renderer() && renderer()->isRenderImage())
+ toRenderImage(renderer())->updateAltText();
} else if (name == srcAttr || name == srcsetAttr) {
- float sourceSize = parseSizesAttribute(fastGetAttribute(sizesAttr).string(), document().renderView(), document().frame());
- ImageCandidate candidate = bestFitSourceForImageAttributes(document().deviceScaleFactor(), fastGetAttribute(srcAttr), fastGetAttribute(srcsetAttr), sourceSize);
- setBestFitURLAndDPRFromImageCandidate(candidate);
+ m_bestFitImageURL = bestFitSourceForImageAttributes(document().deviceScaleFactor(), fastGetAttribute(srcAttr), fastGetAttribute(srcsetAttr));
m_imageLoader.updateFromElementIgnoringPreviousError();
} else if (name == usemapAttr) {
+ setIsLink(!value.isNull() && !shouldProhibitLinks(this));
+
if (inDocument() && !m_lowercasedUsemap.isNull())
document().removeImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);
@@ -161,53 +137,49 @@ void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr
if (inDocument() && !m_lowercasedUsemap.isNull())
document().addImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);
- } else if (name == compositeAttr) {
+ } else if (name == onbeforeloadAttr)
+ setAttributeEventListener(eventNames().beforeloadEvent, name, value);
+ else if (name == compositeAttr) {
// FIXME: images don't support blend modes in their compositing attribute.
BlendMode blendOp = BlendModeNormal;
if (!parseCompositeAndBlendOperator(value, m_compositeOperator, blendOp))
m_compositeOperator = CompositeSourceOver;
-#if ENABLE(SERVICE_CONTROLS)
- } else if (name == webkitimagemenuAttr) {
- m_experimentalImageMenuEnabled = !value.isNull();
- updateImageControls();
-#endif
} else {
if (name == nameAttr) {
bool willHaveName = !value.isNull();
- if (m_hadNameBeforeAttributeChanged != willHaveName && inDocument() && is<HTMLDocument>(document())) {
- HTMLDocument& document = downcast<HTMLDocument>(this->document());
+ if (hasName() != willHaveName && inDocument() && document().isHTMLDocument()) {
+ HTMLDocument* document = toHTMLDocument(&this->document());
const AtomicString& id = getIdAttribute();
if (!id.isEmpty() && id != getNameAttribute()) {
if (willHaveName)
- document.addDocumentNamedItem(*id.impl(), *this);
+ document->addDocumentNamedItem(*id.impl(), *this);
else
- document.removeDocumentNamedItem(*id.impl(), *this);
+ document->removeDocumentNamedItem(*id.impl(), *this);
}
}
- m_hadNameBeforeAttributeChanged = willHaveName;
}
HTMLElement::parseAttribute(name, value);
}
}
-const AtomicString& HTMLImageElement::altText() const
+String HTMLImageElement::altText() const
{
// lets figure out the alt text.. magic stuff
// http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
// also heavily discussed by Hixie on bugzilla
- const AtomicString& alt = fastGetAttribute(altAttr);
- if (!alt.isNull())
- return alt;
+ String alt = getAttribute(altAttr);
// fall back to title attribute
- return fastGetAttribute(titleAttr);
+ if (alt.isNull())
+ alt = getAttribute(titleAttr);
+ return alt;
}
-RenderPtr<RenderElement> HTMLImageElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLImageElement::createElementRenderer(PassRef<RenderStyle> style)
{
if (style.get().hasContent())
- return RenderElement::createFor(*this, WTF::move(style));
+ return RenderElement::createFor(*this, std::move(style));
- return createRenderer<RenderImage>(*this, WTF::move(style), nullptr, m_imageDevicePixelRatio);
+ return createRenderer<RenderImage>(*this, std::move(style));
}
bool HTMLImageElement::canStartSelection() const
@@ -220,17 +192,12 @@ bool HTMLImageElement::canStartSelection() const
void HTMLImageElement::didAttachRenderers()
{
- if (!is<RenderImage>(renderer()))
+ if (!renderer() || !renderer()->isRenderImage())
return;
if (m_imageLoader.hasPendingBeforeLoadEvent())
return;
-
-#if ENABLE(SERVICE_CONTROLS)
- updateImageControls();
-#endif
-
- auto& renderImage = downcast<RenderImage>(*renderer());
- RenderImageResource& renderImageResource = renderImage.imageResource();
+ RenderImage* renderImage = toRenderImage(renderer());
+ RenderImageResource& renderImageResource = renderImage->imageResource();
if (renderImageResource.hasImage())
return;
renderImageResource.setCachedImage(m_imageLoader.image());
@@ -238,7 +205,7 @@ void HTMLImageElement::didAttachRenderers()
// If we have no image at all because we have no src attribute, set
// image height and width for the alt text instead.
if (!m_imageLoader.image() && !renderImageResource.cachedImage())
- renderImage.setImageSizeForAltText();
+ renderImage->setImageSizeForAltText();
}
Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode& insertionPoint)
@@ -296,7 +263,7 @@ int HTMLImageElement::width(bool ignorePendingStylesheets)
document().updateLayout();
RenderBox* box = renderBox();
- return box ? adjustForAbsoluteZoom(box->contentBoxRect().pixelSnappedSize().width(), *box) : 0;
+ return box ? adjustForAbsoluteZoom(box->contentBoxRect().pixelSnappedWidth(), *box) : 0;
}
int HTMLImageElement::height(bool ignorePendingStylesheets)
@@ -319,7 +286,7 @@ int HTMLImageElement::height(bool ignorePendingStylesheets)
document().updateLayout();
RenderBox* box = renderBox();
- return box ? adjustForAbsoluteZoom(box->contentBoxRect().pixelSnappedSize().height(), *box) : 0;
+ return box ? adjustForAbsoluteZoom(box->contentBoxRect().pixelSnappedHeight(), *box) : 0;
}
int HTMLImageElement::naturalWidth() const
@@ -347,37 +314,6 @@ bool HTMLImageElement::isURLAttribute(const Attribute& attribute) const
|| HTMLElement::isURLAttribute(attribute);
}
-bool HTMLImageElement::attributeContainsURL(const Attribute& attribute) const
-{
- return attribute.name() == srcsetAttr
- || HTMLElement::attributeContainsURL(attribute);
-}
-
-String HTMLImageElement::completeURLsInAttributeValue(const URL& base, const Attribute& attribute) const
-{
- if (attribute.name() == srcsetAttr) {
- Vector<ImageCandidate> imageCandidates = parseImageCandidatesFromSrcsetAttribute(StringView(attribute.value()));
- StringBuilder result;
- for (const auto& candidate : imageCandidates) {
- if (&candidate != &imageCandidates[0])
- result.appendLiteral(", ");
- result.append(URL(base, candidate.string.toString()).string());
- if (candidate.density != UninitializedDescriptor) {
- result.append(' ');
- result.appendNumber(candidate.density);
- result.append('x');
- }
- if (candidate.resourceWidth != UninitializedDescriptor) {
- result.append(' ');
- result.appendNumber(candidate.resourceWidth);
- result.append('x');
- }
- }
- return result.toString();
- }
- return HTMLElement::completeURLsInAttributeValue(base, attribute);
-}
-
bool HTMLImageElement::matchesLowercasedUsemap(const AtomicStringImpl& name) const
{
ASSERT(String(&const_cast<AtomicStringImpl&>(name)).lower().impl() == &name);
@@ -386,13 +322,13 @@ bool HTMLImageElement::matchesLowercasedUsemap(const AtomicStringImpl& name) con
const AtomicString& HTMLImageElement::alt() const
{
- return fastGetAttribute(altAttr);
+ return getAttribute(altAttr);
}
bool HTMLImageElement::draggable() const
{
// Image elements are draggable by default.
- return !equalIgnoringCase(fastGetAttribute(draggableAttr), "false");
+ return !equalIgnoringCase(getAttribute(draggableAttr), "false");
}
void HTMLImageElement::setHeight(int value)
@@ -402,7 +338,7 @@ void HTMLImageElement::setHeight(int value)
URL HTMLImageElement::src() const
{
- return document().completeURL(fastGetAttribute(srcAttr));
+ return document().completeURL(getAttribute(srcAttr));
}
void HTMLImageElement::setSrc(const String& value)
@@ -417,7 +353,6 @@ void HTMLImageElement::setWidth(int value)
int HTMLImageElement::x() const
{
- document().updateLayoutIgnorePendingStylesheets();
auto renderer = this->renderer();
if (!renderer)
return 0;
@@ -428,7 +363,6 @@ int HTMLImageElement::x() const
int HTMLImageElement::y() const
{
- document().updateLayoutIgnorePendingStylesheets();
auto renderer = this->renderer();
if (!renderer)
return 0;
@@ -448,7 +382,7 @@ void HTMLImageElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
addSubresourceURL(urls, src());
// FIXME: What about when the usemap attribute begins with "#"?
- addSubresourceURL(urls, document().completeURL(fastGetAttribute(usemapAttr)));
+ addSubresourceURL(urls, document().completeURL(getAttribute(usemapAttr)));
}
void HTMLImageElement::didMoveToNewDocument(Document* oldDocument)
@@ -471,77 +405,6 @@ bool HTMLImageElement::isServerMap() const
return document().completeURL(stripLeadingAndTrailingHTMLSpaces(usemap)).isEmpty();
}
-#if ENABLE(SERVICE_CONTROLS)
-void HTMLImageElement::updateImageControls()
-{
- // If this image element is inside a shadow tree then it is part of an image control.
- if (isInShadowTree())
- return;
-
- Settings* settings = document().settings();
- if (!settings || !settings->imageControlsEnabled())
- return;
-
- bool hasControls = hasImageControls();
- if (!m_experimentalImageMenuEnabled && hasControls)
- destroyImageControls();
- else if (m_experimentalImageMenuEnabled && !hasControls)
- createImageControls();
-}
-
-void HTMLImageElement::createImageControls()
-{
- ASSERT(m_experimentalImageMenuEnabled);
- ASSERT(!hasImageControls());
-
- RefPtr<ImageControlsRootElement> imageControls = ImageControlsRootElement::maybeCreate(document());
- if (!imageControls)
- return;
-
- ensureUserAgentShadowRoot().appendChild(imageControls);
-
- auto* renderObject = renderer();
- if (!renderObject)
- return;
-
- downcast<RenderImage>(*renderObject).setHasShadowControls(true);
-}
-
-void HTMLImageElement::destroyImageControls()
-{
- ShadowRoot* shadowRoot = userAgentShadowRoot();
- if (!shadowRoot)
- return;
-
- if (Node* node = shadowRoot->firstChild()) {
- ASSERT_WITH_SECURITY_IMPLICATION(node->isImageControlsRootElement());
- shadowRoot->removeChild(node);
- }
-
- auto* renderObject = renderer();
- if (!renderObject)
- return;
-
- downcast<RenderImage>(*renderObject).setHasShadowControls(false);
-}
-
-bool HTMLImageElement::hasImageControls() const
-{
- if (ShadowRoot* shadowRoot = userAgentShadowRoot()) {
- Node* node = shadowRoot->firstChild();
- ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isImageControlsRootElement());
- return node;
- }
-
- return false;
-}
-
-bool HTMLImageElement::childShouldCreateRenderer(const Node& child) const
-{
- return hasShadowRootParent(child) && HTMLElement::childShouldCreateRenderer(child);
-}
-#endif // ENABLE(SERVICE_CONTROLS)
-
#if PLATFORM(IOS)
// FIXME: This is a workaround for <rdar://problem/7725158>. We should find a better place for the touchCalloutEnabled() logic.
bool HTMLImageElement::willRespondToMouseClickEvents()
diff --git a/Source/WebCore/html/HTMLImageElement.h b/Source/WebCore/html/HTMLImageElement.h
index 24533468b..d8689d156 100644
--- a/Source/WebCore/html/HTMLImageElement.h
+++ b/Source/WebCore/html/HTMLImageElement.h
@@ -32,14 +32,13 @@
namespace WebCore {
class HTMLFormElement;
-struct ImageCandidate;
class HTMLImageElement : public HTMLElement, public FormNamedItem {
friend class HTMLFormElement;
public:
- static Ref<HTMLImageElement> create(Document&);
- static Ref<HTMLImageElement> create(const QualifiedName&, Document&, HTMLFormElement*);
- static Ref<HTMLImageElement> createForJSConstructor(Document&, const int* optionalWidth, const int* optionalHeight);
+ static PassRefPtr<HTMLImageElement> create(Document&);
+ static PassRefPtr<HTMLImageElement> create(const QualifiedName&, Document&, HTMLFormElement*);
+ static PassRefPtr<HTMLImageElement> createForJSConstructor(Document&, const int* optionalWidth, const int* optionalHeight);
virtual ~HTMLImageElement();
@@ -48,17 +47,15 @@ public:
int naturalWidth() const;
int naturalHeight() const;
-#if ENABLE(PICTURE_SIZES)
- const AtomicString& currentSrc() const { return m_currentSrc; }
-#endif
bool isServerMap() const;
- const AtomicString& altText() const;
+ String altText() const;
CompositeOperator compositeOperator() const { return m_compositeOperator; }
CachedImage* cachedImage() const { return m_imageLoader.image(); }
+ void setCachedImage(CachedImage* i) { m_imageLoader.setImage(i); };
void setLoadManually(bool loadManually) { m_imageLoader.setLoadManually(loadManually); }
@@ -88,27 +85,24 @@ public:
virtual const AtomicString& imageSourceURL() const override;
- bool hasShadowControls() const { return m_experimentalImageMenuEnabled; }
-
protected:
HTMLImageElement(const QualifiedName&, Document&, HTMLFormElement* = 0);
virtual void didMoveToNewDocument(Document* oldDocument) override;
private:
+ virtual bool areAuthorShadowsAllowed() const override { return false; }
+
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
virtual bool isPresentationAttribute(const QualifiedName&) const override;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
virtual void didAttachRenderers() override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
- void setBestFitURLAndDPRFromImageCandidate(const ImageCandidate&);
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual bool canStartSelection() const override;
virtual bool isURLAttribute(const Attribute&) const override;
- virtual bool attributeContainsURL(const Attribute&) const override;
- virtual String completeURLsInAttributeValue(const URL& base, const Attribute&) const override;
virtual bool draggable() const override;
@@ -126,23 +120,11 @@ private:
HTMLFormElement* m_form;
CompositeOperator m_compositeOperator;
AtomicString m_bestFitImageURL;
-#if ENABLE(PICTURE_SIZES)
- AtomicString m_currentSrc;
-#endif
AtomicString m_lowercasedUsemap;
- float m_imageDevicePixelRatio;
- bool m_experimentalImageMenuEnabled;
- bool m_hadNameBeforeAttributeChanged { false }; // FIXME: We only need this because parseAttribute() can't see the old value.
-
-#if ENABLE(SERVICE_CONTROLS)
- void updateImageControls();
- void createImageControls();
- void destroyImageControls();
- bool hasImageControls() const;
- virtual bool childShouldCreateRenderer(const Node&) const override;
-#endif
};
+NODE_TYPE_CASTS(HTMLImageElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLImageElement.idl b/Source/WebCore/html/HTMLImageElement.idl
index 4609146a1..8c551f87b 100644
--- a/Source/WebCore/html/HTMLImageElement.idl
+++ b/Source/WebCore/html/HTMLImageElement.idl
@@ -32,14 +32,10 @@
[Reflect, URL] attribute DOMString longDesc;
[Reflect, URL] attribute DOMString src;
[Reflect] attribute DOMString srcset;
-#if ENABLE_PICTURE_SIZES
- [Reflect] attribute DOMString sizes;
- readonly attribute DOMString currentSrc;
-#endif
[Reflect] attribute DOMString useMap;
[Reflect] attribute long vspace;
attribute long width;
-
+
// Extensions
readonly attribute boolean complete;
[Reflect,URL] attribute DOMString lowsrc;
diff --git a/Source/WebCore/html/HTMLImageLoader.cpp b/Source/WebCore/html/HTMLImageLoader.cpp
index 3e5f81c52..4743dcb22 100644
--- a/Source/WebCore/html/HTMLImageLoader.cpp
+++ b/Source/WebCore/html/HTMLImageLoader.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2010, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,24 +23,22 @@
#include "HTMLImageLoader.h"
#include "CachedImage.h"
-#include "DOMWindow.h"
#include "Element.h"
#include "Event.h"
#include "EventNames.h"
#include "HTMLNames.h"
#include "HTMLObjectElement.h"
#include "HTMLParserIdioms.h"
-#include "HTMLVideoElement.h"
#include "Settings.h"
#include "JSDOMWindowBase.h"
-#include <runtime/JSCInlines.h>
#include <runtime/JSLock.h>
+#include <runtime/Operations.h>
namespace WebCore {
-HTMLImageLoader::HTMLImageLoader(Element& element)
- : ImageLoader(element)
+HTMLImageLoader::HTMLImageLoader(Element* node)
+ : ImageLoader(node)
{
}
@@ -50,22 +48,20 @@ HTMLImageLoader::~HTMLImageLoader()
void HTMLImageLoader::dispatchLoadEvent()
{
-#if ENABLE(VIDEO)
// HTMLVideoElement uses this class to load the poster image, but it should not fire events for loading or failure.
- if (is<HTMLVideoElement>(element()))
+ if (isHTMLVideoElement(element()))
return;
-#endif
bool errorOccurred = image()->errorOccurred();
if (!errorOccurred && image()->response().httpStatusCode() >= 400)
- errorOccurred = is<HTMLObjectElement>(element()); // An <object> considers a 404 to be an error and should fire onerror.
- element().dispatchEvent(Event::create(errorOccurred ? eventNames().errorEvent : eventNames().loadEvent, false, false));
+ errorOccurred = isHTMLObjectElement(element()); // An <object> considers a 404 to be an error and should fire onerror.
+ element()->dispatchEvent(Event::create(errorOccurred ? eventNames().errorEvent : eventNames().loadEvent, false, false));
}
String HTMLImageLoader::sourceURI(const AtomicString& attr) const
{
#if ENABLE(DASHBOARD_SUPPORT)
- Settings* settings = element().document().settings();
+ Settings* settings = element()->document().settings();
if (settings && settings->usesDashboardBackwardCompatibilityMode() && attr.length() > 7 && attr.startsWith("url(\"") && attr.endsWith("\")"))
return attr.string().substring(5, attr.length() - 7);
#endif
@@ -77,22 +73,20 @@ void HTMLImageLoader::notifyFinished(CachedResource*)
{
CachedImage* cachedImage = image();
- Ref<Element> protect(element());
+ RefPtr<Element> element = this->element();
ImageLoader::notifyFinished(cachedImage);
bool loadError = cachedImage->errorOccurred() || cachedImage->response().httpStatusCode() >= 400;
if (!loadError) {
- if (!element().inDocument()) {
- JSC::VM& vm = JSDOMWindowBase::commonVM();
+ if (!element->inDocument()) {
+ JSC::VM* vm = JSDOMWindowBase::commonVM();
JSC::JSLockHolder lock(vm);
- // FIXME: Adopt reportExtraMemoryVisited, and switch to reportExtraMemoryAllocated.
- // https://bugs.webkit.org/show_bug.cgi?id=142595
- vm.heap.deprecatedReportExtraMemory(cachedImage->encodedSize());
+ vm->heap.reportExtraMemoryCost(cachedImage->encodedSize());
}
}
- if (loadError && is<HTMLObjectElement>(element()))
- downcast<HTMLObjectElement>(element()).renderFallbackContent();
+ if (loadError && isHTMLObjectElement(element.get()))
+ toHTMLObjectElement(element.get())->renderFallbackContent();
}
}
diff --git a/Source/WebCore/html/HTMLImageLoader.h b/Source/WebCore/html/HTMLImageLoader.h
index e9bf1c2e3..14ea2bc3a 100644
--- a/Source/WebCore/html/HTMLImageLoader.h
+++ b/Source/WebCore/html/HTMLImageLoader.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004 Apple Inc.
+ * Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -27,9 +27,9 @@
namespace WebCore {
-class HTMLImageLoader final : public ImageLoader {
+class HTMLImageLoader : public ImageLoader {
public:
- explicit HTMLImageLoader(Element&);
+ HTMLImageLoader(Element*);
virtual ~HTMLImageLoader();
virtual void dispatchLoadEvent() override;
diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp
index 3642a9ab6..99219f997 100644
--- a/Source/WebCore/html/HTMLInputElement.cpp
+++ b/Source/WebCore/html/HTMLInputElement.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
* Copyright (C) 2010 Google Inc. All rights reserved.
@@ -69,6 +69,10 @@
#include "ColorInputType.h"
#endif
+#if ENABLE(INPUT_SPEECH)
+#include "RuntimeEnabledFeatures.h"
+#endif
+
#if ENABLE(TOUCH_EVENTS)
#include "TouchEvent.h"
#endif
@@ -81,11 +85,12 @@ using namespace HTMLNames;
class ListAttributeTargetObserver : IdTargetObserver {
WTF_MAKE_FAST_ALLOCATED;
public:
- ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement*);
-
+ static OwnPtr<ListAttributeTargetObserver> create(const AtomicString& id, HTMLInputElement*);
virtual void idTargetChanged() override;
private:
+ ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement*);
+
HTMLInputElement* m_element;
};
#endif
@@ -109,8 +114,7 @@ HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document& docum
, m_hasType(false)
, m_isActivatedSubmit(false)
, m_autocomplete(Uninitialized)
- , m_isAutoFilled(false)
- , m_showAutoFillButton(false)
+ , m_isAutofilled(false)
#if ENABLE(DATALIST_ELEMENT)
, m_hasNonEmptyList(false)
#endif
@@ -122,34 +126,29 @@ HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document& docum
#if ENABLE(TOUCH_EVENTS)
, m_hasTouchEventHandler(false)
#endif
- // m_inputType is lazily created when constructed by the parser to avoid constructing unnecessarily a text inputType and
- // its shadow subtree, just to destroy them when the |type| attribute gets set by the parser to something else than 'text'.
- , m_inputType(createdByParser ? nullptr : InputType::createText(*this))
+ , m_inputType(InputType::createText(*this))
{
ASSERT(hasTagName(inputTag) || hasTagName(isindexTag));
setHasCustomStyleResolveCallbacks();
}
-Ref<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form, bool createdByParser)
+PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form, bool createdByParser)
{
- bool shouldCreateShadowRootLazily = createdByParser;
- Ref<HTMLInputElement> inputElement = adoptRef(*new HTMLInputElement(tagName, document, form, createdByParser));
- if (!shouldCreateShadowRootLazily)
- inputElement->ensureUserAgentShadowRoot();
- return inputElement;
+ RefPtr<HTMLInputElement> inputElement = adoptRef(new HTMLInputElement(tagName, document, form, createdByParser));
+ inputElement->ensureUserAgentShadowRoot();
+ return inputElement.release();
}
-HTMLImageLoader& HTMLInputElement::ensureImageLoader()
+HTMLImageLoader* HTMLInputElement::imageLoader()
{
if (!m_imageLoader)
- m_imageLoader = std::make_unique<HTMLImageLoader>(*this);
- return *m_imageLoader;
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ return m_imageLoader.get();
}
void HTMLInputElement::didAddUserAgentShadowRoot(ShadowRoot*)
{
m_inputType->createShadowSubtree();
- updateInnerTextElementEditability();
}
HTMLInputElement::~HTMLInputElement()
@@ -166,7 +165,7 @@ HTMLInputElement::~HTMLInputElement()
document().formController().checkedRadioButtons().removeButton(this);
#if ENABLE(TOUCH_EVENTS)
if (m_hasTouchEventHandler)
- document().didRemoveEventTargetNode(*this);
+ document().didRemoveEventTargetNode(this);
#endif
}
@@ -200,16 +199,6 @@ HTMLElement* HTMLInputElement::innerSpinButtonElement() const
return m_inputType->innerSpinButtonElement();
}
-HTMLElement* HTMLInputElement::capsLockIndicatorElement() const
-{
- return m_inputType->capsLockIndicatorElement();
-}
-
-HTMLElement* HTMLInputElement::autoFillButtonElement() const
-{
- return m_inputType->autoFillButtonElement();
-}
-
HTMLElement* HTMLInputElement::resultsButtonElement() const
{
return m_inputType->resultsButtonElement();
@@ -220,6 +209,13 @@ HTMLElement* HTMLInputElement::cancelButtonElement() const
return m_inputType->cancelButtonElement();
}
+#if ENABLE(INPUT_SPEECH)
+HTMLElement* HTMLInputElement::speechButtonElement() const
+{
+ return m_inputType->speechButtonElement();
+}
+#endif
+
HTMLElement* HTMLInputElement::sliderThumbElement() const
{
return m_inputType->sliderThumbElement();
@@ -407,7 +403,7 @@ void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
{
if (isTextField()) {
if (!restorePreviousSelection || !hasCachedSelection())
- select(Element::defaultFocusTextStateChangeIntent());
+ select();
else
restoreCachedSelection();
if (document().frame())
@@ -440,14 +436,20 @@ void HTMLInputElement::handleBlurEvent()
m_inputType->handleBlurEvent();
}
-void HTMLInputElement::setType(const AtomicString& type)
+void HTMLInputElement::setType(const String& type)
{
- setAttribute(typeAttr, type);
+ // FIXME: This should just call setAttribute. No reason to handle the empty string specially.
+ // We should write a test case to show that setting to the empty string does not remove the
+ // attribute in other browsers and then fix this. Note that setting to null *does* remove
+ // the attribute and setAttribute implements that.
+ if (type.isEmpty())
+ removeAttribute(typeAttr);
+ else
+ setAttribute(typeAttr, type);
}
void HTMLInputElement::updateType()
{
- ASSERT(m_inputType);
auto newType = InputType::create(*this, fastGetAttribute(typeAttr));
bool hadType = m_hasType;
m_hasType = true;
@@ -469,9 +471,19 @@ void HTMLInputElement::updateType()
m_inputType->destroyShadowSubtree();
- m_inputType = WTF::move(newType);
+ m_inputType = std::move(newType);
m_inputType->createShadowSubtree();
- updateInnerTextElementEditability();
+
+#if ENABLE(TOUCH_EVENTS)
+ bool hasTouchEventHandler = m_inputType->hasTouchEventHandler();
+ if (hasTouchEventHandler != m_hasTouchEventHandler) {
+ if (hasTouchEventHandler)
+ document().didAddTouchEventHandler(this);
+ else
+ document().didRemoveTouchEventHandler(this);
+ m_hasTouchEventHandler = hasTouchEventHandler;
+ }
+#endif
setNeedsWillValidateCheck();
@@ -499,32 +511,14 @@ void HTMLInputElement::updateType()
if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
ASSERT(elementData());
- // FIXME: We don't have the old attribute values so we pretend that we didn't have the old values.
if (const Attribute* height = findAttributeByName(heightAttr))
- attributeChanged(heightAttr, nullAtom, height->value());
+ attributeChanged(heightAttr, height->value());
if (const Attribute* width = findAttributeByName(widthAttr))
- attributeChanged(widthAttr, nullAtom, width->value());
+ attributeChanged(widthAttr, width->value());
if (const Attribute* align = findAttributeByName(alignAttr))
- attributeChanged(alignAttr, nullAtom, align->value());
+ attributeChanged(alignAttr, align->value());
}
- runPostTypeUpdateTasks();
-}
-
-inline void HTMLInputElement::runPostTypeUpdateTasks()
-{
- ASSERT(m_inputType);
-#if ENABLE(TOUCH_EVENTS)
- bool hasTouchEventHandler = m_inputType->hasTouchEventHandler();
- if (hasTouchEventHandler != m_hasTouchEventHandler) {
- if (hasTouchEventHandler)
- document().didAddTouchEventHandler(*this);
- else
- document().didRemoveTouchEventHandler(*this);
- m_hasTouchEventHandler = hasTouchEventHandler;
- }
-#endif
-
if (renderer())
setNeedsStyleRecalc(ReconstructRenderTree);
@@ -538,7 +532,8 @@ inline void HTMLInputElement::runPostTypeUpdateTasks()
addToRadioButtonGroup();
- updateValidity();
+ setNeedsValidityCheck();
+ notifyFormStateChanged();
}
void HTMLInputElement::subtreeHasChanged()
@@ -618,31 +613,8 @@ void HTMLInputElement::collectStyleForPresentationAttribute(const QualifiedName&
HTMLTextFormControlElement::collectStyleForPresentationAttribute(name, value, style);
}
-inline void HTMLInputElement::initializeInputType()
-{
- ASSERT(m_parsingInProgress);
- ASSERT(!m_inputType);
-
- const AtomicString& type = fastGetAttribute(typeAttr);
- if (type.isNull()) {
- m_inputType = InputType::createText(*this);
- ensureUserAgentShadowRoot();
- setNeedsWillValidateCheck();
- return;
- }
-
- m_hasType = true;
- m_inputType = InputType::create(*this, type);
- ensureUserAgentShadowRoot();
- setNeedsWillValidateCheck();
- registerForSuspensionCallbackIfNeeded();
- runPostTypeUpdateTasks();
-}
-
void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- ASSERT(m_inputType);
-
if (name == nameAttr) {
removeFromRadioButtonGroup();
m_name = value;
@@ -674,12 +646,13 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
}
// We only need to setChanged if the form is looking at the default value right now.
if (!hasDirtyValue()) {
- updatePlaceholderVisibility();
+ updatePlaceholderVisibility(false);
setNeedsStyleRecalc();
}
setFormControlValueMatchesRenderer(false);
- updateValidity();
+ setNeedsValidityCheck();
m_valueAttributeWasUpdatedAfterParsing = !m_parsingInProgress;
+ m_inputType->valueAttributeChanged();
} else if (name == checkedAttr) {
// Another radio button in the same group might be checked by state
// restore. We shouldn't call setChecked() even if this has the checked
@@ -703,29 +676,45 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
m_inputType->srcAttributeChanged();
else if (name == usemapAttr || name == accesskeyAttr) {
// FIXME: ignore for the moment
+ } else if (name == onsearchAttr) {
+ // Search field and slider attributes all just cause updateFromElement to be called through style recalcing.
+ setAttributeEventListener(eventNames().searchEvent, name, value);
} else if (name == resultsAttr) {
+ int oldResults = m_maxResults;
m_maxResults = !value.isNull() ? std::min(value.toInt(), maxSavedResults) : -1;
- m_inputType->maxResultsAttributeChanged();
+
+ if (m_maxResults != oldResults && (m_maxResults <= 0 || oldResults <= 0))
+ setNeedsStyleRecalc(ReconstructRenderTree);
+ else
+ setNeedsStyleRecalc();
+ FeatureObserver::observe(&document(), FeatureObserver::ResultsAttribute);
} else if (name == autosaveAttr) {
setNeedsStyleRecalc();
+ FeatureObserver::observe(&document(), FeatureObserver::AutoSaveAttribute);
} else if (name == incrementalAttr) {
setNeedsStyleRecalc();
+ FeatureObserver::observe(&document(), FeatureObserver::IncrementalAttribute);
} else if (name == minAttr) {
m_inputType->minOrMaxAttributeChanged();
- updateValidity();
+ setNeedsValidityCheck();
+ FeatureObserver::observe(&document(), FeatureObserver::MinAttribute);
} else if (name == maxAttr) {
m_inputType->minOrMaxAttributeChanged();
- updateValidity();
+ setNeedsValidityCheck();
+ FeatureObserver::observe(&document(), FeatureObserver::MaxAttribute);
} else if (name == multipleAttr) {
m_inputType->multipleAttributeChanged();
- updateValidity();
+ setNeedsValidityCheck();
} else if (name == stepAttr) {
m_inputType->stepAttributeChanged();
- updateValidity();
+ setNeedsValidityCheck();
+ FeatureObserver::observe(&document(), FeatureObserver::StepAttribute);
} else if (name == patternAttr) {
- updateValidity();
+ setNeedsValidityCheck();
+ FeatureObserver::observe(&document(), FeatureObserver::PatternAttribute);
} else if (name == precisionAttr) {
- updateValidity();
+ setNeedsValidityCheck();
+ FeatureObserver::observe(&document(), FeatureObserver::PrecisionAttribute);
} else if (name == disabledAttr) {
HTMLTextFormControlElement::parseAttribute(name, value);
m_inputType->disabledAttributeChanged();
@@ -740,6 +729,28 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
resetListAttributeTargetObserver();
listAttributeTargetChanged();
}
+ FeatureObserver::observe(&document(), FeatureObserver::ListAttribute);
+ }
+#endif
+#if ENABLE(INPUT_SPEECH)
+ else if (name == webkitspeechAttr) {
+ m_inputType->destroyShadowSubtree();
+ m_inputType->createShadowSubtree();
+
+ // This renderer and its children have quite different layouts and styles depending on
+ // whether the speech button is visible or not. So we reset the whole thing and recreate
+ // to get the right styles and layout.
+ setNeedsStyleRecalc(ReconstructRenderTree);
+
+ setFormControlValueMatchesRenderer(false);
+ FeatureObserver::observe(&document(), FeatureObserver::PrefixedSpeechAttribute);
+ } else if (name == onwebkitspeechchangeAttr)
+ setAttributeEventListener(eventNames().webkitspeechchangeEvent, name, value);
+#endif
+#if ENABLE(DIRECTORY_UPLOAD)
+ else if (name == webkitdirectoryAttr) {
+ HTMLTextFormControlElement::parseAttribute(name, value);
+ FeatureObserver::observe(&document(), FeatureObserver::PrefixedDirectoryAttribute);
}
#endif
else
@@ -747,19 +758,12 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
m_inputType->attributeChanged();
}
-void HTMLInputElement::parserDidSetAttributes()
-{
- ASSERT(m_parsingInProgress);
- initializeInputType();
-}
-
void HTMLInputElement::finishParsingChildren()
{
m_parsingInProgress = false;
- ASSERT(m_inputType);
HTMLTextFormControlElement::finishParsingChildren();
if (!m_stateRestored) {
- bool checked = fastHasAttribute(checkedAttr);
+ bool checked = hasAttribute(checkedAttr);
if (checked)
setChecked(checked);
m_reflectsCheckedAttribute = true;
@@ -771,9 +775,9 @@ bool HTMLInputElement::rendererIsNeeded(const RenderStyle& style)
return m_inputType->rendererIsNeeded() && HTMLTextFormControlElement::rendererIsNeeded(style);
}
-RenderPtr<RenderElement> HTMLInputElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLInputElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return m_inputType->createInputRenderer(WTF::move(style));
+ return m_inputType->createInputRenderer(std::move(style));
}
void HTMLInputElement::willAttachRenderers()
@@ -808,7 +812,7 @@ String HTMLInputElement::altText() const
if (alt.isNull())
alt = getAttribute(titleAttr);
if (alt.isNull())
- alt = fastGetAttribute(valueAttr);
+ alt = getAttribute(valueAttr);
if (alt.isEmpty())
alt = inputElementAltText();
return alt;
@@ -841,8 +845,8 @@ void HTMLInputElement::reset()
if (m_inputType->storesValueSeparateFromAttribute())
setValue(String());
- setAutoFilled(false);
- setChecked(fastHasAttribute(checkedAttr));
+ setAutofilled(false);
+ setChecked(hasAttribute(checkedAttr));
m_reflectsCheckedAttribute = true;
}
@@ -868,8 +872,8 @@ void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventB
if (CheckedRadioButtons* buttons = checkedRadioButtons())
buttons->updateCheckedState(this);
if (renderer() && renderer()->style().hasAppearance())
- renderer()->theme().stateChanged(*renderer(), ControlStates::CheckedState);
- updateValidity();
+ renderer()->theme().stateChanged(renderer(), CheckedState);
+ setNeedsValidityCheck();
// Ideally we'd do this from the render tree (matching
// RenderTextView), but it's not possible to do it at the moment
@@ -889,7 +893,7 @@ void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventB
dispatchFormControlChangeEvent();
}
- setNeedsStyleRecalc();
+ didAffectSelector(AffectedSelectorChecked);
}
void HTMLInputElement::setIndeterminate(bool newValue)
@@ -899,10 +903,10 @@ void HTMLInputElement::setIndeterminate(bool newValue)
m_isIndeterminate = newValue;
- setNeedsStyleRecalc();
+ didAffectSelector(AffectedSelectorIndeterminate);
if (renderer() && renderer()->style().hasAppearance())
- renderer()->theme().stateChanged(*renderer(), ControlStates::CheckedState);
+ renderer()->theme().stateChanged(renderer(), CheckedState);
}
int HTMLInputElement::size() const
@@ -969,6 +973,21 @@ void HTMLInputElement::setValueForUser(const String& value)
setValue(value, DispatchChangeEvent);
}
+const String& HTMLInputElement::suggestedValue() const
+{
+ return m_suggestedValue;
+}
+
+void HTMLInputElement::setSuggestedValue(const String& value)
+{
+ if (!m_inputType->canSetSuggestedValue())
+ return;
+ setFormControlValueMatchesRenderer(false);
+ m_suggestedValue = sanitizeValue(value);
+ setNeedsStyleRecalc();
+ m_inputType->updateInnerTextValue();
+}
+
void HTMLInputElement::setEditingValue(const String& value)
{
if (!renderer() || !isTextField())
@@ -1006,14 +1025,20 @@ void HTMLInputElement::setValue(const String& value, TextFieldEventBehavior even
setLastChangeWasNotUserEdit();
setFormControlValueMatchesRenderer(false);
+ m_suggestedValue = String(); // Prevent TextFieldInputType::setValue from using the suggested value.
m_inputType->setValue(sanitizedValue, valueChanged, eventBehavior);
+
+ if (!valueChanged)
+ return;
+
+ notifyFormStateChanged();
}
void HTMLInputElement::setValueInternal(const String& sanitizedValue, TextFieldEventBehavior eventBehavior)
{
m_valueIfDirty = sanitizedValue;
m_wasModifiedByUser = eventBehavior != DispatchNoEvent;
- updateValidity();
+ setNeedsValidityCheck();
}
double HTMLInputElement::valueAsDate() const
@@ -1045,6 +1070,8 @@ void HTMLInputElement::setValueFromRenderer(const String& value)
// File upload controls will never use this.
ASSERT(!isFileUpload());
+ m_suggestedValue = String();
+
// Renderer and our event handler are responsible for sanitizing values.
ASSERT(value == sanitizeValue(value) || sanitizeValue(value).isEmpty());
@@ -1059,18 +1086,19 @@ void HTMLInputElement::setValueFromRenderer(const String& value)
// Input event is fired by the Node::defaultEventHandler for editable controls.
if (!isTextField())
dispatchInputEvent();
+ notifyFormStateChanged();
- updateValidity();
+ setNeedsValidityCheck();
- // Clear auto fill flag (and yellow background) on user edit.
- setAutoFilled(false);
+ // Clear autofill flag (and yellow background) on user edit.
+ setAutofilled(false);
}
void HTMLInputElement::willDispatchEvent(Event& event, InputElementClickState& state)
{
if (event.type() == eventNames().textInputEvent && m_inputType->shouldSubmitImplicitly(&event))
event.stopPropagation();
- if (event.type() == eventNames().clickEvent && is<MouseEvent>(event) && downcast<MouseEvent>(event).button() == LeftButton) {
+ if (event.type() == eventNames().clickEvent && event.isMouseEvent() && toMouseEvent(&event)->button() == LeftButton) {
m_inputType->willDispatchClick(state);
state.stateful = true;
}
@@ -1083,23 +1111,22 @@ void HTMLInputElement::didDispatchClickEvent(Event& event, const InputElementCli
void HTMLInputElement::defaultEventHandler(Event* evt)
{
- ASSERT(evt);
- if (is<MouseEvent>(*evt) && evt->type() == eventNames().clickEvent && downcast<MouseEvent>(*evt).button() == LeftButton) {
- m_inputType->handleClickEvent(downcast<MouseEvent>(evt));
+ if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
+ m_inputType->handleClickEvent(static_cast<MouseEvent*>(evt));
if (evt->defaultHandled())
return;
}
#if ENABLE(TOUCH_EVENTS)
- if (is<TouchEvent>(*evt)) {
- m_inputType->handleTouchEvent(downcast<TouchEvent>(evt));
+ if (evt->isTouchEvent()) {
+ m_inputType->handleTouchEvent(static_cast<TouchEvent*>(evt));
if (evt->defaultHandled())
return;
}
#endif
- if (is<KeyboardEvent>(*evt) && evt->type() == eventNames().keydownEvent) {
- m_inputType->handleKeydownEvent(downcast<KeyboardEvent>(evt));
+ if (evt->isKeyboardEvent() && evt->type() == eventNames().keydownEvent) {
+ m_inputType->handleKeydownEvent(static_cast<KeyboardEvent*>(evt));
if (evt->defaultHandled())
return;
}
@@ -1125,17 +1152,16 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
// Use key press event here since sending simulated mouse events
// on key down blocks the proper sending of the key press event.
- if (is<KeyboardEvent>(*evt)) {
- KeyboardEvent& keyboardEvent = downcast<KeyboardEvent>(*evt);
- if (keyboardEvent.type() == eventNames().keypressEvent) {
- m_inputType->handleKeypressEvent(&keyboardEvent);
- if (keyboardEvent.defaultHandled())
- return;
- } else if (keyboardEvent.type() == eventNames().keyupEvent) {
- m_inputType->handleKeyupEvent(&keyboardEvent);
- if (keyboardEvent.defaultHandled())
- return;
- }
+ if (evt->isKeyboardEvent() && evt->type() == eventNames().keypressEvent) {
+ m_inputType->handleKeypressEvent(static_cast<KeyboardEvent*>(evt));
+ if (evt->defaultHandled())
+ return;
+ }
+
+ if (evt->isKeyboardEvent() && evt->type() == eventNames().keyupEvent) {
+ m_inputType->handleKeyupEvent(static_cast<KeyboardEvent*>(evt));
+ if (evt->defaultHandled())
+ return;
}
if (m_inputType->shouldSubmitImplicitly(evt)) {
@@ -1157,15 +1183,16 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
return;
}
- if (is<BeforeTextInsertedEvent>(*evt))
- m_inputType->handleBeforeTextInsertedEvent(downcast<BeforeTextInsertedEvent>(evt));
+ if (evt->isBeforeTextInsertedEvent())
+ m_inputType->handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(evt));
- if (is<MouseEvent>(*evt) && evt->type() == eventNames().mousedownEvent) {
- m_inputType->handleMouseDownEvent(downcast<MouseEvent>(evt));
+ if (evt->isMouseEvent() && evt->type() == eventNames().mousedownEvent) {
+ m_inputType->handleMouseDownEvent(static_cast<MouseEvent*>(evt));
if (evt->defaultHandled())
return;
}
+ document().updateStyleIfNeeded();
m_inputType->forwardEvent(evt);
if (!callBaseClassEarly && !evt->defaultHandled())
@@ -1295,24 +1322,15 @@ URL HTMLInputElement::src() const
return document().completeURL(fastGetAttribute(srcAttr));
}
-void HTMLInputElement::setAutoFilled(bool autoFilled)
+void HTMLInputElement::setAutofilled(bool autofilled)
{
- if (autoFilled == m_isAutoFilled)
+ if (autofilled == m_isAutofilled)
return;
- m_isAutoFilled = autoFilled;
+ m_isAutofilled = autofilled;
setNeedsStyleRecalc();
}
-void HTMLInputElement::setShowAutoFillButton(bool showAutoFillButton)
-{
- if (showAutoFillButton == m_showAutoFillButton)
- return;
-
- m_showAutoFillButton = showAutoFillButton;
- m_inputType->updateAutoFillButton();
-}
-
FileList* HTMLInputElement::files()
{
return m_inputType->files();
@@ -1417,6 +1435,11 @@ bool HTMLInputElement::isRequiredFormControl() const
return m_inputType->supportsRequired() && isRequired();
}
+bool HTMLInputElement::matchesReadOnlyPseudoClass() const
+{
+ return m_inputType->supportsReadOnly() && isReadOnly();
+}
+
bool HTMLInputElement::matchesReadWritePseudoClass() const
{
return m_inputType->supportsReadOnly() && !isDisabledOrReadOnly();
@@ -1435,6 +1458,11 @@ void HTMLInputElement::onSearch()
dispatchEvent(Event::create(eventNames().searchEvent, true, false));
}
+void HTMLInputElement::updateClearButtonVisibility()
+{
+ m_inputType->updateClearButtonVisibility();
+}
+
void HTMLInputElement::documentDidResumeFromPageCache()
{
ASSERT(needsSuspensionCallback());
@@ -1473,17 +1501,12 @@ void HTMLInputElement::didChangeForm()
Node::InsertionNotificationRequest HTMLInputElement::insertedInto(ContainerNode& insertionPoint)
{
HTMLTextFormControlElement::insertedInto(insertionPoint);
+ if (insertionPoint.inDocument() && !form())
+ addToRadioButtonGroup();
#if ENABLE(DATALIST_ELEMENT)
resetListAttributeTargetObserver();
#endif
- return InsertionShouldCallFinishedInsertingSubtree;
-}
-
-void HTMLInputElement::finishedInsertingSubtree()
-{
- HTMLTextFormControlElement::finishedInsertingSubtree();
- if (inDocument() && !form())
- addToRadioButtonGroup();
+ return InsertionDone;
}
void HTMLInputElement::removedFrom(ContainerNode& insertionPoint)
@@ -1499,7 +1522,7 @@ void HTMLInputElement::removedFrom(ContainerNode& insertionPoint)
void HTMLInputElement::didMoveToNewDocument(Document* oldDocument)
{
- if (imageLoader())
+ if (hasImageLoader())
imageLoader()->elementDidMoveToNewDocument();
bool needsSuspensionCallback = this->needsSuspensionCallback();
@@ -1511,7 +1534,7 @@ void HTMLInputElement::didMoveToNewDocument(Document* oldDocument)
oldDocument->formController().checkedRadioButtons().removeButton(this);
#if ENABLE(TOUCH_EVENTS)
if (m_hasTouchEventHandler)
- oldDocument->didRemoveEventTargetNode(*this);
+ oldDocument->didRemoveEventTargetNode(this);
#endif
}
@@ -1520,7 +1543,7 @@ void HTMLInputElement::didMoveToNewDocument(Document* oldDocument)
#if ENABLE(TOUCH_EVENTS)
if (m_hasTouchEventHandler)
- document().didAddTouchEventHandler(*this);
+ document().didAddTouchEventHandler(this);
#endif
HTMLTextFormControlElement::didMoveToNewDocument(oldDocument);
@@ -1533,9 +1556,9 @@ void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
addSubresourceURL(urls, src());
}
-bool HTMLInputElement::computeWillValidate() const
+bool HTMLInputElement::recalcWillValidate() const
{
- return m_inputType->supportsValidation() && HTMLTextFormControlElement::computeWillValidate();
+ return m_inputType->supportsValidation() && HTMLTextFormControlElement::recalcWillValidate();
}
void HTMLInputElement::requiredAttributeChanged()
@@ -1564,22 +1587,24 @@ HTMLElement* HTMLInputElement::list() const
HTMLDataListElement* HTMLInputElement::dataList() const
{
if (!m_hasNonEmptyList)
- return nullptr;
+ return 0;
if (!m_inputType->shouldRespectListAttribute())
- return nullptr;
+ return 0;
Element* element = treeScope().getElementById(fastGetAttribute(listAttr));
- if (!is<HTMLDataListElement>(element))
- return nullptr;
+ if (!element)
+ return 0;
+ if (!element->hasTagName(datalistTag))
+ return 0;
- return downcast<HTMLDataListElement>(element);
+ return toHTMLDataListElement(element);
}
void HTMLInputElement::resetListAttributeTargetObserver()
{
if (inDocument())
- m_listAttributeTargetObserver = std::make_unique<ListAttributeTargetObserver>(fastGetAttribute(listAttr), this);
+ m_listAttributeTargetObserver = ListAttributeTargetObserver::create(fastGetAttribute(listAttr), this);
else
m_listAttributeTargetObserver = nullptr;
}
@@ -1595,6 +1620,16 @@ bool HTMLInputElement::isSteppable() const
return m_inputType->isSteppable();
}
+#if ENABLE(INPUT_SPEECH)
+
+bool HTMLInputElement::isSpeechEnabled() const
+{
+ // FIXME: Add support for RANGE, EMAIL, URL, COLOR and DATE/TIME input types.
+ return m_inputType->shouldRespectSpeechAttribute() && RuntimeEnabledFeatures::sharedFeatures().speechInputEnabled() && hasAttribute(webkitspeechAttr);
+}
+
+#endif
+
#if PLATFORM(IOS)
DateComponents::Type HTMLInputElement::dateType() const
{
@@ -1739,11 +1774,6 @@ void HTMLInputElement::updatePlaceholderText()
return m_inputType->updatePlaceholderText();
}
-bool HTMLInputElement::isEmptyValue() const
-{
- return m_inputType->isEmptyValue();
-}
-
void HTMLInputElement::parseMaxLengthAttribute(const AtomicString& value)
{
int maxLength;
@@ -1756,7 +1786,7 @@ void HTMLInputElement::parseMaxLengthAttribute(const AtomicString& value)
if (oldMaxLength != maxLength)
updateValueIfNeeded();
setNeedsStyleRecalc();
- updateValidity();
+ setNeedsValidityCheck();
}
void HTMLInputElement::updateValueIfNeeded()
@@ -1778,10 +1808,26 @@ bool HTMLInputElement::shouldAppearIndeterminate() const
}
#if ENABLE(MEDIA_CAPTURE)
-bool HTMLInputElement::shouldUseMediaCapture() const
+String HTMLInputElement::capture() const
+{
+ if (!isFileUpload())
+ return String();
+
+ String capture = fastGetAttribute(captureAttr).lower();
+ if (capture == "camera"
+ || capture == "camcorder"
+ || capture == "microphone"
+ || capture == "filesystem")
+ return capture;
+
+ return "filesystem";
+}
+
+void HTMLInputElement::setCapture(const String& value)
{
- return isFileUpload() && fastHasAttribute(captureAttr);
+ setAttribute(captureAttr, value);
}
+
#endif
bool HTMLInputElement::isInRequiredRadioButtonGroup()
@@ -1843,6 +1889,11 @@ void HTMLInputElement::setWidth(unsigned width)
}
#if ENABLE(DATALIST_ELEMENT)
+OwnPtr<ListAttributeTargetObserver> ListAttributeTargetObserver::create(const AtomicString& id, HTMLInputElement* element)
+{
+ return adoptPtr(new ListAttributeTargetObserver(id, element));
+}
+
ListAttributeTargetObserver::ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement* element)
: IdTargetObserver(element->treeScope().idTargetObserverRegistry(), id)
, m_element(element)
@@ -1901,16 +1952,13 @@ bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters&
parameters.stepBase = 0;
}
- if (RenderElement* renderer = this->renderer())
- parameters.anchorRectInRootView = document().view()->contentsToRootView(renderer->absoluteBoundingBoxRect());
- else
- parameters.anchorRectInRootView = IntRect();
+ parameters.anchorRectInRootView = document().view()->contentsToRootView(pixelSnappedBoundingBox());
parameters.currentValue = value();
parameters.isAnchorElementRTL = computedStyle()->direction() == RTL;
#if ENABLE(DATALIST_ELEMENT)
if (HTMLDataListElement* dataList = this->dataList()) {
- Ref<HTMLCollection> options = dataList->options();
- for (unsigned i = 0; HTMLOptionElement* option = downcast<HTMLOptionElement>(options->item(i)); ++i) {
+ RefPtr<HTMLCollection> options = dataList->options();
+ for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); ++i) {
if (!isValidValue(option->value()))
continue;
parameters.suggestionValues.append(sanitizeValue(option->value()));
@@ -1923,9 +1971,4 @@ bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters&
}
#endif
-void HTMLInputElement::capsLockStateMayHaveChanged()
-{
- m_inputType->capsLockStateMayHaveChanged();
-}
-
} // namespace
diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h
index b924307a2..286b8a699 100644
--- a/Source/WebCore/html/HTMLInputElement.h
+++ b/Source/WebCore/html/HTMLInputElement.h
@@ -28,7 +28,6 @@
#include "FileChooser.h"
#include "HTMLTextFormControlElement.h"
#include "StepRange.h"
-#include <memory>
#if PLATFORM(IOS)
#include "DateComponents.h"
@@ -63,23 +62,25 @@ struct InputElementClickState {
class HTMLInputElement : public HTMLTextFormControlElement {
public:
- static Ref<HTMLInputElement> create(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
+ static PassRefPtr<HTMLInputElement> create(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
virtual ~HTMLInputElement();
- virtual HTMLInputElement* toInputElement() override final { return this; }
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitspeechchange);
- WEBCORE_EXPORT virtual bool shouldAutocomplete() const override final;
+ virtual HTMLInputElement* toInputElement() override { return this; }
+
+ virtual bool shouldAutocomplete() const override;
// For ValidityState
- virtual bool hasBadInput() const override final;
- virtual bool patternMismatch() const override final;
- virtual bool rangeUnderflow() const override final;
- virtual bool rangeOverflow() const override final;
- virtual bool stepMismatch() const override final;
- virtual bool tooLong() const override final;
- virtual bool typeMismatch() const override final;
- virtual bool valueMissing() const override final;
- virtual String validationMessage() const override final;
+ virtual bool hasBadInput() const override;
+ virtual bool patternMismatch() const override;
+ virtual bool rangeUnderflow() const override;
+ virtual bool rangeOverflow() const override;
+ virtual bool stepMismatch() const override;
+ virtual bool tooLong() const override;
+ virtual bool typeMismatch() const override;
+ virtual bool valueMissing() const override;
+ virtual String validationMessage() const override;
// Returns the minimum value for type=date, number, or range. Don't call this for other types.
double minimum() const;
@@ -106,10 +107,10 @@ public:
bool isTextButton() const;
bool isRadioButton() const;
- WEBCORE_EXPORT bool isTextField() const;
- WEBCORE_EXPORT bool isSearchField() const;
+ bool isTextField() const;
+ bool isSearchField() const;
bool isInputTypeHidden() const;
- WEBCORE_EXPORT bool isPasswordField() const;
+ bool isPasswordField() const;
bool isCheckbox() const;
bool isRangeControl() const;
@@ -121,37 +122,42 @@ public:
// be using a different one. Many input elements behave like text fields, and in addition
// any unknown input type is treated as text. Consider, for example, isTextField or
// isTextField && !isPasswordField.
- WEBCORE_EXPORT bool isText() const;
+ bool isText() const;
- WEBCORE_EXPORT bool isEmailField() const;
+ bool isEmailField() const;
bool isFileUpload() const;
bool isImageButton() const;
- WEBCORE_EXPORT bool isNumberField() const;
+ bool isNumberField() const;
bool isSubmitButton() const;
- WEBCORE_EXPORT bool isTelephoneField() const;
- WEBCORE_EXPORT bool isURLField() const;
- WEBCORE_EXPORT bool isDateField() const;
- WEBCORE_EXPORT bool isDateTimeField() const;
- WEBCORE_EXPORT bool isDateTimeLocalField() const;
- WEBCORE_EXPORT bool isMonthField() const;
- WEBCORE_EXPORT bool isTimeField() const;
- WEBCORE_EXPORT bool isWeekField() const;
+ bool isTelephoneField() const;
+ bool isURLField() const;
+ bool isDateField() const;
+ bool isDateTimeField() const;
+ bool isDateTimeLocalField() const;
+ bool isMonthField() const;
+ bool isTimeField() const;
+ bool isWeekField() const;
+
+#if ENABLE(INPUT_SPEECH)
+ bool isSpeechEnabled() const;
+#endif
#if PLATFORM(IOS)
DateComponents::Type dateType() const;
#endif
HTMLElement* containerElement() const;
- virtual TextControlInnerTextElement* innerTextElement() const override final;
+ virtual TextControlInnerTextElement* innerTextElement() const override;
HTMLElement* innerBlockElement() const;
HTMLElement* innerSpinButtonElement() const;
- HTMLElement* capsLockIndicatorElement() const;
HTMLElement* resultsButtonElement() const;
HTMLElement* cancelButtonElement() const;
+#if ENABLE(INPUT_SPEECH)
+ HTMLElement* speechButtonElement() const;
+#endif
HTMLElement* sliderThumbElement() const;
HTMLElement* sliderTrackElement() const;
- virtual HTMLElement* placeholderElement() const override final;
- WEBCORE_EXPORT HTMLElement* autoFillButtonElement() const;
+ virtual HTMLElement* placeholderElement() const override;
bool checked() const { return m_isChecked; }
void setChecked(bool, TextFieldEventBehavior = DispatchNoEvent);
@@ -161,18 +167,18 @@ public:
void setIndeterminate(bool);
// shouldAppearChecked is used by the rendering tree/CSS while checked() is used by JS to determine checked state
bool shouldAppearChecked() const;
- virtual bool shouldAppearIndeterminate() const override final;
+ virtual bool shouldAppearIndeterminate() const override;
int size() const;
bool sizeShouldIncludeDecoration(int& preferredSize) const;
float decorationWidth() const;
- void setType(const AtomicString&);
+ void setType(const String&);
- WEBCORE_EXPORT virtual String value() const override final;
+ virtual String value() const override;
void setValue(const String&, ExceptionCode&, TextFieldEventBehavior = DispatchNoEvent);
- WEBCORE_EXPORT void setValue(const String&, TextFieldEventBehavior = DispatchNoEvent);
- WEBCORE_EXPORT void setValueForUser(const String&);
+ void setValue(const String&, TextFieldEventBehavior = DispatchNoEvent);
+ void setValueForUser(const String&);
// Checks if the specified string would be a valid value.
// We should not call this for types with no string value such as CHECKBOX and RADIO.
bool isValidValue(const String&) const;
@@ -185,13 +191,16 @@ public:
// The value which is drawn by a renderer.
String visibleValue() const;
- WEBCORE_EXPORT void setEditingValue(const String&);
+ const String& suggestedValue() const;
+ void setSuggestedValue(const String&);
+
+ void setEditingValue(const String&);
double valueAsDate() const;
void setValueAsDate(double, ExceptionCode&);
- WEBCORE_EXPORT double valueAsNumber() const;
- WEBCORE_EXPORT void setValueAsNumber(double, ExceptionCode&, TextFieldEventBehavior = DispatchNoEvent);
+ double valueAsNumber() const;
+ void setValueAsNumber(double, ExceptionCode&, TextFieldEventBehavior = DispatchNoEvent);
String valueWithDefault() const;
@@ -199,17 +208,17 @@ public:
bool canHaveSelection() const;
- virtual bool rendererIsNeeded(const RenderStyle&) override final;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override final;
- virtual void willAttachRenderers() override final;
- virtual void didAttachRenderers() override final;
- virtual void didDetachRenderers() override final;
+ virtual bool rendererIsNeeded(const RenderStyle&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
+ virtual void willAttachRenderers() override;
+ virtual void didAttachRenderers() override;
+ virtual void didDetachRenderers() override;
// FIXME: For isActivatedSubmit and setActivatedSubmit, we should use the NVI-idiom here by making
// it private virtual in all classes and expose a public method in HTMLFormControlElement to call
// the private virtual method.
- virtual bool isActivatedSubmit() const override final;
- virtual void setActivatedSubmit(bool flag) override final;
+ virtual bool isActivatedSubmit() const override;
+ virtual void setActivatedSubmit(bool flag) override;
String altText() const;
@@ -231,16 +240,13 @@ public:
URL src() const;
- virtual int maxLength() const override final;
+ virtual int maxLength() const override;
void setMaxLength(int, ExceptionCode&);
bool multiple() const;
- bool isAutoFilled() const { return m_isAutoFilled; }
- WEBCORE_EXPORT void setAutoFilled(bool = true);
-
- bool showAutoFillButton() const { return m_showAutoFillButton; }
- WEBCORE_EXPORT void setShowAutoFillButton(bool);
+ bool isAutofilled() const { return m_isAutofilled; }
+ void setAutofilled(bool = true);
FileList* files();
void setFiles(PassRefPtr<FileList>);
@@ -262,6 +268,8 @@ public:
void addSearchResult();
void onSearch();
+ void updateClearButtonVisibility();
+
virtual bool willRespondToMouseClickEvents() override;
#if ENABLE(DATALIST_ELEMENT)
@@ -284,13 +292,14 @@ public:
#if ENABLE(INPUT_TYPE_COLOR)
// For test purposes.
- WEBCORE_EXPORT void selectColorInColorChooser(const Color&);
+ void selectColorInColorChooser(const Color&);
#endif
String defaultToolTip() const;
#if ENABLE(MEDIA_CAPTURE)
- bool shouldUseMediaCapture() const;
+ String capture() const;
+ void setCapture(const String& value);
#endif
static const int maximumLength;
@@ -300,28 +309,27 @@ public:
void setHeight(unsigned);
void setWidth(unsigned);
- virtual void blur() override final;
+ virtual void blur() override;
void defaultBlur();
- virtual const AtomicString& name() const override final;
+ virtual const AtomicString& name() const override;
void endEditing();
static Vector<FileChooserFileInfo> filesFromFileInputFormControlState(const FormControlState&);
- virtual bool matchesReadWritePseudoClass() const override final;
- virtual void setRangeText(const String& replacement, ExceptionCode&) override final;
- virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionCode&) override final;
+ virtual bool matchesReadOnlyPseudoClass() const override;
+ virtual bool matchesReadWritePseudoClass() const override;
+ virtual void setRangeText(const String& replacement, ExceptionCode&) override;
+ virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionCode&) override;
- HTMLImageLoader* imageLoader() { return m_imageLoader.get(); }
- HTMLImageLoader& ensureImageLoader();
+ bool hasImageLoader() const { return m_imageLoader; }
+ HTMLImageLoader* imageLoader();
#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
bool setupDateTimeChooserParameters(DateTimeChooserParameters&);
#endif
- void capsLockStateMayHaveChanged();
-
protected:
HTMLInputElement(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
@@ -330,61 +338,63 @@ protected:
private:
enum AutoCompleteSetting { Uninitialized, On, Off };
- virtual void didAddUserAgentShadowRoot(ShadowRoot*) override final;
-
- virtual void willChangeForm() override final;
- virtual void didChangeForm() override final;
- virtual InsertionNotificationRequest insertedInto(ContainerNode&) override final;
- void finishedInsertingSubtree() override final;
- virtual void removedFrom(ContainerNode&) override final;
- virtual void didMoveToNewDocument(Document* oldDocument) override final;
-
- virtual bool hasCustomFocusLogic() const override final;
- virtual bool isKeyboardFocusable(KeyboardEvent*) const override final;
- virtual bool isMouseFocusable() const override final;
- virtual bool isEnumeratable() const override final;
- virtual bool supportLabels() const override final;
- virtual void updateFocusAppearance(bool restorePreviousSelection) override final;
+ // FIXME: Author shadows should be allowed
+ // https://bugs.webkit.org/show_bug.cgi?id=92608
+ virtual bool areAuthorShadowsAllowed() const override { return false; }
+
+ virtual void didAddUserAgentShadowRoot(ShadowRoot*) override;
+
+ virtual void willChangeForm() override;
+ virtual void didChangeForm() override;
+ virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
+ virtual void removedFrom(ContainerNode&) override;
+ virtual void didMoveToNewDocument(Document* oldDocument) override;
+
+ virtual bool hasCustomFocusLogic() const override;
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const override;
+ virtual bool isMouseFocusable() const override;
+ virtual bool isEnumeratable() const override;
+ virtual bool supportLabels() const override;
+ virtual void updateFocusAppearance(bool restorePreviousSelection) override;
virtual bool shouldUseInputMethod() override final;
- virtual bool isTextFormControl() const override final { return isTextField(); }
+ virtual bool isTextFormControl() const override { return isTextField(); }
- virtual bool canTriggerImplicitSubmission() const override final { return isTextField(); }
+ virtual bool canTriggerImplicitSubmission() const override { return isTextField(); }
- virtual const AtomicString& formControlType() const override final;
+ virtual const AtomicString& formControlType() const override;
- virtual bool shouldSaveAndRestoreFormControlState() const override final;
- virtual FormControlState saveFormControlState() const override final;
- virtual void restoreFormControlState(const FormControlState&) override final;
+ virtual bool shouldSaveAndRestoreFormControlState() const override;
+ virtual FormControlState saveFormControlState() const override;
+ virtual void restoreFormControlState(const FormControlState&) override;
- virtual bool canStartSelection() const override final;
+ virtual bool canStartSelection() const override;
- virtual void accessKeyAction(bool sendMouseEvents) override final;
+ virtual void accessKeyAction(bool sendMouseEvents) override;
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) override final;
- virtual bool isPresentationAttribute(const QualifiedName&) const override final;
- virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override final;
- virtual void finishParsingChildren() override final;
- virtual void parserDidSetAttributes() override final;
+ virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
+ virtual bool isPresentationAttribute(const QualifiedName&) const override;
+ virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
+ virtual void finishParsingChildren() override;
- virtual void copyNonAttributePropertiesFromElement(const Element&) override final;
+ virtual void copyNonAttributePropertiesFromElement(const Element&) override;
- virtual bool appendFormData(FormDataList&, bool) override final;
+ virtual bool appendFormData(FormDataList&, bool) override;
- virtual bool isSuccessfulSubmitButton() const override final;
+ virtual bool isSuccessfulSubmitButton() const override;
- virtual void reset() override final;
+ virtual void reset() override;
- virtual bool isURLAttribute(const Attribute&) const override final;
- virtual bool isInRange() const override final;
- virtual bool isOutOfRange() const override final;
+ virtual bool isURLAttribute(const Attribute&) const override;
+ virtual bool isInRange() const override;
+ virtual bool isOutOfRange() const override;
- virtual void documentDidResumeFromPageCache() override final;
+ virtual void documentDidResumeFromPageCache() override;
#if ENABLE(INPUT_TYPE_COLOR)
- virtual void documentWillSuspendForPageCache() override final;
+ virtual void documentWillSuspendForPageCache() override;
#endif
- virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override final;
+ virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override;
bool needsSuspensionCallback();
void registerForSuspensionCallbackIfNeeded();
@@ -394,22 +404,21 @@ private:
bool isTextType() const;
bool tooLong(const String&, NeedsToCheckDirtyFlag) const;
- virtual bool supportsPlaceholder() const override final;
- virtual void updatePlaceholderText() override final;
- virtual bool isEmptyValue() const override final;
- virtual void handleFocusEvent(Node* oldFocusedNode, FocusDirection) override final;
- virtual void handleBlurEvent() override final;
+ virtual bool supportsPlaceholder() const override;
+ virtual void updatePlaceholderText() override;
+ virtual bool isEmptyValue() const override { return innerTextValue().isEmpty(); }
+ virtual bool isEmptySuggestedValue() const override { return suggestedValue().isEmpty(); }
+ virtual void handleFocusEvent(Node* oldFocusedNode, FocusDirection) override;
+ virtual void handleBlurEvent() override;
- virtual bool isOptionalFormControl() const override final { return !isRequiredFormControl(); }
- virtual bool isRequiredFormControl() const override final;
- virtual bool computeWillValidate() const override final;
- virtual void requiredAttributeChanged() override final;
+ virtual bool isOptionalFormControl() const override { return !isRequiredFormControl(); }
+ virtual bool isRequiredFormControl() const override;
+ virtual bool recalcWillValidate() const override;
+ virtual void requiredAttributeChanged() override;
- void initializeInputType();
void updateType();
- void runPostTypeUpdateTasks();
- virtual void subtreeHasChanged() override final;
+ virtual void subtreeHasChanged() override;
#if ENABLE(DATALIST_ELEMENT)
void resetListAttributeTargetObserver();
@@ -424,6 +433,7 @@ private:
AtomicString m_name;
String m_valueIfDirty;
+ String m_suggestedValue;
int m_size;
int m_maxLength;
short m_maxResults;
@@ -433,8 +443,7 @@ private:
bool m_hasType : 1;
bool m_isActivatedSubmit : 1;
unsigned m_autocomplete : 2; // AutoCompleteSetting
- bool m_isAutoFilled : 1;
- bool m_showAutoFillButton : 1;
+ bool m_isAutofilled : 1;
#if ENABLE(DATALIST_ELEMENT)
bool m_hasNonEmptyList : 1;
#endif
@@ -450,11 +459,13 @@ private:
// The ImageLoader must be owned by this element because the loader code assumes
// that it lives as long as its owning element lives. If we move the loader into
// the ImageInput object we may delete the loader while this element lives on.
- std::unique_ptr<HTMLImageLoader> m_imageLoader;
+ OwnPtr<HTMLImageLoader> m_imageLoader;
#if ENABLE(DATALIST_ELEMENT)
- std::unique_ptr<ListAttributeTargetObserver> m_listAttributeTargetObserver;
+ OwnPtr<ListAttributeTargetObserver> m_listAttributeTargetObserver;
#endif
};
+NODE_TYPE_CASTS(HTMLInputElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLInputElement.idl b/Source/WebCore/html/HTMLInputElement.idl
index d38e314e7..434202c4e 100644
--- a/Source/WebCore/html/HTMLInputElement.idl
+++ b/Source/WebCore/html/HTMLInputElement.idl
@@ -54,7 +54,7 @@ interface HTMLInputElement : HTMLElement {
#endif
[Reflect, URL] attribute DOMString src;
[Reflect] attribute DOMString step;
- attribute DOMString type; // readonly dropped as part of DOM level 2
+ [TreatNullAs=NullString] attribute DOMString type; // readonly dropped as part of DOM level 2
[TreatNullAs=NullString] attribute DOMString defaultValue;
// See the discussion in https://bugs.webkit.org/show_bug.cgi?id=100085
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
@@ -62,8 +62,10 @@ interface HTMLInputElement : HTMLElement {
#else
[TreatNullAs=NullString] attribute DOMString value;
#endif
+#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
[SetterRaisesException] attribute Date valueAsDate;
- [SetterRaisesException] attribute unrestricted double valueAsNumber;
+#endif
+ [SetterRaisesException] attribute double valueAsNumber;
[RaisesException] void stepUp(optional long n);
[RaisesException] void stepDown(optional long n);
@@ -98,8 +100,12 @@ interface HTMLInputElement : HTMLElement {
// Non-standard attributes
[Reflect] attribute DOMString align;
+ [Conditional=DIRECTORY_UPLOAD, Reflect] attribute boolean webkitdirectory;
[Reflect] attribute DOMString useMap;
[Reflect] attribute boolean incremental;
+ [Conditional=INPUT_SPEECH, Reflect] attribute boolean webkitSpeech;
+ [Conditional=INPUT_SPEECH, Reflect] attribute boolean webkitGrammar;
+ [Conditional=INPUT_SPEECH, NotEnumerable] attribute EventListener onwebkitspeechchange;
#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
[Reflect] attribute DOMString accessKey;
@@ -123,5 +129,5 @@ interface HTMLInputElement : HTMLElement {
[Conditional=IOS_AUTOCORRECT_AND_AUTOCAPITALIZE, TreatNullAs=NullString] attribute DOMString autocapitalize;
// See http://www.w3.org/TR/html-media-capture/
- [Conditional=MEDIA_CAPTURE, Reflect] attribute boolean capture;
+ [Conditional=MEDIA_CAPTURE] attribute DOMString capture;
};
diff --git a/Source/WebCore/html/HTMLKeygenElement.cpp b/Source/WebCore/html/HTMLKeygenElement.cpp
index e7d914825..401de1c95 100644
--- a/Source/WebCore/html/HTMLKeygenElement.cpp
+++ b/Source/WebCore/html/HTMLKeygenElement.cpp
@@ -44,23 +44,23 @@ using namespace HTMLNames;
class KeygenSelectElement final : public HTMLSelectElement {
public:
- static Ref<KeygenSelectElement> create(Document& document)
+ static PassRefPtr<KeygenSelectElement> create(Document& document)
{
- return adoptRef(*new KeygenSelectElement(document));
+ return adoptRef(new KeygenSelectElement(document));
}
protected:
KeygenSelectElement(Document& document)
: HTMLSelectElement(selectTag, document, 0)
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-keygen-select", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-keygen-select", AtomicString::ConstructFromLiteral));
setPseudo(pseudoId);
}
private:
- virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren(Document& targetDocument) override
+ virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() override
{
- return create(targetDocument);
+ return create(document());
}
};
@@ -83,9 +83,9 @@ inline HTMLKeygenElement::HTMLKeygenElement(const QualifiedName& tagName, Docume
ensureUserAgentShadowRoot().appendChild(select, IGNORE_EXCEPTION);
}
-Ref<HTMLKeygenElement> HTMLKeygenElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
+PassRefPtr<HTMLKeygenElement> HTMLKeygenElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
{
- return adoptRef(*new HTMLKeygenElement(tagName, document, form));
+ return adoptRef(new HTMLKeygenElement(tagName, document, form));
}
void HTMLKeygenElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -112,7 +112,7 @@ bool HTMLKeygenElement::appendFormData(FormDataList& encoded_values, bool)
const AtomicString& HTMLKeygenElement::formControlType() const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, keygen, ("keygen", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, keygen, ("keygen", AtomicString::ConstructFromLiteral));
return keygen;
}
@@ -129,7 +129,7 @@ bool HTMLKeygenElement::shouldSaveAndRestoreFormControlState() const
HTMLSelectElement* HTMLKeygenElement::shadowSelect() const
{
ShadowRoot* root = userAgentShadowRoot();
- return root ? downcast<HTMLSelectElement>(root->firstChild()) : nullptr;
+ return root ? toHTMLSelectElement(root->firstChild()) : 0;
}
} // namespace
diff --git a/Source/WebCore/html/HTMLKeygenElement.h b/Source/WebCore/html/HTMLKeygenElement.h
index 2cec2619d..c0f59ee37 100644
--- a/Source/WebCore/html/HTMLKeygenElement.h
+++ b/Source/WebCore/html/HTMLKeygenElement.h
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2010, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -32,12 +32,15 @@ class HTMLSelectElement;
class HTMLKeygenElement final : public HTMLFormControlElementWithState {
public:
- static Ref<HTMLKeygenElement> create(const QualifiedName&, Document&, HTMLFormElement*);
+ static PassRefPtr<HTMLKeygenElement> create(const QualifiedName&, Document&, HTMLFormElement*);
+
+ virtual bool willValidate() const override { return false; }
private:
HTMLKeygenElement(const QualifiedName&, Document&, HTMLFormElement*);
- virtual bool computeWillValidate() const override { return false; }
+ virtual bool areAuthorShadowsAllowed() const override { return false; }
+
virtual bool canStartSelection() const override { return false; }
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
diff --git a/Source/WebCore/html/HTMLLIElement.cpp b/Source/WebCore/html/HTMLLIElement.cpp
index 2215d7689..ab2df915c 100644
--- a/Source/WebCore/html/HTMLLIElement.cpp
+++ b/Source/WebCore/html/HTMLLIElement.cpp
@@ -26,7 +26,6 @@
#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
-#include "ElementAncestorIterator.h"
#include "HTMLNames.h"
#include "RenderListItem.h"
@@ -41,14 +40,14 @@ HTMLLIElement::HTMLLIElement(const QualifiedName& tagName, Document& document)
setHasCustomStyleResolveCallbacks();
}
-Ref<HTMLLIElement> HTMLLIElement::create(Document& document)
+PassRefPtr<HTMLLIElement> HTMLLIElement::create(Document& document)
{
- return adoptRef(*new HTMLLIElement(liTag, document));
+ return adoptRef(new HTMLLIElement(liTag, document));
}
-Ref<HTMLLIElement> HTMLLIElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLLIElement> HTMLLIElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLLIElement(tagName, document));
+ return adoptRef(new HTMLLIElement(tagName, document));
}
bool HTMLLIElement::isPresentationAttribute(const QualifiedName& name) const
@@ -88,37 +87,39 @@ void HTMLLIElement::parseAttribute(const QualifiedName& name, const AtomicString
void HTMLLIElement::didAttachRenderers()
{
- if (!is<RenderListItem>(renderer()))
+ if (!renderer() || !renderer()->isListItem())
return;
- auto& listItemRenderer = downcast<RenderListItem>(*renderer());
-
- // Check if there is an enclosing list.
- bool isInList = false;
- for (auto& ancestor : ancestorsOfType<HTMLElement>(*this)) {
- if (is<HTMLUListElement>(ancestor) || is<HTMLOListElement>(ancestor)) {
- isInList = true;
+ RenderListItem* listItemRenderer = toRenderListItem(renderer());
+
+ // Find the enclosing list node.
+ Element* listNode = 0;
+ Element* current = this;
+ while (!listNode) {
+ current = current->parentElement();
+ if (!current)
break;
- }
+ if (current->hasTagName(ulTag) || current->hasTagName(olTag))
+ listNode = current;
}
// If we are not in a list, tell the renderer so it can position us inside.
// We don't want to change our style to say "inside" since that would affect nested nodes.
- if (!isInList)
- listItemRenderer.setNotInList(true);
+ if (!listNode)
+ listItemRenderer->setNotInList(true);
parseValue(fastGetAttribute(valueAttr));
}
inline void HTMLLIElement::parseValue(const AtomicString& value)
{
- ASSERT(renderer());
+ ASSERT(renderer() && renderer()->isListItem());
bool valueOK;
int requestedValue = value.toInt(&valueOK);
if (valueOK)
- downcast<RenderListItem>(*renderer()).setExplicitValue(requestedValue);
+ toRenderListItem(renderer())->setExplicitValue(requestedValue);
else
- downcast<RenderListItem>(*renderer()).clearExplicitValue();
+ toRenderListItem(renderer())->clearExplicitValue();
}
}
diff --git a/Source/WebCore/html/HTMLLIElement.h b/Source/WebCore/html/HTMLLIElement.h
index 489b434c8..e76130096 100644
--- a/Source/WebCore/html/HTMLLIElement.h
+++ b/Source/WebCore/html/HTMLLIElement.h
@@ -29,8 +29,8 @@ namespace WebCore {
class HTMLLIElement final : public HTMLElement {
public:
- static Ref<HTMLLIElement> create(Document&);
- static Ref<HTMLLIElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLLIElement> create(Document&);
+ static PassRefPtr<HTMLLIElement> create(const QualifiedName&, Document&);
private:
HTMLLIElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLLabelElement.cpp b/Source/WebCore/html/HTMLLabelElement.cpp
index 1eb7046e9..1cbed01e6 100644
--- a/Source/WebCore/html/HTMLLabelElement.cpp
+++ b/Source/WebCore/html/HTMLLabelElement.cpp
@@ -38,9 +38,9 @@ using namespace HTMLNames;
static LabelableElement* nodeAsSupportedLabelableElement(Node* node)
{
- if (!is<LabelableElement>(node))
+ if (!node || !isLabelableElement(*node))
return nullptr;
- LabelableElement& element = downcast<LabelableElement>(*node);
+ LabelableElement& element = toLabelableElement(*node);
return element.supportLabels() ? &element : nullptr;
}
@@ -50,9 +50,9 @@ inline HTMLLabelElement::HTMLLabelElement(const QualifiedName& tagName, Document
ASSERT(hasTagName(labelTag));
}
-Ref<HTMLLabelElement> HTMLLabelElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLLabelElement> HTMLLabelElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLLabelElement(tagName, document));
+ return adoptRef(new HTMLLabelElement(tagName, document));
}
bool HTMLLabelElement::isFocusable() const
@@ -62,7 +62,7 @@ bool HTMLLabelElement::isFocusable() const
LabelableElement* HTMLLabelElement::control()
{
- const AtomicString& controlId = fastGetAttribute(forAttr);
+ const AtomicString& controlId = getAttribute(forAttr);
if (controlId.isNull()) {
// Search the children and descendants of the label element for a form element.
// per http://dev.w3.org/html5/spec/Overview.html#the-label-element
diff --git a/Source/WebCore/html/HTMLLabelElement.h b/Source/WebCore/html/HTMLLabelElement.h
index 8815bfe8d..aea5237a8 100644
--- a/Source/WebCore/html/HTMLLabelElement.h
+++ b/Source/WebCore/html/HTMLLabelElement.h
@@ -31,7 +31,7 @@ namespace WebCore {
class HTMLLabelElement final : public HTMLElement {
public:
- static Ref<HTMLLabelElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLLabelElement> create(const QualifiedName&, Document&);
LabelableElement* control();
HTMLFormElement* form() const;
@@ -55,6 +55,8 @@ private:
virtual void focus(bool restorePreviousSelection, FocusDirection) override;
};
+NODE_TYPE_CASTS(HTMLLabelElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLLegendElement.cpp b/Source/WebCore/html/HTMLLegendElement.cpp
index ea7973586..5973bc207 100644
--- a/Source/WebCore/html/HTMLLegendElement.cpp
+++ b/Source/WebCore/html/HTMLLegendElement.cpp
@@ -40,9 +40,9 @@ inline HTMLLegendElement::HTMLLegendElement(const QualifiedName& tagName, Docume
ASSERT(hasTagName(legendTag));
}
-Ref<HTMLLegendElement> HTMLLegendElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLLegendElement> HTMLLegendElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLLegendElement(tagName, document));
+ return adoptRef(new HTMLLegendElement(tagName, document));
}
HTMLFormControlElement* HTMLLegendElement::associatedControl()
@@ -79,10 +79,10 @@ HTMLFormElement* HTMLLegendElement::virtualForm() const
// its parent, then the form attribute must return the same value as the
// form attribute on that fieldset element. Otherwise, it must return null.
ContainerNode* fieldset = parentNode();
- if (!is<HTMLFieldSetElement>(fieldset))
- return nullptr;
+ if (!fieldset || !fieldset->hasTagName(fieldsetTag))
+ return 0;
- return downcast<HTMLFieldSetElement>(*fieldset).form();
+ return toHTMLFieldSetElement(fieldset)->form();
}
} // namespace
diff --git a/Source/WebCore/html/HTMLLegendElement.h b/Source/WebCore/html/HTMLLegendElement.h
index 4de12d996..24568bda4 100644
--- a/Source/WebCore/html/HTMLLegendElement.h
+++ b/Source/WebCore/html/HTMLLegendElement.h
@@ -32,7 +32,7 @@ class HTMLFormControlElement;
class HTMLLegendElement final : public HTMLElement {
public:
- static Ref<HTMLLegendElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLLegendElement> create(const QualifiedName&, Document&);
private:
HTMLLegendElement(const QualifiedName&, Document&);
@@ -45,6 +45,8 @@ private:
virtual HTMLFormElement* virtualForm() const override;
};
+NODE_TYPE_CASTS(HTMLLegendElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp
index 04139cb72..95cfcda4d 100644
--- a/Source/WebCore/html/HTMLLinkElement.cpp
+++ b/Source/WebCore/html/HTMLLinkElement.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2009 Rob Buis (rwlbuis@gmail.com)
* Copyright (C) 2011 Google Inc. All rights reserved.
*
@@ -39,14 +39,11 @@
#include "FrameLoaderClient.h"
#include "FrameTree.h"
#include "FrameView.h"
-#include "HTMLAnchorElement.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
#include "MediaList.h"
#include "MediaQueryEvaluator.h"
-#include "MouseEvent.h"
#include "Page.h"
-#include "RelList.h"
#include "RenderStyle.h"
#include "SecurityOrigin.h"
#include "Settings.h"
@@ -62,13 +59,13 @@ using namespace HTMLNames;
static LinkEventSender& linkLoadEventSender()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(LinkEventSender, sharedLoadEventSender, (eventNames().loadEvent));
+ DEFINE_STATIC_LOCAL(LinkEventSender, sharedLoadEventSender, (eventNames().loadEvent));
return sharedLoadEventSender;
}
inline HTMLLinkElement::HTMLLinkElement(const QualifiedName& tagName, Document& document, bool createdByParser)
: HTMLElement(tagName, document)
- , m_linkLoader(*this)
+ , m_linkLoader(this)
, m_sizes(DOMSettableTokenList::create())
, m_disabledState(Unset)
, m_loading(false)
@@ -81,9 +78,9 @@ inline HTMLLinkElement::HTMLLinkElement(const QualifiedName& tagName, Document&
ASSERT(hasTagName(linkTag));
}
-Ref<HTMLLinkElement> HTMLLinkElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
+PassRefPtr<HTMLLinkElement> HTMLLinkElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
{
- return adoptRef(*new HTMLLinkElement(tagName, document, createdByParser));
+ return adoptRef(new HTMLLinkElement(tagName, document, createdByParser));
}
HTMLLinkElement::~HTMLLinkElement()
@@ -97,7 +94,7 @@ HTMLLinkElement::~HTMLLinkElement()
if (inDocument())
document().styleSheetCollection().removeStyleSheetCandidateNode(*this);
- linkLoadEventSender().cancelEvent(*this);
+ linkLoadEventSender().cancelEvent(this);
}
void HTMLLinkElement::setDisabledState(bool disabled)
@@ -113,7 +110,7 @@ void HTMLLinkElement::setDisabledState(bool disabled)
removePendingSheet();
// Check #2: An alternate sheet becomes enabled while it is still loading.
- if (m_relAttribute.isAlternate && m_disabledState == EnabledViaScript)
+ if (m_relAttribute.m_isAlternate && m_disabledState == EnabledViaScript)
addPendingSheet(ActiveSheet);
// Check #3: A main sheet becomes enabled while it was still loading and
@@ -121,7 +118,7 @@ void HTMLLinkElement::setDisabledState(bool disabled)
// happen (a double toggle for no reason essentially). This happens on
// virtualplastic.net, which manages to do about 12 enable/disables on only 3
// sheets. :)
- if (!m_relAttribute.isAlternate && m_disabledState == EnabledViaScript && oldDisabledState == Disabled)
+ if (!m_relAttribute.m_isAlternate && m_disabledState == EnabledViaScript && oldDisabledState == Disabled)
addPendingSheet(ActiveSheet);
// If the sheet is already loading just bail.
@@ -140,55 +137,36 @@ void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicStri
{
if (name == relAttr) {
m_relAttribute = LinkRelAttribute(value);
- if (m_relList)
- m_relList->updateRelAttribute(value);
process();
- return;
- }
- if (name == hrefAttr) {
- bool wasLink = isLink();
- setIsLink(!value.isNull() && !shouldProhibitLinks(this));
- if (wasLink != isLink())
- setNeedsStyleRecalc();
+ } else if (name == hrefAttr) {
process();
- return;
- }
- if (name == typeAttr) {
+ } else if (name == typeAttr) {
m_type = value;
process();
- return;
- }
- if (name == sizesAttr) {
+ } else if (name == sizesAttr) {
setSizes(value);
process();
- return;
- }
- if (name == mediaAttr) {
+ } else if (name == mediaAttr) {
m_media = value.string().lower();
process();
- if (m_sheet && !isDisabled())
- document().styleResolverChanged(DeferRecalcStyle);
- return;
- }
- if (name == disabledAttr) {
+ } else if (name == disabledAttr)
setDisabledState(!value.isNull());
- return;
- }
- if (name == titleAttr) {
- if (m_sheet)
+ else if (name == onbeforeloadAttr)
+ setAttributeEventListener(eventNames().beforeloadEvent, name, value);
+ else {
+ if (name == titleAttr && m_sheet)
m_sheet->setTitle(value);
- return;
+ HTMLElement::parseAttribute(name, value);
}
- HTMLElement::parseAttribute(name, value);
}
bool HTMLLinkElement::shouldLoadLink()
{
- Ref<Document> originalDocument = document();
+ Ref<Document> originalDocument(document());
if (!dispatchBeforeLoadEvent(getNonEmptyURLAttribute(hrefAttr)))
return false;
// A beforeload handler might have removed us from the document or changed the document.
- if (!inDocument() || &document() != originalDocument.ptr())
+ if (!inDocument() || &document() != &originalDocument.get())
return false;
return true;
}
@@ -200,16 +178,18 @@ void HTMLLinkElement::process()
return;
}
+ String type = m_type.lower();
URL url = getNonEmptyURLAttribute(hrefAttr);
- if (!m_linkLoader.loadLink(m_relAttribute, url, document()))
+ if (!m_linkLoader.loadLink(m_relAttribute, type, m_sizes->toString(), url, &document()))
return;
- bool treatAsStyleSheet = m_relAttribute.isStyleSheet
- || (document().settings() && document().settings()->treatsAnyTextCSSLinkAsStylesheet() && m_type.containsIgnoringASCIICase("text/css"));
+ bool acceptIfTypeContainsTextCSS = document().page() && document().page()->settings().treatsAnyTextCSSLinkAsStylesheet();
- if (m_disabledState != Disabled && treatAsStyleSheet && document().frame() && url.isValid()) {
- AtomicString charset = fastGetAttribute(charsetAttr);
+ if (m_disabledState != Disabled && (m_relAttribute.m_isStyleSheet || (acceptIfTypeContainsTextCSS && type.contains("text/css")))
+ && document().frame() && url.isValid()) {
+
+ String charset = getAttribute(charsetAttr);
if (charset.isEmpty() && document().frame())
charset = document().charset();
@@ -240,12 +220,10 @@ void HTMLLinkElement::process()
addPendingSheet(isActive ? ActiveSheet : InactiveSheet);
// Load stylesheets that are not needed for the rendering immediately with low priority.
- Optional<ResourceLoadPriority> priority;
- if (!isActive)
- priority = ResourceLoadPriority::VeryLow;
+ ResourceLoadPriority priority = isActive ? ResourceLoadPriorityUnresolved : ResourceLoadPriorityVeryLow;
CachedResourceRequest request(ResourceRequest(document().completeURL(url)), charset, priority);
request.setInitiator(this);
- m_cachedSheet = document().cachedResourceLoader().requestCSSStyleSheet(request);
+ m_cachedSheet = document().cachedResourceLoader()->requestCSSStyleSheet(request);
if (m_cachedSheet)
m_cachedSheet->addClient(this);
@@ -266,7 +244,7 @@ void HTMLLinkElement::clearSheet()
ASSERT(m_sheet);
ASSERT(m_sheet->ownerNode() == this);
m_sheet->clearOwnerNode();
- m_sheet = nullptr;
+ m_sheet = 0;
}
Node::InsertionNotificationRequest HTMLLinkElement::insertedInto(ContainerNode& insertionPoint)
@@ -291,6 +269,8 @@ void HTMLLinkElement::removedFrom(ContainerNode& insertionPoint)
if (!insertionPoint.inDocument())
return;
+ m_linkLoader.released();
+
if (m_isInShadowTree) {
ASSERT(!m_sheet);
return;
@@ -319,17 +299,12 @@ void HTMLLinkElement::setCSSStyleSheet(const String& href, const URL& baseURL, c
ASSERT(!m_sheet);
return;
}
- auto* frame = document().frame();
- if (!frame)
- return;
-
// Completing the sheet load may cause scripts to execute.
Ref<HTMLLinkElement> protect(*this);
CSSParserContext parserContext(document(), baseURL, charset);
- auto cachePolicy = frame->loader().subresourceCachePolicy();
- if (RefPtr<StyleSheetContents> restoredSheet = const_cast<CachedCSSStyleSheet*>(cachedStyleSheet)->restoreParsedStyleSheet(parserContext, cachePolicy)) {
+ if (RefPtr<StyleSheetContents> restoredSheet = const_cast<CachedCSSStyleSheet*>(cachedStyleSheet)->restoreParsedStyleSheet(parserContext)) {
ASSERT(restoredSheet->isCacheable());
ASSERT(!restoredSheet->isLoading());
@@ -344,7 +319,7 @@ void HTMLLinkElement::setCSSStyleSheet(const String& href, const URL& baseURL, c
}
Ref<StyleSheetContents> styleSheet(StyleSheetContents::create(href, parserContext));
- m_sheet = CSSStyleSheet::create(styleSheet.copyRef(), this);
+ m_sheet = CSSStyleSheet::create(styleSheet.get(), this);
m_sheet->setMediaQueries(MediaQuerySet::createAllowingDescriptionSyntax(m_media));
m_sheet->setTitle(title());
@@ -355,7 +330,7 @@ void HTMLLinkElement::setCSSStyleSheet(const String& href, const URL& baseURL, c
styleSheet.get().checkLoaded();
if (styleSheet.get().isCacheable())
- const_cast<CachedCSSStyleSheet*>(cachedStyleSheet)->saveParsedStyleSheet(WTF::move(styleSheet));
+ const_cast<CachedCSSStyleSheet*>(cachedStyleSheet)->saveParsedStyleSheet(styleSheet.get());
}
bool HTMLLinkElement::styleSheetIsLoading() const
@@ -400,19 +375,12 @@ void HTMLLinkElement::dispatchPendingEvent(LinkEventSender* eventSender)
linkLoadingErrored();
}
-DOMTokenList& HTMLLinkElement::relList()
-{
- if (!m_relList)
- m_relList = std::make_unique<RelList>(*this);
- return *m_relList;
-}
-
void HTMLLinkElement::notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred)
{
if (m_firedLoad)
return;
m_loadedSheet = !errorOccurred;
- linkLoadEventSender().dispatchEventSoon(*this);
+ linkLoadEventSender().dispatchEventSoon(this);
m_firedLoad = true;
}
@@ -428,36 +396,14 @@ bool HTMLLinkElement::isURLAttribute(const Attribute& attribute) const
return attribute.name().localName() == hrefAttr || HTMLElement::isURLAttribute(attribute);
}
-void HTMLLinkElement::defaultEventHandler(Event* event)
-{
- ASSERT(event);
- if (MouseEvent::canTriggerActivationBehavior(*event)) {
- handleClick(*event);
- return;
- }
- HTMLElement::defaultEventHandler(event);
-}
-
-void HTMLLinkElement::handleClick(Event& event)
-{
- event.setDefaultHandled();
- URL url = href();
- if (url.isNull())
- return;
- Frame* frame = document().frame();
- if (!frame)
- return;
- frame->loader().urlSelected(url, target(), &event, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate());
-}
-
URL HTMLLinkElement::href() const
{
return document().completeURL(getAttribute(hrefAttr));
}
-const AtomicString& HTMLLinkElement::rel() const
+String HTMLLinkElement::rel() const
{
- return fastGetAttribute(relAttr);
+ return getAttribute(relAttr);
}
String HTMLLinkElement::target() const
@@ -465,14 +411,14 @@ String HTMLLinkElement::target() const
return getAttribute(targetAttr);
}
-const AtomicString& HTMLLinkElement::type() const
+String HTMLLinkElement::type() const
{
return getAttribute(typeAttr);
}
IconType HTMLLinkElement::iconType() const
{
- return m_relAttribute.iconType;
+ return m_relAttribute.m_iconType;
}
String HTMLLinkElement::iconSizes() const
@@ -485,10 +431,10 @@ void HTMLLinkElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
HTMLElement::addSubresourceAttributeURLs(urls);
// Favicons are handled by a special case in LegacyWebArchive::create()
- if (m_relAttribute.iconType != InvalidIcon)
+ if (m_relAttribute.m_iconType != InvalidIcon)
return;
- if (!m_relAttribute.isStyleSheet)
+ if (!m_relAttribute.m_isStyleSheet)
return;
// Append the URL of this link element.
@@ -530,6 +476,11 @@ void HTMLLinkElement::removePendingSheet(RemovePendingSheetNotificationType noti
: DocumentStyleSheetCollection::RemovePendingSheetNotifyLater);
}
+DOMSettableTokenList* HTMLLinkElement::sizes() const
+{
+ return m_sizes.get();
+}
+
void HTMLLinkElement::setSizes(const String& value)
{
m_sizes->setValue(value);
diff --git a/Source/WebCore/html/HTMLLinkElement.h b/Source/WebCore/html/HTMLLinkElement.h
index a667352d6..65b324176 100644
--- a/Source/WebCore/html/HTMLLinkElement.h
+++ b/Source/WebCore/html/HTMLLinkElement.h
@@ -29,6 +29,7 @@
#include "CachedResourceHandle.h"
#include "DOMSettableTokenList.h"
#include "HTMLElement.h"
+#include "IconURL.h"
#include "LinkLoader.h"
#include "LinkLoaderClient.h"
#include "LinkRelAttribute.h"
@@ -36,7 +37,6 @@
namespace WebCore {
class HTMLLinkElement;
-class RelList;
class URL;
template<typename T> class EventSender;
@@ -44,15 +44,15 @@ typedef EventSender<HTMLLinkElement> LinkEventSender;
class HTMLLinkElement final : public HTMLElement, public CachedStyleSheetClient, public LinkLoaderClient {
public:
- static Ref<HTMLLinkElement> create(const QualifiedName&, Document&, bool createdByParser);
+ static PassRefPtr<HTMLLinkElement> create(const QualifiedName&, Document&, bool createdByParser);
virtual ~HTMLLinkElement();
URL href() const;
- const AtomicString& rel() const;
+ String rel() const;
virtual String target() const override;
- const AtomicString& type() const;
+ String type() const;
IconType iconType() const;
@@ -66,13 +66,11 @@ public:
bool isDisabled() const { return m_disabledState == Disabled; }
bool isEnabledViaScript() const { return m_disabledState == EnabledViaScript; }
void setSizes(const String&);
- DOMSettableTokenList& sizes() { return m_sizes.get(); }
+ DOMSettableTokenList* sizes() const;
void dispatchPendingEvent(LinkEventSender*);
static void dispatchPendingLoadEvents();
- DOMTokenList& relList();
-
private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
@@ -93,15 +91,13 @@ private:
virtual void linkLoaded() override;
virtual void linkLoadingErrored() override;
- bool isAlternate() const { return m_disabledState == Unset && m_relAttribute.isAlternate; }
+ bool isAlternate() const { return m_disabledState == Unset && m_relAttribute.m_isAlternate; }
void setDisabledState(bool);
virtual bool isURLAttribute(const Attribute&) const override;
- virtual void defaultEventHandler(Event*) override;
- void handleClick(Event&);
-
+private:
HTMLLinkElement(const QualifiedName&, Document&, bool createdByParser);
virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override;
@@ -129,7 +125,7 @@ private:
String m_type;
String m_media;
- Ref<DOMSettableTokenList> m_sizes;
+ RefPtr<DOMSettableTokenList> m_sizes;
DisabledState m_disabledState;
LinkRelAttribute m_relAttribute;
bool m_loading;
@@ -139,10 +135,10 @@ private:
bool m_loadedSheet;
PendingSheetType m_pendingSheetType;
-
- std::unique_ptr<RelList> m_relList;
};
+NODE_TYPE_CASTS(HTMLLinkElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLLinkElement.idl b/Source/WebCore/html/HTMLLinkElement.idl
index 33e76cc0c..0a4e34759 100644
--- a/Source/WebCore/html/HTMLLinkElement.idl
+++ b/Source/WebCore/html/HTMLLinkElement.idl
@@ -27,8 +27,8 @@ interface HTMLLinkElement : HTMLElement {
[Reflect] attribute DOMString media;
[Reflect] attribute DOMString rel;
[Reflect] attribute DOMString rev;
-#if (defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT) || (defined(LANGUAGE_GOBJECT) || LANGUAGE_GOBJECT)
- [CustomSetter] attribute DOMSettableTokenList sizes;
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ [Custom] attribute DOMSettableTokenList sizes;
#endif
[Reflect] attribute DOMString target;
[Reflect] attribute DOMString type;
@@ -40,7 +40,5 @@ interface HTMLLinkElement : HTMLElement {
// Objective-C extension:
readonly attribute URL absoluteLinkURL;
#endif
-
- readonly attribute DOMTokenList relList;
};
diff --git a/Source/WebCore/html/HTMLMapElement.cpp b/Source/WebCore/html/HTMLMapElement.cpp
index a3c9c3392..bb1ba20bb 100644
--- a/Source/WebCore/html/HTMLMapElement.cpp
+++ b/Source/WebCore/html/HTMLMapElement.cpp
@@ -41,14 +41,14 @@ HTMLMapElement::HTMLMapElement(const QualifiedName& tagName, Document& document)
ASSERT(hasTagName(mapTag));
}
-Ref<HTMLMapElement> HTMLMapElement::create(Document& document)
+PassRefPtr<HTMLMapElement> HTMLMapElement::create(Document& document)
{
- return adoptRef(*new HTMLMapElement(mapTag, document));
+ return adoptRef(new HTMLMapElement(mapTag, document));
}
-Ref<HTMLMapElement> HTMLMapElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLMapElement> HTMLMapElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLMapElement(tagName, document));
+ return adoptRef(new HTMLMapElement(tagName, document));
}
HTMLMapElement::~HTMLMapElement()
@@ -88,8 +88,8 @@ void HTMLMapElement::parseAttribute(const QualifiedName& name, const AtomicStrin
// FIXME: This logic seems wrong for XML documents.
// Either the id or name will be used depending on the order the attributes are parsed.
- if (name == HTMLNames::idAttr || name == HTMLNames::nameAttr) {
- if (name == HTMLNames::idAttr) {
+ if (isIdAttributeName(name) || name == nameAttr) {
+ if (isIdAttributeName(name)) {
// Call base class so that hasID bit gets set.
HTMLElement::parseAttribute(name, value);
if (document().isHTMLDocument())
@@ -110,7 +110,7 @@ void HTMLMapElement::parseAttribute(const QualifiedName& name, const AtomicStrin
HTMLElement::parseAttribute(name, value);
}
-Ref<HTMLCollection> HTMLMapElement::areas()
+PassRefPtr<HTMLCollection> HTMLMapElement::areas()
{
return ensureCachedHTMLCollection(MapAreas);
}
diff --git a/Source/WebCore/html/HTMLMapElement.h b/Source/WebCore/html/HTMLMapElement.h
index 7d7740830..9ae446728 100644
--- a/Source/WebCore/html/HTMLMapElement.h
+++ b/Source/WebCore/html/HTMLMapElement.h
@@ -32,8 +32,8 @@ class HTMLImageElement;
class HTMLMapElement final : public HTMLElement {
public:
- static Ref<HTMLMapElement> create(Document&);
- static Ref<HTMLMapElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLMapElement> create(Document&);
+ static PassRefPtr<HTMLMapElement> create(const QualifiedName&, Document&);
virtual ~HTMLMapElement();
const AtomicString& getName() const { return m_name; }
@@ -41,7 +41,7 @@ public:
bool mapMouseEvent(LayoutPoint location, const LayoutSize&, HitTestResult&);
HTMLImageElement* imageElement();
- Ref<HTMLCollection> areas();
+ PassRefPtr<HTMLCollection> areas();
private:
HTMLMapElement(const QualifiedName&, Document&);
@@ -54,6 +54,8 @@ private:
AtomicString m_name;
};
+NODE_TYPE_CASTS(HTMLMapElement)
+
} // namespaces
#endif
diff --git a/Source/WebCore/html/HTMLMarqueeElement.cpp b/Source/WebCore/html/HTMLMarqueeElement.cpp
index 23ffbb001..602a6fba4 100644
--- a/Source/WebCore/html/HTMLMarqueeElement.cpp
+++ b/Source/WebCore/html/HTMLMarqueeElement.cpp
@@ -42,16 +42,16 @@ inline HTMLMarqueeElement::HTMLMarqueeElement(const QualifiedName& tagName, Docu
ASSERT(hasTagName(marqueeTag));
}
-Ref<HTMLMarqueeElement> HTMLMarqueeElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLMarqueeElement> HTMLMarqueeElement::create(const QualifiedName& tagName, Document& document)
{
- Ref<HTMLMarqueeElement> marqueeElement = adoptRef(*new HTMLMarqueeElement(tagName, document));
+ RefPtr<HTMLMarqueeElement> marqueeElement(adoptRef(new HTMLMarqueeElement(tagName, document)));
marqueeElement->suspendIfNeeded();
- return marqueeElement;
+ return marqueeElement.release();
}
int HTMLMarqueeElement::minimumDelay() const
{
- if (!fastHasAttribute(truespeedAttr)) {
+ if (fastGetAttribute(truespeedAttr).isEmpty()) {
// WinIE uses 60ms as the minimum delay by default.
return 60;
}
@@ -166,7 +166,7 @@ void HTMLMarqueeElement::setLoop(int loop, ExceptionCode& ec)
setIntegralAttribute(loopAttr, loop);
}
-bool HTMLMarqueeElement::canSuspendForPageCache() const
+bool HTMLMarqueeElement::canSuspend() const
{
return true;
}
diff --git a/Source/WebCore/html/HTMLMarqueeElement.h b/Source/WebCore/html/HTMLMarqueeElement.h
index cc58d60b7..d10982b1d 100644
--- a/Source/WebCore/html/HTMLMarqueeElement.h
+++ b/Source/WebCore/html/HTMLMarqueeElement.h
@@ -32,14 +32,14 @@ class RenderMarquee;
class HTMLMarqueeElement final : public HTMLElement, private ActiveDOMObject {
public:
- static Ref<HTMLMarqueeElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLMarqueeElement> create(const QualifiedName&, Document&);
int minimumDelay() const;
// DOM Functions
void start();
- virtual void stop() override;
+ void stop() override;
int scrollAmount() const;
void setScrollAmount(int, ExceptionCode&);
@@ -57,14 +57,15 @@ private:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
// ActiveDOMObject
- virtual bool canSuspendForPageCache() const override;
+ virtual bool canSuspend() const override;
virtual void suspend(ReasonForSuspension) override;
virtual void resume() override;
- virtual const char* activeDOMObjectName() const override { return "HTMLMarqueeElement"; }
RenderMarquee* renderMarquee() const;
};
+NODE_TYPE_CASTS(HTMLMarqueeElement)
+
} // namespace WebCore
#endif // HTMLMarqueeElement_h
diff --git a/Source/WebCore/html/HTMLMarqueeElement.idl b/Source/WebCore/html/HTMLMarqueeElement.idl
index a80561460..5b8e3a9f2 100644
--- a/Source/WebCore/html/HTMLMarqueeElement.idl
+++ b/Source/WebCore/html/HTMLMarqueeElement.idl
@@ -35,7 +35,7 @@ interface HTMLMarqueeElement : HTMLElement {
// FIXME: Implement the following event handler attributes
// https://bugs.webkit.org/show_bug.cgi?id=49788
- // attribute EventHandler onbounce;
- // attribute EventHandler onfinish;
- // attribute EventHandler onstart;
+ // attribute EventListener onbounce;
+ // attribute EventListener onfinish;
+ // attribute EventListener onstart;
};
diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp
index 5f5f77028..beaa451bd 100644
--- a/Source/WebCore/html/HTMLMediaElement.cpp
+++ b/Source/WebCore/html/HTMLMediaElement.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -37,11 +37,7 @@
#include "ClientRectList.h"
#include "ContentSecurityPolicy.h"
#include "ContentType.h"
-#include "CookieJar.h"
-#include "DiagnosticLoggingClient.h"
#include "DiagnosticLoggingKeys.h"
-#include "DisplaySleepDisabler.h"
-#include "Document.h"
#include "DocumentLoader.h"
#include "ElementIterator.h"
#include "EventNames.h"
@@ -63,27 +59,19 @@
#include "MediaFragmentURIParser.h"
#include "MediaKeyEvent.h"
#include "MediaList.h"
-#include "MediaPlayer.h"
#include "MediaQueryEvaluator.h"
-#include "MediaResourceLoader.h"
-#include "MemoryPressureHandler.h"
-#include "NetworkingContext.h"
+#include "MediaSessionManager.h"
+#include "PageActivityAssertionToken.h"
#include "PageGroup.h"
-#include "PageThrottler.h"
-#include "PlatformMediaSessionManager.h"
#include "ProgressTracker.h"
-#include "RenderLayerCompositor.h"
#include "RenderVideo.h"
#include "RenderView.h"
-#include "ResourceLoadInfo.h"
#include "ScriptController.h"
#include "ScriptSourceCode.h"
#include "SecurityPolicy.h"
-#include "SessionID.h"
#include "Settings.h"
#include "ShadowRoot.h"
#include "TimeRanges.h"
-#include "UserContentController.h"
#include <limits>
#include <runtime/Uint8Array.h>
#include <wtf/CurrentTime.h>
@@ -91,6 +79,16 @@
#include <wtf/Ref.h>
#include <wtf/text/CString.h>
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerCompositor.h"
+#endif
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "RenderEmbeddedObject.h"
+#include "SubframeLoader.h"
+#include "Widget.h"
+#endif
+
#if ENABLE(VIDEO_TRACK)
#include "AudioTrackList.h"
#include "HTMLTrackElement.h"
@@ -112,17 +110,17 @@
#include "RuntimeApplicationChecksIOS.h"
#endif
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#if ENABLE(IOS_AIRPLAY)
#include "WebKitPlaybackTargetAvailabilityEvent.h"
#endif
-#if ENABLE(MEDIA_SESSION)
-#include "MediaSession.h"
+#if PLATFORM(MAC)
+#include "DisplaySleepDisabler.h"
#endif
#if ENABLE(MEDIA_SOURCE)
#include "DOMWindow.h"
-#include "MediaSource.h"
+#include "HTMLMediaSource.h"
#include "Performance.h"
#include "VideoPlaybackQuality.h"
#endif
@@ -145,16 +143,12 @@
#include "JSMediaControlsHost.h"
#include "MediaControlsHost.h"
#include "ScriptGlobalObject.h"
+#include "UserAgentScripts.h"
#include <bindings/ScriptObject.h>
#endif
namespace WebCore {
-static const double SeekRepeatDelay = 0.1;
-static const double SeekTime = 0.2;
-static const double ScanRepeatDelay = 1.5;
-static const double ScanMaximumRate = 8;
-
static void setFlags(unsigned& value, unsigned flags)
{
value |= flags;
@@ -198,17 +192,12 @@ static const char* boolString(bool val)
static const char* mediaSourceBlobProtocol = "blob";
#endif
-#if ENABLE(MEDIA_STREAM)
-// URL protocol used to signal that the media stream API is being used.
-static const char* mediaStreamBlobProtocol = "blob";
-#endif
-
using namespace HTMLNames;
typedef HashMap<Document*, HashSet<HTMLMediaElement*>> DocumentElementSetMap;
static DocumentElementSetMap& documentToElementSetMap()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(DocumentElementSetMap, map, ());
+ DEFINE_STATIC_LOCAL(DocumentElementSetMap, map, ());
return map;
}
@@ -265,82 +254,33 @@ private:
};
#endif
-struct HTMLMediaElement::TrackGroup {
- enum GroupKind { CaptionsAndSubtitles, Description, Chapter, Metadata, Other };
-
- TrackGroup(GroupKind kind)
- : visibleTrack(0)
- , defaultTrack(0)
- , kind(kind)
- , hasSrcLang(false)
- {
- }
-
- Vector<RefPtr<TextTrack>> tracks;
- RefPtr<TextTrack> visibleTrack;
- RefPtr<TextTrack> defaultTrack;
- GroupKind kind;
- bool hasSrcLang;
-};
-
-HashSet<HTMLMediaElement*>& HTMLMediaElement::allMediaElements()
-{
- static NeverDestroyed<HashSet<HTMLMediaElement*>> elements;
- return elements;
-}
-
-#if ENABLE(MEDIA_SESSION)
-typedef HashMap<uint64_t, HTMLMediaElement*> IDToElementMap;
-
-static IDToElementMap& elementIDsToElements()
-{
- static NeverDestroyed<IDToElementMap> map;
- return map;
-}
-
-HTMLMediaElement* HTMLMediaElement::elementWithID(uint64_t id)
-{
- if (id == HTMLMediaElementInvalidID)
- return nullptr;
-
- return elementIDsToElements().get(id);
-}
-
-static uint64_t nextElementID()
-{
- static uint64_t elementID = 0;
- return ++elementID;
-}
-#endif
-
HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document, bool createdByParser)
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ : HTMLFrameOwnerElement(tagName, document)
+#else
: HTMLElement(tagName, document)
+#endif
, ActiveDOMObject(&document)
- , m_pendingActionTimer(*this, &HTMLMediaElement::pendingActionTimerFired)
- , m_progressEventTimer(*this, &HTMLMediaElement::progressEventTimerFired)
- , m_playbackProgressTimer(*this, &HTMLMediaElement::playbackProgressTimerFired)
- , m_scanTimer(*this, &HTMLMediaElement::scanTimerFired)
- , m_seekTaskQueue(document)
- , m_resizeTaskQueue(document)
- , m_shadowDOMTaskQueue(document)
+ , m_loadTimer(this, &HTMLMediaElement::loadTimerFired)
+ , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
+ , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired)
, m_playedTimeRanges()
, m_asyncEventQueue(*this)
- , m_requestedPlaybackRate(1)
- , m_reportedPlaybackRate(1)
- , m_defaultPlaybackRate(1)
+ , m_playbackRate(1.0f)
+ , m_defaultPlaybackRate(1.0f)
, m_webkitPreservesPitch(true)
, m_networkState(NETWORK_EMPTY)
, m_readyState(HAVE_NOTHING)
, m_readyStateMaximum(HAVE_NOTHING)
, m_volume(1.0f)
, m_volumeInitialized(false)
+ , m_lastSeekTime(0)
, m_previousProgressTime(std::numeric_limits<double>::max())
, m_clockTimeAtLastUpdateEvent(0)
- , m_lastTimeUpdateEventMovieTime(MediaTime::positiveInfiniteTime())
+ , m_lastTimeUpdateEventMovieTime(std::numeric_limits<double>::max())
, m_loadState(WaitingForSource)
- , m_videoFullscreenMode(VideoFullscreenModeNone)
-#if PLATFORM(IOS)
- , m_videoFullscreenGravity(MediaPlayer::VideoGravityResizeAspect)
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ , m_proxyWidget(0)
#endif
, m_preload(MediaPlayer::Auto)
, m_displayMode(Unknown)
@@ -348,13 +288,12 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
#if ENABLE(MEDIA_SOURCE)
, m_droppedVideoFrames(0)
#endif
+ , m_cachedTime(MediaPlayer::invalidTime())
, m_clockTimeAtLastCachedTimeUpdate(0)
, m_minimumClockTimeToUpdateCachedTime(0)
+ , m_fragmentStartTime(MediaPlayer::invalidTime())
+ , m_fragmentEndTime(MediaPlayer::invalidTime())
, m_pendingActionFlags(0)
- , m_actionAfterScan(Nothing)
- , m_scanType(Scan)
- , m_scanDirection(Forward)
- , m_firstTimePlaying(true)
, m_playing(false)
, m_isWaitingUntilMediaCanStart(false)
, m_shouldDelayLoadEvent(false)
@@ -363,27 +302,33 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
, m_autoplaying(true)
, m_muted(false)
, m_explicitlyMuted(false)
- , m_initiallyMuted(false)
, m_paused(true)
, m_seeking(false)
, m_sentStalledEvent(false)
, m_sentEndEvent(false)
, m_pausedInternal(false)
, m_sendProgressEvents(true)
+ , m_isFullscreen(false)
, m_closedCaptionsVisible(false)
, m_webkitLegacyClosedCaptionOverride(false)
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ , m_needWidgetUpdate(false)
+#endif
, m_completelyLoaded(false)
, m_havePreparedToPlay(false)
, m_parsingInProgress(createdByParser)
- , m_elementIsHidden(document.hidden())
-#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- , m_mediaControlsDependOnPageScaleFactor(false)
+#if ENABLE(PAGE_VISIBILITY_API)
+ , m_isDisplaySleepDisablingSuspended(document.hidden())
+#endif
+#if PLATFORM(IOS)
+ , m_requestingPlay(false)
+ , m_platformLayerBorrowed(false)
#endif
#if ENABLE(VIDEO_TRACK)
, m_tracksAreReady(true)
, m_haveVisibleTextTrack(false)
, m_processingPreferenceChange(false)
- , m_lastTextTrackUpdateTime(MediaTime(-1, 1))
+ , m_lastTextTrackUpdateTime(-1)
, m_captionDisplayMode(CaptionUserPreferences::Automatic)
, m_audioTracks(0)
, m_textTracks(0)
@@ -393,75 +338,69 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
#if ENABLE(WEB_AUDIO)
, m_audioSourceNode(0)
#endif
- , m_mediaSession(std::make_unique<MediaElementSession>(*this))
+ , m_mediaSession(HTMLMediaSession::create(*this))
, m_reportedExtraMemoryCost(0)
#if ENABLE(MEDIA_STREAM)
, m_mediaStreamSrcObject(nullptr)
#endif
{
- allMediaElements().add(this);
-
- LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this);
+ LOG(Media, "HTMLMediaElement::HTMLMediaElement");
setHasCustomStyleResolveCallbacks();
- m_mediaSession->addBehaviorRestriction(MediaElementSession::RequireUserGestureForFullscreen);
- m_mediaSession->addBehaviorRestriction(MediaElementSession::RequirePageConsentToLoadMedia);
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- m_mediaSession->addBehaviorRestriction(MediaElementSession::RequireUserGestureToAutoplayToExternalDevice);
-#endif
+ m_mediaSession->addBehaviorRestriction(HTMLMediaSession::RequireUserGestureForFullscreen);
+ m_mediaSession->addBehaviorRestriction(HTMLMediaSession::RequirePageConsentToLoadMedia);
// FIXME: We should clean up and look to better merge the iOS and non-iOS code below.
Settings* settings = document.settings();
#if !PLATFORM(IOS)
- if (settings && settings->requiresUserGestureForMediaPlayback()) {
- m_mediaSession->addBehaviorRestriction(MediaElementSession::RequireUserGestureForRateChange);
- m_mediaSession->addBehaviorRestriction(MediaElementSession::RequireUserGestureForLoad);
+ document.registerForMediaVolumeCallbacks(this);
+ document.registerForPrivateBrowsingStateChangedCallbacks(this);
+
+#if ENABLE(PAGE_VISIBILITY_API)
+ document.registerForVisibilityStateChangedCallbacks(this);
+#endif
+
+ if (settings && settings->mediaPlaybackRequiresUserGesture()) {
+ m_mediaSession->addBehaviorRestriction(HTMLMediaSession::RequireUserGestureForRateChange);
+ m_mediaSession->addBehaviorRestriction(HTMLMediaSession::RequireUserGestureForLoad);
}
#else
m_sendProgressEvents = false;
- if (!settings || settings->requiresUserGestureForMediaPlayback()) {
- // Allow autoplay in a MediaDocument that is not in an iframe.
- if (document.ownerElement() || !document.isMediaDocument())
- m_mediaSession->addBehaviorRestriction(MediaElementSession::RequireUserGestureForRateChange);
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- m_mediaSession->addBehaviorRestriction(MediaElementSession::RequireUserGestureToShowPlaybackTargetPicker);
+ if (!settings || settings->mediaPlaybackRequiresUserGesture()) {
+ m_mediaSession->addBehaviorRestriction(HTMLMediaSession::RequireUserGestureForRateChange);
+#if ENABLE(IOS_AIRPLAY)
+ m_mediaSession->addBehaviorRestriction(HTMLMediaSession::RequireUserGestureToShowPlaybackTargetPicker);
#endif
- } else {
- // Relax RequireUserGestureForFullscreen when requiresUserGestureForMediaPlayback is not set:
- m_mediaSession->removeBehaviorRestriction(MediaElementSession::RequireUserGestureForFullscreen);
}
#endif // !PLATFORM(IOS)
- if (settings && settings->audioPlaybackRequiresUserGesture() && settings->requiresUserGestureForMediaPlayback())
- m_mediaSession->addBehaviorRestriction(MediaElementSession::RequireUserGestureForAudioRateChange);
+ addElementToDocumentMap(*this, document);
#if ENABLE(VIDEO_TRACK)
+ document.registerForCaptionPreferencesChangedCallbacks(this);
if (document.page())
m_captionDisplayMode = document.page()->group().captionPreferences()->captionDisplayMode();
#endif
-
-#if ENABLE(MEDIA_SESSION)
- m_elementID = nextElementID();
- elementIDsToElements().add(m_elementID, this);
-
- setSessionInternal(document.defaultMediaSession());
-#endif
-
- registerWithDocument(document);
}
HTMLMediaElement::~HTMLMediaElement()
{
- LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this);
-
- allMediaElements().remove(this);
+ LOG(Media, "HTMLMediaElement::~HTMLMediaElement");
m_asyncEventQueue.close();
+ if (m_isWaitingUntilMediaCanStart)
+ document().removeMediaCanStartListener(this);
setShouldDelayLoadEvent(false);
- unregisterWithDocument(document());
+ document().unregisterForMediaVolumeCallbacks(this);
+ document().unregisterForPrivateBrowsingStateChangedCallbacks(this);
+
+#if ENABLE(PAGE_VISIBILITY_API)
+ document().unregisterForVisibilityStateChangedCallbacks(this);
+#endif
#if ENABLE(VIDEO_TRACK)
+ document().unregisterForCaptionPreferencesChangedCallbacks(this);
if (m_audioTracks) {
m_audioTracks->clearElement();
for (unsigned i = 0; i < m_audioTracks->length(); ++i)
@@ -480,17 +419,14 @@ HTMLMediaElement::~HTMLMediaElement()
}
#endif
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent)) {
- m_hasPlaybackTargetAvailabilityListeners = false;
- m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, false);
- updateMediaState();
- }
+#if ENABLE(IOS_AIRPLAY)
+ if (m_player && !hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent))
+ m_player->setHasPlaybackTargetAvailabilityListeners(false);
#endif
if (m_mediaController) {
m_mediaController->removeMediaElement(this);
- m_mediaController = nullptr;
+ m_mediaController = 0;
}
#if ENABLE(MEDIA_SOURCE)
@@ -501,121 +437,38 @@ HTMLMediaElement::~HTMLMediaElement()
setMediaKeys(0);
#endif
-#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- if (m_isolatedWorld)
- m_isolatedWorld->clearWrappers();
-#endif
-
-#if ENABLE(MEDIA_SESSION)
- if (m_session) {
- m_session->removeMediaElement(*this);
- m_session = nullptr;
- }
-
- elementIDsToElements().remove(m_elementID);
-#endif
-
- m_seekTaskQueue.close();
+ removeElementFromDocumentMap(*this, document());
m_completelyLoaded = true;
-}
-
-void HTMLMediaElement::registerWithDocument(Document& document)
-{
- m_mediaSession->registerWithDocument(document);
-
- if (m_isWaitingUntilMediaCanStart)
- document.addMediaCanStartListener(this);
-
-#if !PLATFORM(IOS)
- document.registerForMediaVolumeCallbacks(this);
- document.registerForPrivateBrowsingStateChangedCallbacks(this);
-#endif
-
- document.registerForVisibilityStateChangedCallbacks(this);
-
-#if ENABLE(VIDEO_TRACK)
- if (m_requireCaptionPreferencesChangedCallbacks)
- document.registerForCaptionPreferencesChangedCallbacks(this);
-#endif
-
-#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- if (m_mediaControlsDependOnPageScaleFactor)
- document.registerForPageScaleFactorChangedCallbacks(this);
-#endif
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- document.registerForPageCacheSuspensionCallbacks(this);
-#endif
-
- document.registerForAllowsMediaDocumentInlinePlaybackChangedCallbacks(*this);
-
- document.addAudioProducer(this);
- addElementToDocumentMap(*this, document);
-}
-
-void HTMLMediaElement::unregisterWithDocument(Document& document)
-{
- m_mediaSession->unregisterWithDocument(document);
-
- if (m_isWaitingUntilMediaCanStart)
- document.removeMediaCanStartListener(this);
-
-#if !PLATFORM(IOS)
- document.unregisterForMediaVolumeCallbacks(this);
- document.unregisterForPrivateBrowsingStateChangedCallbacks(this);
-#endif
-
- document.unregisterForVisibilityStateChangedCallbacks(this);
-
-#if ENABLE(VIDEO_TRACK)
- if (m_requireCaptionPreferencesChangedCallbacks)
- document.unregisterForCaptionPreferencesChangedCallbacks(this);
-#endif
-
-#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- if (m_mediaControlsDependOnPageScaleFactor)
- document.unregisterForPageScaleFactorChangedCallbacks(this);
-#endif
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- document.unregisterForPageCacheSuspensionCallbacks(this);
-#endif
-
- document.unregisterForAllowsMediaDocumentInlinePlaybackChangedCallbacks(*this);
-
- document.removeAudioProducer(this);
- removeElementFromDocumentMap(*this, document);
+ if (m_player)
+ m_player->clearMediaPlayerClient();
}
void HTMLMediaElement::didMoveToNewDocument(Document* oldDocument)
{
+ if (m_isWaitingUntilMediaCanStart) {
+ if (oldDocument)
+ oldDocument->removeMediaCanStartListener(this);
+ document().addMediaCanStartListener(this);
+ }
+
if (m_shouldDelayLoadEvent) {
if (oldDocument)
oldDocument->decrementLoadEventDelayCount();
document().incrementLoadEventDelayCount();
}
- if (oldDocument)
- unregisterWithDocument(*oldDocument);
+ if (oldDocument) {
+ oldDocument->unregisterForMediaVolumeCallbacks(this);
+ removeElementFromDocumentMap(*this, *oldDocument);
+ }
- registerWithDocument(document());
+ document().registerForMediaVolumeCallbacks(this);
+ addElementToDocumentMap(*this, document());
HTMLElement::didMoveToNewDocument(oldDocument);
}
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-void HTMLMediaElement::documentWillSuspendForPageCache()
-{
- m_mediaSession->unregisterWithDocument(document());
-}
-
-void HTMLMediaElement::documentDidResumeFromPageCache()
-{
- m_mediaSession->registerWithDocument(document());
-}
-#endif
-
bool HTMLMediaElement::hasCustomFocusLogic() const
{
return true;
@@ -635,18 +488,46 @@ bool HTMLMediaElement::isMouseFocusable() const
return false;
}
+#if PLATFORM(IOS)
+bool HTMLMediaElement::parseMediaPlayerAttribute(const QualifiedName& name, const AtomicString& value)
+{
+ ASSERT(m_player);
+ if (name == data_youtube_idAttr) {
+ m_player->attributeChanged(name.toString(), value);
+ return true;
+ }
+ if (name == titleAttr) {
+ m_player->attributeChanged(name.toString(), value);
+ return true;
+ }
+
+ if (Settings* settings = document().settings()) {
+#if ENABLE(IOS_AIRPLAY)
+ if (name == webkitairplayAttr && settings->mediaPlaybackAllowsAirPlay()) {
+ m_player->attributeChanged(name.toString(), value);
+ return true;
+ }
+#endif
+ if (name == webkit_playsinlineAttr && settings->mediaPlaybackAllowsInline()) {
+ m_player->attributeChanged(name.toString(), ASCIILiteral(value.isNull() ? "false" : "true"));
+ return true;
+ }
+ }
+ return false;
+}
+#endif
+
void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == srcAttr) {
#if PLATFORM(IOS)
// Note, unless the restriction on requiring user action has been removed,
// do not begin downloading data on iOS.
- if (!value.isNull() && m_mediaSession->dataLoadingPermitted(*this))
+ if (!value.isNull() && m_mediaSession->dataLoadingPermitted(*this)) {
#else
// Trigger a reload, as long as the 'src' attribute is present.
- if (!value.isNull())
+ if (!value.isNull()) {
#endif
- {
clearMediaPlayer(LoadMediaResource);
scheduleDelayedAction(LoadMediaResource);
}
@@ -671,6 +552,66 @@ void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr
} else if (name == mediagroupAttr)
setMediaGroup(value);
+ else if (name == onabortAttr)
+ setAttributeEventListener(eventNames().abortEvent, name, value);
+ else if (name == onbeforeloadAttr)
+ setAttributeEventListener(eventNames().beforeloadEvent, name, value);
+ else if (name == oncanplayAttr)
+ setAttributeEventListener(eventNames().canplayEvent, name, value);
+ else if (name == oncanplaythroughAttr)
+ setAttributeEventListener(eventNames().canplaythroughEvent, name, value);
+ else if (name == ondurationchangeAttr)
+ setAttributeEventListener(eventNames().durationchangeEvent, name, value);
+ else if (name == onemptiedAttr)
+ setAttributeEventListener(eventNames().emptiedEvent, name, value);
+ else if (name == onendedAttr)
+ setAttributeEventListener(eventNames().endedEvent, name, value);
+ else if (name == onerrorAttr)
+ setAttributeEventListener(eventNames().errorEvent, name, value);
+ else if (name == onloadeddataAttr)
+ setAttributeEventListener(eventNames().loadeddataEvent, name, value);
+ else if (name == onloadedmetadataAttr)
+ setAttributeEventListener(eventNames().loadedmetadataEvent, name, value);
+ else if (name == onloadstartAttr)
+ setAttributeEventListener(eventNames().loadstartEvent, name, value);
+ else if (name == onpauseAttr)
+ setAttributeEventListener(eventNames().pauseEvent, name, value);
+ else if (name == onplayAttr)
+ setAttributeEventListener(eventNames().playEvent, name, value);
+ else if (name == onplayingAttr)
+ setAttributeEventListener(eventNames().playingEvent, name, value);
+ else if (name == onprogressAttr)
+ setAttributeEventListener(eventNames().progressEvent, name, value);
+ else if (name == onratechangeAttr)
+ setAttributeEventListener(eventNames().ratechangeEvent, name, value);
+ else if (name == onseekedAttr)
+ setAttributeEventListener(eventNames().seekedEvent, name, value);
+ else if (name == onseekingAttr)
+ setAttributeEventListener(eventNames().seekingEvent, name, value);
+ else if (name == onstalledAttr)
+ setAttributeEventListener(eventNames().stalledEvent, name, value);
+ else if (name == onsuspendAttr)
+ setAttributeEventListener(eventNames().suspendEvent, name, value);
+ else if (name == ontimeupdateAttr)
+ setAttributeEventListener(eventNames().timeupdateEvent, name, value);
+ else if (name == onvolumechangeAttr)
+ setAttributeEventListener(eventNames().volumechangeEvent, name, value);
+ else if (name == onwaitingAttr)
+ setAttributeEventListener(eventNames().waitingEvent, name, value);
+ else if (name == onwebkitbeginfullscreenAttr)
+ setAttributeEventListener(eventNames().webkitbeginfullscreenEvent, name, value);
+ else if (name == onwebkitendfullscreenAttr)
+ setAttributeEventListener(eventNames().webkitendfullscreenEvent, name, value);
+#if ENABLE(IOS_AIRPLAY)
+ else if (name == onwebkitcurrentplaybacktargetiswirelesschangedAttr)
+ setAttributeEventListener(eventNames().webkitcurrentplaybacktargetiswirelesschangedEvent, name, value);
+ else if (name == onwebkitplaybacktargetavailabilitychangedAttr)
+ setAttributeEventListener(eventNames().webkitplaybacktargetavailabilitychangedEvent, name, value);
+#endif
+#if PLATFORM(IOS)
+ else if (m_player && parseMediaPlayerAttribute(name, value))
+ return;
+#endif
else
HTMLElement::parseAttribute(name, value);
}
@@ -679,6 +620,13 @@ void HTMLMediaElement::finishParsingChildren()
{
HTMLElement::finishParsingChildren();
m_parsingInProgress = false;
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy()) {
+ document().updateStyleIfNeeded();
+ createMediaPlayerProxy();
+ }
+#endif
#if ENABLE(VIDEO_TRACK)
if (!RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
@@ -691,12 +639,29 @@ void HTMLMediaElement::finishParsingChildren()
bool HTMLMediaElement::rendererIsNeeded(const RenderStyle& style)
{
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy())
+ return true;
+#endif
return controls() && HTMLElement::rendererIsNeeded(style);
}
-RenderPtr<RenderElement> HTMLMediaElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLMediaElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderMedia>(*this, WTF::move(style));
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy()) {
+ // Setup the renderer if we already have a proxy widget.
+ auto mediaRenderer = createRenderer<RenderEmbeddedObject>(*this, std::move(style));
+ if (m_proxyWidget) {
+ mediaRenderer->setWidget(m_proxyWidget);
+
+ if (Frame* frame = document().frame())
+ frame->loader().client().showMediaPlayerProxyPlugin(m_proxyWidget.get());
+ }
+ return std::move(mediaRenderer);
+ }
+#endif
+ return createRenderer<RenderMedia>(*this, std::move(style));
}
bool HTMLMediaElement::childShouldCreateRenderer(const Node& child) const
@@ -718,7 +683,7 @@ bool HTMLMediaElement::childShouldCreateRenderer(const Node& child) const
Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode& insertionPoint)
{
- LOG(Media, "HTMLMediaElement::insertedInto(%p)", this);
+ LOG(Media, "HTMLMediaElement::insertedInto");
HTMLElement::insertedInto(insertionPoint);
if (insertionPoint.inDocument()) {
@@ -743,29 +708,26 @@ Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode&
void HTMLMediaElement::removedFrom(ContainerNode& insertionPoint)
{
- LOG(Media, "HTMLMediaElement::removedFrom(%p)", this);
+ LOG(Media, "HTMLMediaElement::removedFrom");
m_inActiveDocument = false;
if (insertionPoint.inDocument()) {
- if (hasMediaControls())
- mediaControls()->hide();
+ configureMediaControls();
if (m_networkState > NETWORK_EMPTY)
pause();
- if (m_videoFullscreenMode != VideoFullscreenModeNone)
+ if (m_isFullscreen)
exitFullscreen();
if (m_player) {
+ JSC::VM* vm = JSDOMWindowBase::commonVM();
+ JSC::JSLockHolder lock(vm);
+
size_t extraMemoryCost = m_player->extraMemoryCost();
- if (extraMemoryCost > m_reportedExtraMemoryCost) {
- JSC::VM& vm = JSDOMWindowBase::commonVM();
- JSC::JSLockHolder lock(vm);
-
- size_t extraMemoryCostDelta = extraMemoryCost - m_reportedExtraMemoryCost;
- m_reportedExtraMemoryCost = extraMemoryCost;
- // FIXME: Adopt reportExtraMemoryVisited, and switch to reportExtraMemoryAllocated.
- // https://bugs.webkit.org/show_bug.cgi?id=142595
- vm.heap.deprecatedReportExtraMemory(extraMemoryCostDelta);
- }
+ size_t extraMemoryCostDelta = extraMemoryCost - m_reportedExtraMemoryCost;
+ m_reportedExtraMemoryCost = extraMemoryCost;
+
+ if (extraMemoryCostDelta > 0)
+ vm->heap.reportExtraMemoryCost(extraMemoryCostDelta);
}
}
@@ -775,12 +737,23 @@ void HTMLMediaElement::removedFrom(ContainerNode& insertionPoint)
void HTMLMediaElement::willAttachRenderers()
{
ASSERT(!renderer());
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy())
+ m_needWidgetUpdate = true;
+#endif
}
void HTMLMediaElement::didAttachRenderers()
{
if (renderer())
renderer()->updateFromElement();
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ else if (m_proxyWidget) {
+ if (Frame* frame = document().frame())
+ frame->loader().client().hideMediaPlayerProxyPlugin(m_proxyWidget.get());
+ }
+#endif
}
void HTMLMediaElement::didRecalcStyle(Style::Change)
@@ -791,9 +764,14 @@ void HTMLMediaElement::didRecalcStyle(Style::Change)
void HTMLMediaElement::scheduleDelayedAction(DelayedActionType actionType)
{
- LOG(Media, "HTMLMediaElement::scheduleLoad(%p)", this);
+ LOG(Media, "HTMLMediaElement::scheduleLoad");
if ((actionType & LoadMediaResource) && !(m_pendingActionFlags & LoadMediaResource)) {
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy())
+ createMediaPlayerProxy();
+#endif
+
prepareForLoad();
setFlags(m_pendingActionFlags, LoadMediaResource);
}
@@ -808,28 +786,20 @@ void HTMLMediaElement::scheduleDelayedAction(DelayedActionType actionType)
setFlags(m_pendingActionFlags, TextTrackChangesNotification);
#endif
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- if (actionType & CheckPlaybackTargetCompatablity)
- setFlags(m_pendingActionFlags, CheckPlaybackTargetCompatablity);
-#endif
-
- if (actionType & CheckMediaState)
- setFlags(m_pendingActionFlags, CheckMediaState);
-
- m_pendingActionTimer.startOneShot(0);
+ m_loadTimer.startOneShot(0);
}
void HTMLMediaElement::scheduleNextSourceChild()
{
// Schedule the timer to try the next <source> element WITHOUT resetting state ala prepareForLoad.
setFlags(m_pendingActionFlags, LoadMediaResource);
- m_pendingActionTimer.startOneShot(0);
+ m_loadTimer.startOneShot(0);
}
void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
{
#if LOG_MEDIA_EVENTS
- LOG(Media, "HTMLMediaElement::scheduleEvent(%p) - scheduling '%s'", this, eventName.string().ascii().data());
+ LOG(Media, "HTMLMediaElement::scheduleEvent - scheduling '%s'", eventName.string().ascii().data());
#endif
RefPtr<Event> event = Event::create(eventName, false, true);
@@ -839,7 +809,7 @@ void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
m_asyncEventQueue.enqueueEvent(event.release());
}
-void HTMLMediaElement::pendingActionTimerFired()
+void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>&)
{
Ref<HTMLMediaElement> protect(*this); // loadNextSourceChild may fire 'beforeload', which can make arbitrary DOM mutations.
@@ -860,17 +830,6 @@ void HTMLMediaElement::pendingActionTimerFired()
notifyMediaPlayerOfTextTrackChanges();
#endif
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- if (m_pendingActionFlags & CheckPlaybackTargetCompatablity && m_player && m_player->isCurrentPlaybackTargetWireless() && !m_player->canPlayToWirelessPlaybackTarget()) {
- LOG(Media, "HTMLMediaElement::pendingActionTimerFired(%p) - calling setShouldPlayToPlaybackTarget(false)", this);
- m_failedToPlayToWirelessTarget = true;
- m_player->setShouldPlayToPlaybackTarget(false);
- }
-
- if (m_pendingActionFlags & CheckMediaState)
- updateMediaState();
-#endif
-
m_pendingActionFlags = 0;
}
@@ -932,25 +891,20 @@ String HTMLMediaElement::canPlayType(const String& mimeType, const String& keySy
break;
}
- LOG(Media, "HTMLMediaElement::canPlayType(%p) - [%s, %s, %s] -> %s", this, mimeType.utf8().data(), keySystem.utf8().data(), url.stringCenterEllipsizedToLength().utf8().data(), canPlay.utf8().data());
+ LOG(Media, "HTMLMediaElement::canPlayType(%s, %s, %s) -> %s", mimeType.utf8().data(), keySystem.utf8().data(), url.stringCenterEllipsizedToLength().utf8().data(), canPlay.utf8().data());
return canPlay;
}
-double HTMLMediaElement::getStartDate() const
-{
- return m_player->getStartDate().toDouble();
-}
-
void HTMLMediaElement::load()
{
Ref<HTMLMediaElement> protect(*this); // loadInternal may result in a 'beforeload' event, which can make arbitrary DOM mutations.
- LOG(Media, "HTMLMediaElement::load(%p)", this);
+ LOG(Media, "HTMLMediaElement::load()");
if (!m_mediaSession->dataLoadingPermitted(*this))
return;
- if (ScriptController::processingUserGestureForMedia())
+ if (ScriptController::processingUserGesture())
removeBehaviorsRestrictionsAfterFirstUserGesture();
prepareForLoad();
@@ -960,13 +914,11 @@ void HTMLMediaElement::load()
void HTMLMediaElement::prepareForLoad()
{
- LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this);
+ LOG(Media, "HTMLMediaElement::prepareForLoad");
// Perform the cleanup required for the resource load algorithm to run.
stopPeriodicTimers();
- m_pendingActionTimer.stop();
- // FIXME: Figure out appropriate place to reset LoadTextTrackResource if necessary and set m_pendingActionFlags to 0 here.
- m_pendingActionFlags &= ~LoadMediaResource;
+ m_loadTimer.stop();
m_sentEndEvent = false;
m_sentStalledEvent = false;
m_haveFiredLoadedData = false;
@@ -975,13 +927,9 @@ void HTMLMediaElement::prepareForLoad()
m_displayMode = Unknown;
m_currentSrc = URL();
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- m_failedToPlayToWirelessTarget = false;
-#endif
-
// 1 - Abort any already-running instance of the resource selection algorithm for this element.
m_loadState = WaitingForSource;
- m_currentSourceNode = nullptr;
+ m_currentSourceNode = 0;
// 2 - If there are any tasks from the media element's media element event task source in
// one of the task queues, then remove those tasks.
@@ -996,48 +944,30 @@ void HTMLMediaElement::prepareForLoad()
closeMediaSource();
#endif
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy()) {
+ if (m_player)
+ m_player->cancelLoad();
+ else
+ createMediaPlayerProxy();
+ } else
+#endif
createMediaPlayer();
// 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps
if (m_networkState != NETWORK_EMPTY) {
- // 4.1 - Queue a task to fire a simple event named emptied at the media element.
- scheduleEvent(eventNames().emptiedEvent);
-
- // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it.
m_networkState = NETWORK_EMPTY;
-
- // 4.3 - Forget the media element's media-resource-specific tracks.
- forgetResourceSpecificTracks();
-
- // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that state.
m_readyState = HAVE_NOTHING;
m_readyStateMaximum = HAVE_NOTHING;
-
- // 4.5 - If the paused attribute is false, then set it to true.
+ refreshCachedTime();
m_paused = true;
-
- // 4.6 - If seeking is true, set it to false.
m_seeking = false;
-
- // 4.7 - Set the current playback position to 0.
- // Set the official playback position to 0.
- // If this changed the official playback position, then queue a task to fire a simple event named timeupdate at the media element.
- // FIXME: Add support for firing this event. e.g., scheduleEvent(eventNames().timeUpdateEvent);
-
- // 4.8 - Set the initial playback position to 0.
- // FIXME: Make this less subtle. The position only becomes 0 because of the createMediaPlayer() call
- // above.
- refreshCachedTime();
-
invalidateCachedTime();
-
- // 4.9 - Set the timeline offset to Not-a-Number (NaN).
- // 4.10 - Update the duration attribute to Not-a-Number (NaN).
-
+ scheduleEvent(eventNames().emptiedEvent);
updateMediaController();
#if ENABLE(VIDEO_TRACK)
if (RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
- updateActiveTextTrackCues(MediaTime::zeroTime());
+ updateActiveTextTrackCues(0);
#endif
}
@@ -1045,7 +975,7 @@ void HTMLMediaElement::prepareForLoad()
setPlaybackRate(defaultPlaybackRate());
// 6 - Set the error attribute to null and the autoplaying flag to true.
- m_error = nullptr;
+ m_error = 0;
m_autoplaying = true;
// 7 - Invoke the media element's resource selection algorithm.
@@ -1059,10 +989,7 @@ void HTMLMediaElement::prepareForLoad()
// 2 - Asynchronously await a stable state.
m_playedTimeRanges = TimeRanges::create();
-
- // FIXME: Investigate whether these can be moved into m_networkState != NETWORK_EMPTY block above
- // so they are closer to the relevant spec steps.
- m_lastSeekTime = MediaTime::zeroTime();
+ m_lastSeekTime = 0;
// The spec doesn't say to block the load event until we actually run the asynchronous section
// algorithm, but do it now because we won't start that until after the timer fires and the
@@ -1072,7 +999,8 @@ void HTMLMediaElement::prepareForLoad()
setShouldDelayLoadEvent(true);
#if PLATFORM(IOS)
- if (effectivePreload != MediaPlayer::None && m_mediaSession->allowsAutomaticMediaDataLoading(*this))
+ Settings* settings = document().settings();
+ if (effectivePreload != MediaPlayer::None && settings && settings->mediaDataLoadsAutomatically())
prepareToPlay();
#endif
@@ -1101,7 +1029,7 @@ void HTMLMediaElement::loadInternal()
// Once the page has allowed an element to load media, it is free to load at will. This allows a
// playlist that starts in a foreground tab to continue automatically if the tab is subsequently
// put into the background.
- m_mediaSession->removeBehaviorRestriction(MediaElementSession::RequirePageConsentToLoadMedia);
+ m_mediaSession->removeBehaviorRestriction(HTMLMediaSession::RequirePageConsentToLoadMedia);
#if ENABLE(VIDEO_TRACK)
if (hasMediaControls())
@@ -1126,7 +1054,7 @@ void HTMLMediaElement::loadInternal()
void HTMLMediaElement::selectMediaResource()
{
- LOG(Media, "HTMLMediaElement::selectMediaResource(%p)", this);
+ LOG(Media, "HTMLMediaElement::selectMediaResource");
enum Mode { attribute, children };
@@ -1139,7 +1067,7 @@ void HTMLMediaElement::selectMediaResource()
if (auto firstSource = childrenOfType<HTMLSourceElement>(*this).first()) {
mode = children;
m_nextChildNodeToConsider = firstSource;
- m_currentSourceNode = nullptr;
+ m_currentSourceNode = 0;
} else {
// Otherwise the media element has neither a src attribute nor a source element
// child: set the networkState to NETWORK_EMPTY, and abort these steps; the
@@ -1148,7 +1076,7 @@ void HTMLMediaElement::selectMediaResource()
setShouldDelayLoadEvent(false);
m_networkState = NETWORK_EMPTY;
- LOG(Media, "HTMLMediaElement::selectMediaResource(%p) - nothing to load", this);
+ LOG(Media, "HTMLMediaElement::selectMediaResource, nothing to load");
return;
}
}
@@ -1169,7 +1097,7 @@ void HTMLMediaElement::selectMediaResource()
URL mediaURL = getNonEmptyURLAttribute(srcAttr);
if (mediaURL.isEmpty()) {
mediaLoadingFailed(MediaPlayer::FormatError);
- LOG(Media, "HTMLMediaElement::selectMediaResource(%p) - empty 'src'", this);
+ LOG(Media, "HTMLMediaElement::selectMediaResource, empty 'src'");
return;
}
@@ -1183,7 +1111,7 @@ void HTMLMediaElement::selectMediaResource()
// will have to pick a media engine based on the file extension.
ContentType contentType((String()));
loadResource(mediaURL, contentType, String());
- LOG(Media, "HTMLMediaElement::selectMediaResource(%p) - using 'src' attribute url", this);
+ LOG(Media, "HTMLMediaElement::selectMediaResource, using 'src' attribute url");
return;
}
@@ -1201,18 +1129,40 @@ void HTMLMediaElement::loadNextSourceChild()
return;
}
- // Recreate the media player for the new url
- createMediaPlayer();
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (!shouldUseVideoPluginProxy())
+#endif
+ // Recreate the media player for the new url
+ createMediaPlayer();
m_loadState = LoadingFromSourceElement;
loadResource(mediaURL, contentType, keySystem);
}
+static URL createFileURLForApplicationCacheResource(const String& path)
+{
+ // URL should have a function to create a url from a path, but it does not. This function
+ // is not suitable because URL::setPath uses encodeWithURLEscapeSequences, which it notes
+ // does not correctly escape '#' and '?'. This function works for our purposes because
+ // app cache media files are always created with encodeForFileName(createCanonicalUUIDString()).
+
+#if USE(CF) && PLATFORM(WIN)
+ RetainPtr<CFURLRef> cfURL = adoptCF(CFURLCreateWithFileSystemPath(0, path.createCFString().get(), kCFURLWindowsPathStyle, false));
+ URL url(cfURL.get());
+#else
+ URL url;
+
+ url.setProtocol(ASCIILiteral("file"));
+ url.setPath(path);
+#endif
+ return url;
+}
+
void HTMLMediaElement::loadResource(const URL& initialURL, ContentType& contentType, const String& keySystem)
{
ASSERT(isSafeToLoadURL(initialURL, Complain));
- LOG(Media, "HTMLMediaElement::loadResource(%p) - %s, %s, %s", this, urlForLoggingMedia(initialURL).utf8().data(), contentType.raw().utf8().data(), keySystem.utf8().data());
+ LOG(Media, "HTMLMediaElement::loadResource(%s, %s, %s)", urlForLoggingMedia(initialURL).utf8().data(), contentType.raw().utf8().data(), keySystem.utf8().data());
Frame* frame = document().frame();
if (!frame) {
@@ -1220,31 +1170,12 @@ void HTMLMediaElement::loadResource(const URL& initialURL, ContentType& contentT
return;
}
- Page* page = frame->page();
- if (!page) {
- mediaLoadingFailed(MediaPlayer::FormatError);
- return;
- }
-
URL url = initialURL;
if (!frame->loader().willLoadMediaElementURL(url)) {
mediaLoadingFailed(MediaPlayer::FormatError);
return;
}
-
-#if ENABLE(CONTENT_EXTENSIONS)
- ResourceRequest request(url);
- DocumentLoader* documentLoader = frame->loader().documentLoader();
-
- if (page->userContentController() && documentLoader)
- page->userContentController()->processContentExtensionRulesForLoad(*page, request, ResourceType::Media, *documentLoader);
-
- if (request.isNull()) {
- mediaLoadingFailed(MediaPlayer::FormatError);
- return;
- }
-#endif
-
+
// The resource fetch algorithm
m_networkState = NETWORK_LOADING;
@@ -1261,32 +1192,27 @@ void HTMLMediaElement::loadResource(const URL& initialURL, ContentType& contentT
}
}
- // Log that we started loading a media element.
- if (Frame* frame = document().frame())
- frame->mainFrame().diagnosticLoggingClient().logDiagnosticMessageWithValue(DiagnosticLoggingKeys::mediaKey(), isVideo() ? DiagnosticLoggingKeys::videoKey() : DiagnosticLoggingKeys::audioKey(), DiagnosticLoggingKeys::loadingKey(), ShouldSample::No);
-
- m_firstTimePlaying = true;
-
// Set m_currentSrc *before* changing to the cache url, the fact that we are loading from the app
// cache is an internal detail not exposed through the media element API.
m_currentSrc = url;
if (resource) {
- url = ApplicationCacheHost::createFileURL(resource->path());
- LOG(Media, "HTMLMediaElement::loadResource(%p) - will load from app cache -> %s", this, urlForLoggingMedia(url).utf8().data());
+ url = createFileURLForApplicationCacheResource(resource->path());
+ LOG(Media, "HTMLMediaElement::loadResource - will load from app cache -> %s", urlForLoggingMedia(url).utf8().data());
}
- LOG(Media, "HTMLMediaElement::loadResource(%p) - m_currentSrc -> %s", this, urlForLoggingMedia(m_currentSrc).utf8().data());
+ LOG(Media, "HTMLMediaElement::loadResource - m_currentSrc -> %s", urlForLoggingMedia(m_currentSrc).utf8().data());
#if ENABLE(MEDIA_STREAM)
if (MediaStreamRegistry::registry().lookup(url.string()))
- m_mediaSession->removeBehaviorRestriction(MediaElementSession::RequireUserGestureForRateChange);
+ m_mediaSession->removeBehaviorRestriction(HTMLMediaSession::RequireUserGestureForRateChange);
#endif
if (m_sendProgressEvents)
startProgressEventTimer();
- bool privateMode = document().page() && document().page()->usesEphemeralSession();
+ Settings* settings = document().settings();
+ bool privateMode = !settings || settings->privateBrowsingEnabled();
m_player->setPrivateBrowsingMode(privateMode);
// Reset display mode to force a recalculation of what to show because we are resetting the player.
@@ -1307,24 +1233,19 @@ void HTMLMediaElement::loadResource(const URL& initialURL, ContentType& contentT
ASSERT(!m_mediaSource);
if (url.protocolIs(mediaSourceBlobProtocol))
- m_mediaSource = MediaSource::lookup(url.string());
+ m_mediaSource = HTMLMediaSource::lookup(url.string());
if (m_mediaSource) {
if (m_mediaSource->attachToElement(this))
- m_player->load(url, contentType, m_mediaSource.get());
+ m_player->load(url, contentType, m_mediaSource);
else {
// Forget our reference to the MediaSource, so we leave it alone
// while processing remainder of load failure.
- m_mediaSource = nullptr;
+ m_mediaSource = 0;
mediaLoadingFailed(MediaPlayer::FormatError);
}
} else
#endif
-#if ENABLE(MEDIA_STREAM)
- if (m_mediaStreamSrcObject)
- m_player->load(m_mediaStreamSrcObject->privateStream());
- else
-#endif
if (!m_player->load(url, contentType, keySystem))
mediaLoadingFailed(MediaPlayer::FormatError);
@@ -1343,12 +1264,13 @@ static bool trackIndexCompare(TextTrack* a,
return a->trackIndex() - b->trackIndex() < 0;
}
-static bool eventTimeCueCompare(const std::pair<MediaTime, TextTrackCue*>& a, const std::pair<MediaTime, TextTrackCue*>& b)
+static bool eventTimeCueCompare(const std::pair<double, TextTrackCue*>& a,
+ const std::pair<double, TextTrackCue*>& b)
{
// 12 - Sort the tasks in events in ascending time order (tasks with earlier
// times first).
if (a.first != b.first)
- return a.first - b.first < MediaTime::zeroTime();
+ return a.first - b.first < 0;
// If the cues belong to different text tracks, it doesn't make sense to
// compare the two tracks by the relative cue order, so return the relative
@@ -1368,7 +1290,7 @@ static bool compareCueInterval(const CueInterval& one, const CueInterval& two)
};
-void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
+void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
{
// 4.8.10.8 Playing the media resource
@@ -1378,7 +1300,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
if (ignoreTrackDisplayUpdateRequests())
return;
- LOG(Media, "HTMLMediaElement::updateActiveTextTracks(%p)", this);
+ LOG(Media, "HTMLMediaElement::updateActiveTextTracks");
// 1 - Let current cues be a list of cues, initialized to contain all the
// cues of all the hidden, showing, or showing by default text tracks of the
@@ -1391,8 +1313,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
// whenever ... the media element's readyState is changed back to HAVE_NOTHING.
if (m_readyState != HAVE_NOTHING && m_player) {
currentCues = m_cueTree.allOverlaps(m_cueTree.createInterval(movieTime, movieTime));
- if (currentCues.size() > 1)
- std::sort(currentCues.begin(), currentCues.end(), &compareCueInterval);
+ std::sort(currentCues.begin(), currentCues.end(), &compareCueInterval);
}
CueList previousCues;
@@ -1406,7 +1327,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
// 3 - Let last time be the current playback position at the time this
// algorithm was last run for this media element, if this is not the first
// time it has run.
- MediaTime lastTime = m_lastTextTrackUpdateTime;
+ double lastTime = m_lastTextTrackUpdateTime;
// 4 - If the current playback position has, since the last time this
// algorithm was run, only changed through its usual monotonic increase
@@ -1414,13 +1335,13 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
// cues whose start times are greater than or equal to last time and whose
// end times are less than or equal to the current playback position.
// Otherwise, let missed cues be an empty list.
- if (lastTime >= MediaTime::zeroTime() && m_lastSeekTime < movieTime) {
+ if (lastTime >= 0 && m_lastSeekTime < movieTime) {
CueList potentiallySkippedCues =
m_cueTree.allOverlaps(m_cueTree.createInterval(lastTime, movieTime));
for (size_t i = 0; i < potentiallySkippedCues.size(); ++i) {
- MediaTime cueStartTime = potentiallySkippedCues[i].low();
- MediaTime cueEndTime = potentiallySkippedCues[i].high();
+ double cueStartTime = potentiallySkippedCues[i].low();
+ double cueEndTime = potentiallySkippedCues[i].high();
// Consider cues that may have been missed since the last seek time.
if (cueStartTime > std::max(m_lastSeekTime, lastTime) && cueEndTime < movieTime)
@@ -1438,7 +1359,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
// element. (In the other cases, such as explicit seeks, relevant events get
// fired as part of the overall process of changing the current playback
// position.)
- if (!m_paused && m_lastSeekTime <= lastTime)
+ if (m_lastSeekTime <= lastTime)
scheduleTimeupdateEvent(false);
// Explicitly cache vector sizes, as their content is constant from here.
@@ -1456,12 +1377,9 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
activeSetChanged = true;
for (size_t i = 0; i < currentCuesSize; ++i) {
- TextTrackCue* cue = currentCues[i].data();
-
- if (cue->isRenderable())
- toVTTCue(cue)->updateDisplayTree(movieTime);
+ currentCues[i].data()->updateDisplayTree(movieTime);
- if (!cue->isActive())
+ if (!currentCues[i].data()->isActive())
activeSetChanged = true;
}
@@ -1488,7 +1406,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
// 8 - Let events be a list of tasks, initially empty. Each task in this
// list will be associated with a text track, a text track cue, and a time,
// which are used to sort the list before the tasks are queued.
- Vector<std::pair<MediaTime, TextTrackCue*>> eventTasks;
+ Vector<std::pair<double, TextTrackCue*>> eventTasks;
// 8 - Let affected tracks be a list of text tracks, initially empty.
Vector<TextTrack*> affectedTracks;
@@ -1496,7 +1414,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
for (size_t i = 0; i < missedCuesSize; ++i) {
// 9 - For each text track cue in missed cues, prepare an event named enter
// for the TextTrackCue object with the text track cue start time.
- eventTasks.append(std::make_pair(missedCues[i].data()->startMediaTime(),
+ eventTasks.append(std::make_pair(missedCues[i].data()->startTime(),
missedCues[i].data()));
// 10 - For each text track [...] in missed cues, prepare an event
@@ -1508,8 +1426,9 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
// checked when these tasks are actually queued below. This doesn't
// affect sorting events before dispatch either, because the exit
// event has the same time as the enter event.
- if (missedCues[i].data()->startMediaTime() < missedCues[i].data()->endMediaTime())
- eventTasks.append(std::make_pair(missedCues[i].data()->endMediaTime(), missedCues[i].data()));
+ if (missedCues[i].data()->startTime() < missedCues[i].data()->endTime())
+ eventTasks.append(std::make_pair(missedCues[i].data()->endTime(),
+ missedCues[i].data()));
}
for (size_t i = 0; i < previousCuesSize; ++i) {
@@ -1517,7 +1436,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
// track cue active flag set prepare an event named exit for the
// TextTrackCue object with the text track cue end time.
if (!currentCues.contains(previousCues[i]))
- eventTasks.append(std::make_pair(previousCues[i].data()->endMediaTime(),
+ eventTasks.append(std::make_pair(previousCues[i].data()->endTime(),
previousCues[i].data()));
}
@@ -1526,7 +1445,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
// text track cue active flag set, prepare an event named enter for the
// TextTrackCue object with the text track cue start time.
if (!previousCues.contains(currentCues[i]))
- eventTasks.append(std::make_pair(currentCues[i].data()->startMediaTime(),
+ eventTasks.append(std::make_pair(currentCues[i].data()->startTime(),
currentCues[i].data()));
}
@@ -1554,7 +1473,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
event->setTarget(eventTasks[i].second);
m_asyncEventQueue.enqueueEvent(event.release());
} else {
- if (eventTasks[i].first == eventTasks[i].second->startMediaTime())
+ if (eventTasks[i].first == eventTasks[i].second->startTime())
event = Event::create(eventNames().enterEvent, false, false);
else
event = Event::create(eventNames().exitEvent, false, false);
@@ -1578,9 +1497,9 @@ void HTMLMediaElement::updateActiveTextTrackCues(const MediaTime& movieTime)
// ... if the text track has a corresponding track element, to then fire a
// simple event named cuechange at the track element as well.
- if (is<LoadableTextTrack>(*affectedTracks[i])) {
+ if (affectedTracks[i]->trackType() == TextTrack::TrackElement) {
RefPtr<Event> event = Event::create(eventNames().cuechangeEvent, false, false);
- HTMLTrackElement* trackElement = downcast<LoadableTextTrack>(*affectedTracks[i]).trackElement();
+ HTMLTrackElement* trackElement = static_cast<LoadableTextTrack*>(affectedTracks[i])->trackElement();
ASSERT(trackElement);
event->setTarget(trackElement);
@@ -1676,11 +1595,6 @@ void HTMLMediaElement::textTrackModeChanged(TextTrack* track)
if (m_textTracks && m_textTracks->contains(track))
m_textTracks->scheduleChangeEvent();
-
-#if ENABLE(AVF_CAPTIONS)
- if (track->trackType() == TextTrack::TrackElement && m_player)
- m_player->notifyTrackModeChanged();
-#endif
}
void HTMLMediaElement::videoTrackSelectedChanged(VideoTrack* track)
@@ -1707,7 +1621,7 @@ void HTMLMediaElement::endIgnoringTrackDisplayUpdateRequests()
ASSERT(m_ignoreTrackDisplayUpdate);
--m_ignoreTrackDisplayUpdate;
if (!m_ignoreTrackDisplayUpdate && m_inActiveDocument)
- updateActiveTextTrackCues(currentMediaTime());
+ updateActiveTextTrackCues(currentTime());
}
void HTMLMediaElement::textTrackAddCues(TextTrack* track, const TextTrackCueList* cues)
@@ -1727,55 +1641,38 @@ void HTMLMediaElement::textTrackRemoveCues(TextTrack*, const TextTrackCueList* c
textTrackRemoveCue(cues->item(i)->track(), cues->item(i));
}
-void HTMLMediaElement::textTrackAddCue(TextTrack* track, PassRefPtr<TextTrackCue> prpCue)
+void HTMLMediaElement::textTrackAddCue(TextTrack* track, PassRefPtr<TextTrackCue> cue)
{
if (track->mode() == TextTrack::disabledKeyword())
return;
- RefPtr<TextTrackCue> cue = prpCue;
-
// Negative duration cues need be treated in the interval tree as
// zero-length cues.
- MediaTime endTime = std::max(cue->startMediaTime(), cue->endMediaTime());
+ double endTime = std::max(cue->startTime(), cue->endTime());
- CueInterval interval = m_cueTree.createInterval(cue->startMediaTime(), endTime, cue.get());
+ CueInterval interval = m_cueTree.createInterval(cue->startTime(), endTime, cue.get());
if (!m_cueTree.contains(interval))
m_cueTree.add(interval);
- updateActiveTextTrackCues(currentMediaTime());
+ updateActiveTextTrackCues(currentTime());
}
-void HTMLMediaElement::textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue> prpCue)
+void HTMLMediaElement::textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue> cue)
{
- RefPtr<TextTrackCue> cue = prpCue;
// Negative duration cues need to be treated in the interval tree as
// zero-length cues.
- MediaTime endTime = std::max(cue->startMediaTime(), cue->endMediaTime());
+ double endTime = std::max(cue->startTime(), cue->endTime());
- CueInterval interval = m_cueTree.createInterval(cue->startMediaTime(), endTime, cue.get());
+ CueInterval interval = m_cueTree.createInterval(cue->startTime(), endTime, cue.get());
m_cueTree.remove(interval);
-#if ENABLE(WEBVTT_REGIONS)
- // Since the cue will be removed from the media element and likely the
- // TextTrack might also be destructed, notifying the region of the cue
- // removal shouldn't be done.
- if (cue->isRenderable())
- toVTTCue(cue.get())->notifyRegionWhenRemovingDisplayTree(false);
-#endif
-
size_t index = m_currentlyActiveCues.find(interval);
if (index != notFound) {
cue->setIsActive(false);
m_currentlyActiveCues.remove(index);
}
- if (cue->isRenderable())
- toVTTCue(cue.get())->removeDisplayTree();
- updateActiveTextTrackCues(currentMediaTime());
-
-#if ENABLE(WEBVTT_REGIONS)
- if (cue->isRenderable())
- toVTTCue(cue.get())->notifyRegionWhenRemovingDisplayTree(true);
-#endif
+ cue->removeDisplayTree();
+ updateActiveTextTrackCues(currentTime());
}
#endif
@@ -1783,7 +1680,7 @@ void HTMLMediaElement::textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue> p
bool HTMLMediaElement::isSafeToLoadURL(const URL& url, InvalidURLAction actionIfInvalid)
{
if (!url.isValid()) {
- LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%p) - %s -> FALSE because url is invalid", this, urlForLoggingMedia(url).utf8().data());
+ LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE because url is invalid", urlForLoggingMedia(url).utf8().data());
return false;
}
@@ -1791,12 +1688,12 @@ bool HTMLMediaElement::isSafeToLoadURL(const URL& url, InvalidURLAction actionIf
if (!frame || !document().securityOrigin()->canDisplay(url)) {
if (actionIfInvalid == Complain)
FrameLoader::reportLocalLoadFailed(frame, url.stringCenterEllipsizedToLength());
- LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%p) - %s -> FALSE rejected by SecurityOrigin", this, urlForLoggingMedia(url).utf8().data());
+ LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE rejected by SecurityOrigin", urlForLoggingMedia(url).utf8().data());
return false;
}
- if (!document().contentSecurityPolicy()->allowMediaFromSource(url, isInUserAgentShadowTree())) {
- LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%p) - %s -> rejected by Content Security Policy", this, urlForLoggingMedia(url).utf8().data());
+ if (!document().contentSecurityPolicy()->allowMediaFromSource(url)) {
+ LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> rejected by Content Security Policy", urlForLoggingMedia(url).utf8().data());
return false;
}
@@ -1815,7 +1712,7 @@ void HTMLMediaElement::startProgressEventTimer()
void HTMLMediaElement::waitForSourceChange()
{
- LOG(Media, "HTMLMediaElement::waitForSourceChange(%p)", this);
+ LOG(Media, "HTMLMediaElement::waitForSourceChange");
stopPeriodicTimers();
m_loadState = WaitingForSource;
@@ -1834,11 +1731,11 @@ void HTMLMediaElement::waitForSourceChange()
void HTMLMediaElement::noneSupported()
{
- LOG(Media, "HTMLMediaElement::noneSupported(%p)", this);
+ LOG(Media, "HTMLMediaElement::noneSupported");
stopPeriodicTimers();
m_loadState = WaitingForSource;
- m_currentSourceNode = nullptr;
+ m_currentSourceNode = 0;
// 4.8.10.5
// 6 - Reaching this step indicates that the media resource failed to load or that the given
@@ -1849,7 +1746,6 @@ void HTMLMediaElement::noneSupported()
m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
// 6.2 - Forget the media element's media-resource-specific text tracks.
- forgetResourceSpecificTracks();
// 6.3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE value.
m_networkState = NETWORK_NO_SOURCE;
@@ -1875,7 +1771,7 @@ void HTMLMediaElement::noneSupported()
void HTMLMediaElement::mediaLoadingFailedFatally(MediaPlayer::NetworkState error)
{
- LOG(Media, "HTMLMediaElement::mediaLoadingFailedFatally(%p) - error = %d", this, static_cast<int>(error));
+ LOG(Media, "HTMLMediaElement::mediaLoadingFailedFatally(%d)", static_cast<int>(error));
// 1 - The user agent should cancel the fetching process.
stopPeriodicTimers();
@@ -1906,23 +1802,23 @@ void HTMLMediaElement::mediaLoadingFailedFatally(MediaPlayer::NetworkState error
setShouldDelayLoadEvent(false);
// 6 - Abort the overall resource selection algorithm.
- m_currentSourceNode = nullptr;
-
-#if PLATFORM(COCOA)
- if (is<MediaDocument>(document()))
- downcast<MediaDocument>(document()).mediaElementSawUnsupportedTracks();
-#endif
+ m_currentSourceNode = 0;
}
void HTMLMediaElement::cancelPendingEventsAndCallbacks()
{
- LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks(%p)", this);
+ LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks");
m_asyncEventQueue.cancelAllEvents();
for (auto& source : childrenOfType<HTMLSourceElement>(*this))
source.cancelPendingErrorEvent();
}
+Document* HTMLMediaElement::mediaPlayerOwningDocument()
+{
+ return &document();
+}
+
void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
{
beginProcessingMediaPlayerCallback();
@@ -1932,22 +1828,23 @@ void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
static void logMediaLoadRequest(Page* page, const String& mediaEngine, const String& errorMessage, bool succeeded)
{
- if (!page)
+ if (!page || !page->settings().diagnosticLoggingEnabled())
return;
- DiagnosticLoggingClient& diagnosticLoggingClient = page->mainFrame().diagnosticLoggingClient();
+ ChromeClient& chromeClient = page->chrome().client();
+
if (!succeeded) {
- diagnosticLoggingClient.logDiagnosticMessageWithResult(DiagnosticLoggingKeys::mediaLoadingFailedKey(), errorMessage, DiagnosticLoggingResultFail, ShouldSample::No);
+ chromeClient.logDiagnosticMessage(DiagnosticLoggingKeys::mediaLoadingFailedKey(), errorMessage, DiagnosticLoggingKeys::failKey());
return;
}
- diagnosticLoggingClient.logDiagnosticMessage(DiagnosticLoggingKeys::mediaLoadedKey(), mediaEngine, ShouldSample::No);
+ chromeClient.logDiagnosticMessage(DiagnosticLoggingKeys::mediaLoadedKey(), mediaEngine, DiagnosticLoggingKeys::noopKey());
if (!page->hasSeenAnyMediaEngine())
- diagnosticLoggingClient.logDiagnosticMessage(DiagnosticLoggingKeys::pageContainsAtLeastOneMediaEngineKey(), emptyString(), ShouldSample::No);
+ chromeClient.logDiagnosticMessage(DiagnosticLoggingKeys::pageContainsAtLeastOneMediaEngineKey(), emptyString(), DiagnosticLoggingKeys::noopKey());
if (!page->hasSeenMediaEngine(mediaEngine))
- diagnosticLoggingClient.logDiagnosticMessage(DiagnosticLoggingKeys::pageContainsMediaEngineKey(), mediaEngine, ShouldSample::No);
+ chromeClient.logDiagnosticMessage(DiagnosticLoggingKeys::pageContainsMediaEngineKey(), mediaEngine, DiagnosticLoggingKeys::noopKey());
page->sawMediaEngine(mediaEngine);
}
@@ -1974,23 +1871,16 @@ void HTMLMediaElement::mediaLoadingFailed(MediaPlayer::NetworkState error)
// <source> children, schedule the next one
if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement) {
- // resource selection algorithm
- // Step 9.Otherwise.9 - Failed with elements: Queue a task, using the DOM manipulation task source, to fire a simple event named error at the candidate element.
if (m_currentSourceNode)
m_currentSourceNode->scheduleErrorEvent();
else
- LOG(Media, "HTMLMediaElement::setNetworkState(%p) - error event not sent, <source> was removed", this);
+ LOG(Media, "HTMLMediaElement::setNetworkState - error event not sent, <source> was removed");
- // 9.Otherwise.10 - Asynchronously await a stable state. The synchronous section consists of all the remaining steps of this algorithm until the algorithm says the synchronous section has ended.
-
- // 9.Otherwise.11 - Forget the media element's media-resource-specific tracks.
- forgetResourceSpecificTracks();
-
if (havePotentialSourceChild()) {
- LOG(Media, "HTMLMediaElement::setNetworkState(%p) - scheduling next <source>", this);
+ LOG(Media, "HTMLMediaElement::setNetworkState - scheduling next <source>");
scheduleNextSourceChild();
} else {
- LOG(Media, "HTMLMediaElement::setNetworkState(%p) - no more <source> elements, waiting", this);
+ LOG(Media, "HTMLMediaElement::setNetworkState - no more <source> elements, waiting");
waitForSourceChange();
}
@@ -2013,7 +1903,7 @@ void HTMLMediaElement::mediaLoadingFailed(MediaPlayer::NetworkState error)
void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
{
- LOG(Media, "HTMLMediaElement::setNetworkState(%p) - new state = %d, current state = %d", this, static_cast<int>(state), static_cast<int>(m_networkState));
+ LOG(Media, "HTMLMediaElement::setNetworkState(%d) - current state is %d", static_cast<int>(state), static_cast<int>(m_networkState));
if (state == MediaPlayer::Empty) {
// Just update the cached state and leave, we can't do anything.
@@ -2075,7 +1965,7 @@ void HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*)
void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
{
- LOG(Media, "HTMLMediaElement::setReadyState(%p) - new state = %d, current state = %d,", this, static_cast<int>(state), static_cast<int>(m_readyState));
+ LOG(Media, "HTMLMediaElement::setReadyState(%d) - current state is %d,", static_cast<int>(state), static_cast<int>(m_readyState));
// Set "wasPotentiallyPlaying" BEFORE updating m_readyState, potentiallyPlaying() uses it
bool wasPotentiallyPlaying = potentiallyPlaying();
@@ -2119,7 +2009,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
scheduleEvent(eventNames().waitingEvent);
// 4.8.10.10 step 14 & 15.
- if (!m_player->seeking() && m_readyState >= HAVE_CURRENT_DATA)
+ if (m_readyState >= HAVE_CURRENT_DATA)
finishSeek();
} else {
if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA) {
@@ -2134,25 +2024,12 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
prepareMediaFragmentURI();
scheduleEvent(eventNames().durationchangeEvent);
scheduleEvent(eventNames().loadedmetadataEvent);
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent))
- enqueuePlaybackTargetAvailabilityChangedEvent();
-#endif
- m_initiallyMuted = m_volume < 0.05 || muted();
-
if (hasMediaControls())
mediaControls()->loadedMetadata();
if (renderer())
renderer()->updateFromElement();
- if (is<MediaDocument>(document()))
- downcast<MediaDocument>(document()).mediaElementNaturalSizeChanged(expandedIntSize(m_player->naturalSize()));
-
logMediaLoadRequest(document().page(), m_player->engineDescription(), String(), true);
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- updateMediaState(UpdateMediaState::Asynchronously);
-#endif
}
bool shouldUpdateDisplayState = false;
@@ -2204,7 +2081,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
updateMediaController();
#if ENABLE(VIDEO_TRACK)
if (RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
- updateActiveTextTrackCues(currentMediaTime());
+ updateActiveTextTrackCues(currentTime());
#endif
}
@@ -2297,11 +2174,6 @@ bool HTMLMediaElement::mediaPlayerKeyNeeded(MediaPlayer*, const String& keySyste
#endif
#if ENABLE(ENCRYPTED_MEDIA_V2)
-RefPtr<ArrayBuffer> HTMLMediaElement::mediaPlayerCachedKeyForKeyId(const String& keyId) const
-{
- return m_mediaKeys ? m_mediaKeys->cachedKeyForKeyId(keyId) : nullptr;
-}
-
bool HTMLMediaElement::mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array* initData)
{
if (!hasEventListeners("webkitneedkey")) {
@@ -2322,23 +2194,6 @@ bool HTMLMediaElement::mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array* initData)
return true;
}
-String HTMLMediaElement::mediaPlayerMediaKeysStorageDirectory() const
-{
- Settings* settings = document().settings();
- if (!settings)
- return emptyString();
-
- String storageDirectory = settings->mediaKeysStorageDirectory();
- if (storageDirectory.isEmpty())
- return emptyString();
-
- SecurityOrigin* origin = document().securityOrigin();
- if (!origin)
- return emptyString();
-
- return pathByAppendingComponent(storageDirectory, origin->databaseIdentifier());
-}
-
void HTMLMediaElement::setMediaKeys(MediaKeys* mediaKeys)
{
if (m_mediaKeys == mediaKeys)
@@ -2350,34 +2205,9 @@ void HTMLMediaElement::setMediaKeys(MediaKeys* mediaKeys)
if (m_mediaKeys)
m_mediaKeys->setMediaElement(this);
}
-
-void HTMLMediaElement::keyAdded()
-{
- if (m_player)
- m_player->keyAdded();
-}
-#endif
-
-#if ENABLE(MEDIA_STREAM)
-String HTMLMediaElement::mediaPlayerMediaDeviceIdentifierStorageDirectory() const
-{
- Settings* settings = document().settings();
- if (!settings)
- return emptyString();
-
- String storageDirectory = settings->mediaDeviceIdentifierStorageDirectory();
- if (storageDirectory.isEmpty())
- return emptyString();
-
- SecurityOrigin* origin = document().securityOrigin();
- if (!origin)
- return emptyString();
-
- return pathByAppendingComponent(storageDirectory, origin->databaseIdentifier());
-}
#endif
-void HTMLMediaElement::progressEventTimerFired()
+void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>&)
{
ASSERT(m_player);
if (m_networkState != NETWORK_LOADING)
@@ -2403,24 +2233,29 @@ void HTMLMediaElement::progressEventTimerFired()
void HTMLMediaElement::rewind(double timeDelta)
{
- LOG(Media, "HTMLMediaElement::rewind(%p) - %f", this, timeDelta);
- setCurrentTime(std::max(currentMediaTime() - MediaTime::createWithDouble(timeDelta), minTimeSeekable()));
+ LOG(Media, "HTMLMediaElement::rewind(%f)", timeDelta);
+ setCurrentTime(std::max(currentTime() - timeDelta, minTimeSeekable()));
}
void HTMLMediaElement::returnToRealtime()
{
- LOG(Media, "HTMLMediaElement::returnToRealtime(%p)", this);
+ LOG(Media, "HTMLMediaElement::returnToRealtime");
setCurrentTime(maxTimeSeekable());
}
-void HTMLMediaElement::addPlayedRange(const MediaTime& start, const MediaTime& end)
+void HTMLMediaElement::addPlayedRange(double start, double end)
{
- LOG(Media, "HTMLMediaElement::addPlayedRange(%p) - [%s, %s]", this, toString(start).utf8().data(), toString(end).utf8().data());
+ LOG(Media, "HTMLMediaElement::addPlayedRange(%f, %f)", start, end);
if (!m_playedTimeRanges)
m_playedTimeRanges = TimeRanges::create();
- m_playedTimeRanges->ranges().add(start, end);
+ m_playedTimeRanges->add(start, end);
}
+bool HTMLMediaElement::supportsSave() const
+{
+ return m_player ? m_player->supportsSave() : false;
+}
+
bool HTMLMediaElement::supportsScanning() const
{
return m_player ? m_player->supportsScanning() : false;
@@ -2437,12 +2272,7 @@ void HTMLMediaElement::prepareToPlay()
void HTMLMediaElement::fastSeek(double time)
{
- fastSeek(MediaTime::createWithDouble(time));
-}
-
-void HTMLMediaElement::fastSeek(const MediaTime& time)
-{
- LOG(Media, "HTMLMediaElement::fastSeek(%p) - %s", this, toString(time).utf8().data());
+ LOG(Media, "HTMLMediaElement::fastSeek(%f)", time);
// 4.7.10.9 Seeking
// 9. If the approximate-for-speed flag is set, adjust the new playback position to a value that will
// allow for playback to resume promptly. If new playback position before this step is before current
@@ -2450,29 +2280,22 @@ void HTMLMediaElement::fastSeek(const MediaTime& time)
// position. Similarly, if the new playback position before this step is after current playback position,
// then the adjusted new playback position must also be after the current playback position.
refreshCachedTime();
- MediaTime delta = time - currentMediaTime();
- MediaTime negativeTolerance = delta >= MediaTime::zeroTime() ? delta : MediaTime::positiveInfiniteTime();
- MediaTime positiveTolerance = delta < MediaTime::zeroTime() ? -delta : MediaTime::positiveInfiniteTime();
-
- seekWithTolerance(time, negativeTolerance, positiveTolerance, true);
-}
+ double delta = time - currentTime();
+ double negativeTolerance = delta >= 0 ? delta : std::numeric_limits<double>::infinity();
+ double positiveTolerance = delta < 0 ? -delta : std::numeric_limits<double>::infinity();
-void HTMLMediaElement::seek(const MediaTime& time)
-{
- LOG(Media, "HTMLMediaElement::seek(%p) - %s", this, toString(time).utf8().data());
- seekWithTolerance(time, MediaTime::zeroTime(), MediaTime::zeroTime(), true);
+ seekWithTolerance(time, negativeTolerance, positiveTolerance);
}
-void HTMLMediaElement::seekInternal(const MediaTime& time)
+void HTMLMediaElement::seek(double time)
{
- LOG(Media, "HTMLMediaElement::seekInternal(%p) - %s", this, toString(time).utf8().data());
- seekWithTolerance(time, MediaTime::zeroTime(), MediaTime::zeroTime(), false);
+ LOG(Media, "HTMLMediaElement::seek(%f)", time);
+ seekWithTolerance(time, 0, 0);
}
-void HTMLMediaElement::seekWithTolerance(const MediaTime& inTime, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance, bool fromDOM)
+void HTMLMediaElement::seekWithTolerance(double time, double negativeTolerance, double positiveTolerance)
{
// 4.8.10.9 Seeking
- MediaTime time = inTime;
// 1 - Set the media element's show poster flag to false.
setDisplayMode(Video);
@@ -2487,54 +2310,27 @@ void HTMLMediaElement::seekWithTolerance(const MediaTime& inTime, const MediaTim
// Get the current time before setting m_seeking, m_lastSeekTime is returned once it is set.
refreshCachedTime();
- MediaTime now = currentMediaTime();
+ double now = currentTime();
// 3 - If the element's seeking IDL attribute is true, then another instance of this algorithm is
// already running. Abort that other instance of the algorithm without waiting for the step that
// it is running to complete.
- if (m_seekTaskQueue.hasPendingTasks()) {
- m_seekTaskQueue.cancelAllTasks();
- m_pendingSeek = nullptr;
- }
+ // Nothing specific to be done here.
// 4 - Set the seeking IDL attribute to true.
// The flag will be cleared when the engine tells us the time has actually changed.
m_seeking = true;
- if (m_playing) {
- if (m_lastSeekTime < now)
- addPlayedRange(m_lastSeekTime, now);
- }
- m_lastSeekTime = time;
// 5 - If the seek was in response to a DOM method call or setting of an IDL attribute, then continue
// the script. The remainder of these steps must be run asynchronously.
- m_pendingSeek = std::make_unique<PendingSeek>(now, time, negativeTolerance, positiveTolerance);
- if (fromDOM)
- m_seekTaskQueue.enqueueTask(std::bind(&HTMLMediaElement::seekTask, this));
- else
- seekTask();
-}
-
-void HTMLMediaElement::seekTask()
-{
- if (!m_player) {
- m_seeking = false;
- return;
- }
-
- ASSERT(m_pendingSeek);
- MediaTime now = m_pendingSeek->now;
- MediaTime time = m_pendingSeek->targetTime;
- MediaTime negativeTolerance = m_pendingSeek->negativeTolerance;
- MediaTime positiveTolerance = m_pendingSeek->positiveTolerance;
- m_pendingSeek = nullptr;
+ // Nothing to be done here.
// 6 - If the new playback position is later than the end of the media resource, then let it be the end
// of the media resource instead.
- time = std::min(time, durationMediaTime());
+ time = std::min(time, duration());
// 7 - If the new playback position is less than the earliest possible position, let it be that position instead.
- MediaTime earliestTime = m_player->startTime();
+ double earliestTime = m_player->startTime();
time = std::max(time, earliestTime);
// Ask the media engine for the time value in the movie's time scale before comparing with current time. This
@@ -2543,9 +2339,9 @@ void HTMLMediaElement::seekTask()
// not generate a timechanged callback. This means m_seeking will never be cleared and we will never
// fire a 'seeked' event.
#if !LOG_DISABLED
- MediaTime mediaTime = m_player->mediaTimeForTimeValue(time);
+ double mediaTime = m_player->mediaTimeForTimeValue(time);
if (time != mediaTime)
- LOG(Media, "HTMLMediaElement::seekTimerFired(%p) - %s - media timeline equivalent is %s", this, toString(time).utf8().data(), toString(mediaTime).utf8().data());
+ LOG(Media, "HTMLMediaElement::seek(%f) - media timeline equivalent is %f", time, mediaTime);
#endif
time = m_player->mediaTimeForTimeValue(time);
@@ -2563,7 +2359,7 @@ void HTMLMediaElement::seekTask()
#if ENABLE(MEDIA_SOURCE)
// Always notify the media engine of a seek if the source is not closed. This ensures that the source is
// always in a flushed state when the 'seeking' event fires.
- if (m_mediaSource && !m_mediaSource->isClosed())
+ if (m_mediaSource && m_mediaSource->isClosed())
noSeekRequired = false;
#endif
@@ -2576,10 +2372,14 @@ void HTMLMediaElement::seekTask()
m_seeking = false;
return;
}
- time = seekableRanges->ranges().nearest(time);
+ time = seekableRanges->nearest(time);
- m_sentEndEvent = false;
+ if (m_playing) {
+ if (m_lastSeekTime < now)
+ addPlayedRange(m_lastSeekTime, now);
+ }
m_lastSeekTime = time;
+ m_sentEndEvent = false;
// 10 - Queue a task to fire a simple event named seeking at the element.
scheduleEvent(eventNames().seekingEvent);
@@ -2594,7 +2394,12 @@ void HTMLMediaElement::seekTask()
void HTMLMediaElement::finishSeek()
{
- LOG(Media, "HTMLMediaElement::finishSeek(%p)", this);
+ LOG(Media, "HTMLMediaElement::finishSeek");
+
+#if ENABLE(MEDIA_SOURCE)
+ if (m_mediaSource)
+ m_mediaSource->monitorSourceBuffers();
+#endif
// 4.8.10.9 Seeking
// 14 - Set the seeking IDL attribute to false.
@@ -2608,11 +2413,6 @@ void HTMLMediaElement::finishSeek()
// 17 - Queue a task to fire a simple event named seeked at the element.
scheduleEvent(eventNames().seekedEvent);
-
-#if ENABLE(MEDIA_SOURCE)
- if (m_mediaSource)
- m_mediaSource->monitorSourceBuffers();
-#endif
}
HTMLMediaElement::ReadyState HTMLMediaElement::readyState() const
@@ -2641,25 +2441,12 @@ void HTMLMediaElement::refreshCachedTime() const
return;
m_cachedTime = m_player->currentTime();
- if (!m_cachedTime) {
- // Do not use m_cachedTime until the media engine returns a non-zero value because we can't
- // estimate current time until playback actually begins.
- invalidateCachedTime();
- return;
- }
-
m_clockTimeAtLastCachedTimeUpdate = monotonicallyIncreasingTime();
}
-void HTMLMediaElement::invalidateCachedTime() const
+void HTMLMediaElement::invalidateCachedTime()
{
- if (!m_player || !m_player->maximumDurationToCacheMediaTime())
- return;
-
-#if !LOG_DISABLED
- if (m_cachedTime.isValid())
- LOG(Media, "HTMLMediaElement::invalidateCachedTime(%p)", this);
-#endif
+ LOG(Media, "HTMLMediaElement::invalidateCachedTime");
// Don't try to cache movie time when playback first starts as the time reported by the engine
// sometimes fluctuates for a short amount of time, so the cached time will be off if we take it
@@ -2667,34 +2454,29 @@ void HTMLMediaElement::invalidateCachedTime() const
static const double minimumTimePlayingBeforeCacheSnapshot = 0.5;
m_minimumClockTimeToUpdateCachedTime = monotonicallyIncreasingTime() + minimumTimePlayingBeforeCacheSnapshot;
- m_cachedTime = MediaTime::invalidTime();
+ m_cachedTime = MediaPlayer::invalidTime();
}
// playback state
double HTMLMediaElement::currentTime() const
{
- return currentMediaTime().toDouble();
-}
-
-MediaTime HTMLMediaElement::currentMediaTime() const
-{
#if LOG_CACHED_TIME_WARNINGS
- static const MediaTime minCachedDeltaForWarning = MediaTime::create(1, 100);
+ static const double minCachedDeltaForWarning = 0.01;
#endif
if (!m_player)
- return MediaTime::zeroTime();
+ return 0;
if (m_seeking) {
- LOG(Media, "HTMLMediaElement::currentTime(%p) - seeking, returning %s", this, toString(m_lastSeekTime).utf8().data());
+ LOG(Media, "HTMLMediaElement::currentTime - seeking, returning %f", m_lastSeekTime);
return m_lastSeekTime;
}
- if (m_cachedTime.isValid() && m_paused) {
+ if (m_cachedTime != MediaPlayer::invalidTime() && m_paused) {
#if LOG_CACHED_TIME_WARNINGS
- MediaTime delta = m_cachedTime - m_player->currentTime();
+ double delta = m_cachedTime - m_player->currentTime();
if (delta > minCachedDeltaForWarning)
- LOG(Media, "HTMLMediaElement::currentTime(%p) - WARNING, cached time is %s seconds off of media time when paused", this, toString(delta).utf8().data());
+ LOG(Media, "HTMLMediaElement::currentTime - WARNING, cached time is %f seconds off of media time when paused", delta);
#endif
return m_cachedTime;
}
@@ -2703,17 +2485,17 @@ MediaTime HTMLMediaElement::currentMediaTime() const
double now = monotonicallyIncreasingTime();
double maximumDurationToCacheMediaTime = m_player->maximumDurationToCacheMediaTime();
- if (maximumDurationToCacheMediaTime && m_cachedTime.isValid() && !m_paused && now > m_minimumClockTimeToUpdateCachedTime) {
+ if (maximumDurationToCacheMediaTime && m_cachedTime != MediaPlayer::invalidTime() && !m_paused && now > m_minimumClockTimeToUpdateCachedTime) {
double clockDelta = now - m_clockTimeAtLastCachedTimeUpdate;
// Not too soon, use the cached time only if it hasn't expired.
if (clockDelta < maximumDurationToCacheMediaTime) {
- MediaTime adjustedCacheTime = m_cachedTime + MediaTime::createWithDouble(effectivePlaybackRate() * clockDelta);
+ double adjustedCacheTime = m_cachedTime + (m_playbackRate * clockDelta);
#if LOG_CACHED_TIME_WARNINGS
- MediaTime delta = adjustedCacheTime - m_player->currentTime();
+ double delta = adjustedCacheTime - m_player->currentTime();
if (delta > minCachedDeltaForWarning)
- LOG(Media, "HTMLMediaElement::currentTime(%p) - WARNING, cached time is %f seconds off of media time when playing", this, delta);
+ LOG(Media, "HTMLMediaElement::currentTime - WARNING, cached time is %f seconds off of media time when playing", delta);
#endif
return adjustedCacheTime;
}
@@ -2722,55 +2504,30 @@ MediaTime HTMLMediaElement::currentMediaTime() const
#if LOG_CACHED_TIME_WARNINGS
if (maximumDurationToCacheMediaTime && now > m_minimumClockTimeToUpdateCachedTime && m_cachedTime != MediaPlayer::invalidTime()) {
double clockDelta = now - m_clockTimeAtLastCachedTimeUpdate;
- MediaTime delta = m_cachedTime + MediaTime::createWithDouble(effectivePlaybackRate() * clockDelta) - m_player->currentTime();
- LOG(Media, "HTMLMediaElement::currentTime(%p) - cached time was %s seconds off of media time when it expired", this, toString(delta).utf8().data());
+ double delta = m_cachedTime + (m_playbackRate * clockDelta) - m_player->currentTime();
+ LOG(Media, "HTMLMediaElement::currentTime - cached time was %f seconds off of media time when it expired", delta);
}
#endif
refreshCachedTime();
- if (m_cachedTime.isInvalid())
- return MediaTime::zeroTime();
-
return m_cachedTime;
}
void HTMLMediaElement::setCurrentTime(double time)
{
- setCurrentTime(MediaTime::createWithDouble(time));
-}
-
-void HTMLMediaElement::setCurrentTime(const MediaTime& time)
-{
if (m_mediaController)
return;
- seekInternal(time);
-}
-
-void HTMLMediaElement::setCurrentTime(double time, ExceptionCode& ec)
-{
- // On setting, if the media element has a current media controller, then the user agent must
- // throw an InvalidStateError exception
- if (m_mediaController) {
- ec = INVALID_STATE_ERR;
- return;
- }
-
- seek(MediaTime::createWithDouble(time));
+ seek(time);
}
double HTMLMediaElement::duration() const
{
- return durationMediaTime().toDouble();
-}
-
-MediaTime HTMLMediaElement::durationMediaTime() const
-{
if (m_player && m_readyState >= HAVE_METADATA)
return m_player->duration();
- return MediaTime::invalidTime();
+ return std::numeric_limits<double>::quiet_NaN();
}
bool HTMLMediaElement::paused() const
@@ -2793,36 +2550,25 @@ double HTMLMediaElement::defaultPlaybackRate() const
void HTMLMediaElement::setDefaultPlaybackRate(double rate)
{
if (m_defaultPlaybackRate != rate) {
- LOG(Media, "HTMLMediaElement::setDefaultPlaybackRate(%p) - %f", this, rate);
m_defaultPlaybackRate = rate;
scheduleEvent(eventNames().ratechangeEvent);
}
}
-double HTMLMediaElement::effectivePlaybackRate() const
-{
- return m_mediaController ? m_mediaController->playbackRate() : m_reportedPlaybackRate;
-}
-
-double HTMLMediaElement::requestedPlaybackRate() const
-{
- return m_mediaController ? m_mediaController->playbackRate() : m_requestedPlaybackRate;
-}
-
double HTMLMediaElement::playbackRate() const
{
- return m_requestedPlaybackRate;
+ return m_playbackRate;
}
void HTMLMediaElement::setPlaybackRate(double rate)
{
- LOG(Media, "HTMLMediaElement::setPlaybackRate(%p) - %f", this, rate);
+ LOG(Media, "HTMLMediaElement::setPlaybackRate(%f)", rate);
if (m_player && potentiallyPlaying() && m_player->rate() != rate && !m_mediaController)
m_player->setRate(rate);
- if (m_requestedPlaybackRate != rate) {
- m_reportedPlaybackRate = m_requestedPlaybackRate = rate;
+ if (m_playbackRate != rate) {
+ m_playbackRate = rate;
invalidateCachedTime();
scheduleEvent(eventNames().ratechangeEvent);
}
@@ -2830,9 +2576,9 @@ void HTMLMediaElement::setPlaybackRate(double rate)
void HTMLMediaElement::updatePlaybackRate()
{
- double requestedRate = requestedPlaybackRate();
- if (m_player && potentiallyPlaying() && m_player->rate() != requestedRate)
- m_player->setRate(requestedRate);
+ double effectiveRate = m_mediaController ? m_mediaController->playbackRate() : m_playbackRate;
+ if (m_player && potentiallyPlaying() && m_player->rate() != effectiveRate)
+ m_player->setRate(effectiveRate);
}
bool HTMLMediaElement::webkitPreservesPitch() const
@@ -2842,7 +2588,7 @@ bool HTMLMediaElement::webkitPreservesPitch() const
void HTMLMediaElement::setWebkitPreservesPitch(bool preservesPitch)
{
- LOG(Media, "HTMLMediaElement::setWebkitPreservesPitch(%p) - %s", this, boolString(preservesPitch));
+ LOG(Media, "HTMLMediaElement::setWebkitPreservesPitch(%s)", boolString(preservesPitch));
m_webkitPreservesPitch = preservesPitch;
@@ -2857,11 +2603,21 @@ bool HTMLMediaElement::ended() const
// 4.8.10.8 Playing the media resource
// The ended attribute must return true if the media element has ended
// playback and the direction of playback is forwards, and false otherwise.
- return endedPlayback() && requestedPlaybackRate() > 0;
+ return endedPlayback() && m_playbackRate > 0;
}
bool HTMLMediaElement::autoplay() const
{
+#if PLATFORM(IOS)
+ // Unless the restriction on requiring user actions has been lifted, we do not
+ // allow playback to start just because the page has "autoplay". They are either
+ // lifted through Settings, or once the user explictly calls load() or play()
+ // because they have OK'ed us loading data. This allows playback to continue if
+ // the URL is changed while the movie is playing.
+ if (!m_mediaSession->playbackPermitted(*this) || !m_mediaSession->dataLoadingPermitted(*this))
+ return false;
+#endif
+
return fastHasAttribute(autoplayAttr);
}
@@ -2870,10 +2626,13 @@ String HTMLMediaElement::preload() const
switch (m_preload) {
case MediaPlayer::None:
return ASCIILiteral("none");
+ break;
case MediaPlayer::MetaData:
return ASCIILiteral("metadata");
+ break;
case MediaPlayer::Auto:
return ASCIILiteral("auto");
+ break;
}
ASSERT_NOT_REACHED();
@@ -2882,37 +2641,37 @@ String HTMLMediaElement::preload() const
void HTMLMediaElement::setPreload(const String& preload)
{
- LOG(Media, "HTMLMediaElement::setPreload(%p) - %s", this, preload.utf8().data());
+ LOG(Media, "HTMLMediaElement::setPreload(%s)", preload.utf8().data());
setAttribute(preloadAttr, preload);
}
void HTMLMediaElement::play()
{
- LOG(Media, "HTMLMediaElement::play(%p)", this);
+ LOG(Media, "HTMLMediaElement::play()");
if (!m_mediaSession->playbackPermitted(*this))
return;
- if (ScriptController::processingUserGestureForMedia())
+ if (ScriptController::processingUserGesture())
removeBehaviorsRestrictionsAfterFirstUserGesture();
+ if (m_mediaSession->state() == MediaSession::Interrupted) {
+ m_resumePlaybackAfterInterruption = true;
+ return;
+ }
+
playInternal();
}
void HTMLMediaElement::playInternal()
{
- LOG(Media, "HTMLMediaElement::playInternal(%p)", this);
-
- if (!m_mediaSession->clientWillBeginPlayback()) {
- LOG(Media, " returning because of interruption");
- return;
- }
+ LOG(Media, "HTMLMediaElement::playInternal");
// 4.8.10.9. Playing the media resource
if (!m_player || m_networkState == NETWORK_EMPTY)
scheduleDelayedAction(LoadMediaResource);
if (endedPlayback())
- seekInternal(MediaTime::zeroTime());
+ seek(0);
if (m_mediaController)
m_mediaController->bringElementUpToSpeed(this);
@@ -2926,64 +2685,43 @@ void HTMLMediaElement::playInternal()
scheduleEvent(eventNames().waitingEvent);
else if (m_readyState >= HAVE_FUTURE_DATA)
scheduleEvent(eventNames().playingEvent);
-
-#if ENABLE(MEDIA_SESSION)
- // 6.3 Activating a media session from a media element
- // When the play() method is invoked, the paused attribute is true, and the readyState attribute has the value
- // HAVE_FUTURE_DATA or HAVE_ENOUGH_DATA, then
- // 1. Let media session be the value of the current media session.
- // 2. If we are not currently in media session's list of active participating media elements then append
- // ourselves to this list.
- // 3. Let activated be the result of running the media session invocation algorithm for media session.
- // 4. If activated is failure, pause ourselves.
- if (m_readyState == HAVE_ENOUGH_DATA || m_readyState == HAVE_FUTURE_DATA) {
- if (m_session) {
- m_session->addActiveMediaElement(*this);
-
- if (m_session->kindEnum() == MediaSession::Kind::Content) {
- if (Page* page = document().page())
- page->chrome().client().focusedContentMediaElementDidChange(m_elementID);
- }
-
- if (!m_session->invoke()) {
- pause();
- return;
- }
- }
- }
-#endif
}
m_autoplaying = false;
+#if PLATFORM(IOS)
+ m_requestingPlay = true;
+#endif
updatePlayState();
updateMediaController();
}
void HTMLMediaElement::pause()
{
- LOG(Media, "HTMLMediaElement::pause(%p)", this);
+ LOG(Media, "HTMLMediaElement::pause()");
if (!m_mediaSession->playbackPermitted(*this))
return;
+ if (m_mediaSession->state() == MediaSession::Interrupted) {
+ m_resumePlaybackAfterInterruption = false;
+ return;
+ }
+
pauseInternal();
}
void HTMLMediaElement::pauseInternal()
{
- LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this);
-
- if (!m_mediaSession->clientWillPausePlayback()) {
- LOG(Media, " returning because of interruption");
- return;
- }
+ LOG(Media, "HTMLMediaElement::pauseInternal");
// 4.8.10.9. Playing the media resource
if (!m_player || m_networkState == NETWORK_EMPTY) {
+#if PLATFORM(IOS)
// Unless the restriction on media requiring user action has been lifted
// don't trigger loading if a script calls pause().
if (!m_mediaSession->playbackPermitted(*this))
return;
+#endif
scheduleDelayedAction(LoadMediaResource);
}
@@ -2993,9 +2731,6 @@ void HTMLMediaElement::pauseInternal()
m_paused = true;
scheduleTimeupdateEvent(false);
scheduleEvent(eventNames().pauseEvent);
-
- if (MemoryPressureHandler::singleton().isUnderMemoryPressure())
- purgeBufferedDataIfPossible();
}
updatePlayState();
@@ -3008,7 +2743,7 @@ void HTMLMediaElement::closeMediaSource()
return;
m_mediaSource->close();
- m_mediaSource = nullptr;
+ m_mediaSource = 0;
}
#endif
@@ -3018,7 +2753,7 @@ void HTMLMediaElement::webkitGenerateKeyRequest(const String& keySystem, PassRef
#if ENABLE(ENCRYPTED_MEDIA_V2)
static bool firstTime = true;
if (firstTime && scriptExecutionContext()) {
- scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, ASCIILiteral("'HTMLMediaElement.webkitGenerateKeyRequest()' is deprecated. Use 'MediaKeys.createSession()' instead."));
+ scriptExecutionContext()->addConsoleMessage(JSMessageSource, WarningMessageLevel, "'HTMLMediaElement.webkitGenerateKeyRequest()' is deprecated. Use 'MediaKeys.createSession()' instead.");
firstTime = false;
}
#endif
@@ -3054,7 +2789,7 @@ void HTMLMediaElement::webkitAddKey(const String& keySystem, PassRefPtr<Uint8Arr
#if ENABLE(ENCRYPTED_MEDIA_V2)
static bool firstTime = true;
if (firstTime && scriptExecutionContext()) {
- scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, ASCIILiteral("'HTMLMediaElement.webkitAddKey()' is deprecated. Use 'MediaKeySession.update()' instead."));
+ scriptExecutionContext()->addConsoleMessage(JSMessageSource, WarningMessageLevel, "'HTMLMediaElement.webkitAddKey()' is deprecated. Use 'MediaKeySession.update()' instead.");
firstTime = false;
}
#endif
@@ -3120,7 +2855,7 @@ bool HTMLMediaElement::loop() const
void HTMLMediaElement::setLoop(bool b)
{
- LOG(Media, "HTMLMediaElement::setLoop(%p) - %s", this, boolString(b));
+ LOG(Media, "HTMLMediaElement::setLoop(%s)", boolString(b));
setBooleanAttribute(loopAttr, b);
}
@@ -3132,12 +2867,20 @@ bool HTMLMediaElement::controls() const
if (frame && !frame->script().canExecuteScripts(NotAboutToExecuteScript))
return true;
+ // always show controls for video when fullscreen playback is required.
+ if (isVideo() && document().page() && document().page()->chrome().requiresFullscreenForVideoPlayback())
+ return true;
+
+ // Always show controls when in full screen mode.
+ if (isFullscreen())
+ return true;
+
return fastHasAttribute(controlsAttr);
}
void HTMLMediaElement::setControls(bool b)
{
- LOG(Media, "HTMLMediaElement::setControls(%p) - %s", this, boolString(b));
+ LOG(Media, "HTMLMediaElement::setControls(%s)", boolString(b));
setBooleanAttribute(controlsAttr, b);
}
@@ -3148,7 +2891,7 @@ double HTMLMediaElement::volume() const
void HTMLMediaElement::setVolume(double vol, ExceptionCode& ec)
{
- LOG(Media, "HTMLMediaElement::setVolume(%p) - %f", this, vol);
+ LOG(Media, "HTMLMediaElement::setVolume(%f)", vol);
if (vol < 0.0f || vol > 1.0f) {
ec = INDEX_SIZE_ERR;
@@ -3172,7 +2915,7 @@ bool HTMLMediaElement::muted() const
void HTMLMediaElement::setMuted(bool muted)
{
- LOG(Media, "HTMLMediaElement::setMuted(%p) - %s", this, boolString(muted));
+ LOG(Media, "HTMLMediaElement::setMuted(%s)", boolString(muted));
#if PLATFORM(IOS)
UNUSED_PARAM(muted);
@@ -3183,29 +2926,19 @@ void HTMLMediaElement::setMuted(bool muted)
// Avoid recursion when the player reports volume changes.
if (!processingMediaPlayerCallback()) {
if (m_player) {
- m_player->setMuted(effectiveMuted());
+ m_player->setMuted(m_muted);
if (hasMediaControls())
mediaControls()->changedMute();
}
}
scheduleEvent(eventNames().volumechangeEvent);
-
-#if ENABLE(MEDIA_SESSION)
- document().updateIsPlayingMedia(m_elementID);
-#else
- document().updateIsPlayingMedia();
-#endif
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- updateMediaState(UpdateMediaState::Asynchronously);
-#endif
}
#endif
}
void HTMLMediaElement::togglePlayState()
{
- LOG(Media, "HTMLMediaElement::togglePlayState(%p) - canPlay() is %s", this, boolString(canPlay()));
+ LOG(Media, "HTMLMediaElement::togglePlayState - canPlay() is %s", boolString(canPlay()));
// We can safely call the internal play/pause methods, which don't check restrictions, because
// this method is only called from the built-in media controller
@@ -3218,7 +2951,7 @@ void HTMLMediaElement::togglePlayState()
void HTMLMediaElement::beginScrubbing()
{
- LOG(Media, "HTMLMediaElement::beginScrubbing(%p) - paused() is %s", this, boolString(paused()));
+ LOG(Media, "HTMLMediaElement::beginScrubbing - paused() is %s", boolString(paused()));
if (!paused()) {
if (ended()) {
@@ -3237,65 +2970,12 @@ void HTMLMediaElement::beginScrubbing()
void HTMLMediaElement::endScrubbing()
{
- LOG(Media, "HTMLMediaElement::endScrubbing(%p) - m_pausedInternal is %s", this, boolString(m_pausedInternal));
+ LOG(Media, "HTMLMediaElement::endScrubbing - m_pausedInternal is %s", boolString(m_pausedInternal));
if (m_pausedInternal)
setPausedInternal(false);
}
-void HTMLMediaElement::beginScanning(ScanDirection direction)
-{
- m_scanType = supportsScanning() ? Scan : Seek;
- m_scanDirection = direction;
-
- if (m_scanType == Seek) {
- // Scanning by seeking requires the video to be paused during scanning.
- m_actionAfterScan = paused() ? Nothing : Play;
- pause();
- } else {
- // Scanning by scanning requires the video to be playing during scanninging.
- m_actionAfterScan = paused() ? Pause : Nothing;
- play();
- setPlaybackRate(nextScanRate());
- }
-
- m_scanTimer.start(0, m_scanType == Seek ? SeekRepeatDelay : ScanRepeatDelay);
-}
-
-void HTMLMediaElement::endScanning()
-{
- if (m_scanType == Scan)
- setPlaybackRate(defaultPlaybackRate());
-
- if (m_actionAfterScan == Play)
- play();
- else if (m_actionAfterScan == Pause)
- pause();
-
- if (m_scanTimer.isActive())
- m_scanTimer.stop();
-}
-
-double HTMLMediaElement::nextScanRate()
-{
- double rate = std::min(ScanMaximumRate, fabs(playbackRate() * 2));
- if (m_scanDirection == Backward)
- rate *= -1;
-#if PLATFORM(IOS)
- rate = std::min(std::max(rate, minFastReverseRate()), maxFastForwardRate());
-#endif
- return rate;
-}
-
-void HTMLMediaElement::scanTimerFired()
-{
- if (m_scanType == Seek) {
- double seekTime = m_scanDirection == Forward ? SeekTime : -SeekTime;
- setCurrentTime(currentTime() + seekTime);
- } else
- setPlaybackRate(nextScanRate());
-}
-
// The spec says to fire periodic timeupdate events (those sent while playing) every
// "15 to 250ms", we choose the slowest frequency
static const double maxTimeupdateEventFrequency = 0.25;
@@ -3309,12 +2989,12 @@ void HTMLMediaElement::startPlaybackProgressTimer()
m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency);
}
-void HTMLMediaElement::playbackProgressTimerFired()
+void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>&)
{
ASSERT(m_player);
- if (m_fragmentEndTime.isValid() && currentMediaTime() >= m_fragmentEndTime && requestedPlaybackRate() > 0) {
- m_fragmentEndTime = MediaTime::invalidTime();
+ if (m_fragmentEndTime != MediaPlayer::invalidTime() && currentTime() >= m_fragmentEndTime && m_playbackRate > 0) {
+ m_fragmentEndTime = MediaPlayer::invalidTime();
if (!m_mediaController && !m_paused) {
// changes paused to true and fires a simple event named pause at the media element.
pauseInternal();
@@ -3323,7 +3003,7 @@ void HTMLMediaElement::playbackProgressTimerFired()
scheduleTimeupdateEvent(true);
- if (!requestedPlaybackRate())
+ if (!m_playbackRate)
return;
if (!m_paused && hasMediaControls())
@@ -3331,7 +3011,7 @@ void HTMLMediaElement::playbackProgressTimerFired()
#if ENABLE(VIDEO_TRACK)
if (RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
- updateActiveTextTrackCues(currentMediaTime());
+ updateActiveTextTrackCues(currentTime());
#endif
#if ENABLE(MEDIA_SOURCE)
@@ -3351,7 +3031,7 @@ void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent)
// Some media engines make multiple "time changed" callbacks at the same time, but we only want one
// event at a given time so filter here
- MediaTime movieTime = currentMediaTime();
+ double movieTime = currentTime();
if (movieTime != m_lastTimeUpdateEventMovieTime) {
scheduleEvent(eventNames().timeupdateEvent);
m_clockTimeAtLastUpdateEvent = now;
@@ -3368,29 +3048,25 @@ double HTMLMediaElement::percentLoaded() const
{
if (!m_player)
return 0;
- MediaTime duration = m_player->duration();
+ double duration = m_player->duration();
- if (!duration || duration.isPositiveInfinite() || duration.isNegativeInfinite())
+ if (!duration || std::isinf(duration))
return 0;
- MediaTime buffered = MediaTime::zeroTime();
- bool ignored;
- std::unique_ptr<PlatformTimeRanges> timeRanges = m_player->buffered();
+ double buffered = 0;
+ RefPtr<TimeRanges> timeRanges = m_player->buffered();
for (unsigned i = 0; i < timeRanges->length(); ++i) {
- MediaTime start = timeRanges->start(i, ignored);
- MediaTime end = timeRanges->end(i, ignored);
+ double start = timeRanges->start(i, IGNORE_EXCEPTION);
+ double end = timeRanges->end(i, IGNORE_EXCEPTION);
buffered += end - start;
}
- return buffered.toDouble() / duration.toDouble();
+ return buffered / duration;
}
#if ENABLE(VIDEO_TRACK)
void HTMLMediaElement::mediaPlayerDidAddAudioTrack(PassRefPtr<AudioTrackPrivate> prpTrack)
{
- if (isPlaying() && !m_mediaSession->playbackPermitted(*this))
- pauseInternal();
-
if (!RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
return;
@@ -3551,11 +3227,6 @@ void HTMLMediaElement::addTextTrack(PassRefPtr<TextTrack> track)
if (!RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
return;
- if (!m_requireCaptionPreferencesChangedCallbacks) {
- m_requireCaptionPreferencesChangedCallbacks = true;
- document().registerForCaptionPreferencesChangedCallbacks(this);
- }
-
textTracks()->append(track);
closeCaptionTracksChanged();
@@ -3577,17 +3248,17 @@ void HTMLMediaElement::removeAudioTrack(AudioTrack* track)
m_audioTracks->remove(track);
}
-void HTMLMediaElement::removeTextTrack(TextTrack* track, bool scheduleEvent)
+void HTMLMediaElement::removeTextTrack(TextTrack* track)
{
if (!RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
return;
TrackDisplayUpdateScope scope(this);
- if (TextTrackCueList* cues = track->cues())
+ TextTrackCueList* cues = track->cues();
+ if (cues)
textTrackRemoveCues(track, cues);
track->clearClient();
- if (m_textTracks)
- m_textTracks->remove(track, scheduleEvent);
+ m_textTracks->remove(track);
closeCaptionTracksChanged();
}
@@ -3600,7 +3271,7 @@ void HTMLMediaElement::removeVideoTrack(VideoTrack* track)
m_videoTracks->remove(track);
}
-void HTMLMediaElement::forgetResourceSpecificTracks()
+void HTMLMediaElement::removeAllInbandTracks()
{
while (m_audioTracks && m_audioTracks->length())
removeAudioTrack(m_audioTracks->lastItem());
@@ -3611,7 +3282,7 @@ void HTMLMediaElement::forgetResourceSpecificTracks()
TextTrack* track = m_textTracks->item(i);
if (track->trackType() == TextTrack::InBand)
- removeTextTrack(track, false);
+ removeTextTrack(track);
}
}
@@ -3725,7 +3396,7 @@ void HTMLMediaElement::didRemoveTextTrack(HTMLTrackElement* trackElement)
#if !LOG_DISABLED
if (trackElement->hasTagName(trackTag)) {
URL url = trackElement->getNonEmptyURLAttribute(srcAttr);
- LOG(Media, "HTMLMediaElement::didRemoveTrack(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data());
+ LOG(Media, "HTMLMediaElement::didRemoveTrack - 'src' is %s", urlForLoggingMedia(url).utf8().data());
}
#endif
@@ -3753,10 +3424,10 @@ void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
{
ASSERT(group.tracks.size());
- LOG(Media, "HTMLMediaElement::configureTextTrackGroup(%p)", this);
+ LOG(Media, "HTMLMediaElement::configureTextTrackGroup");
Page* page = document().page();
- CaptionUserPreferences* captionPreferences = page ? page->group().captionPreferences() : 0;
+ CaptionUserPreferences* captionPreferences = page? page->group().captionPreferences() : 0;
CaptionUserPreferences::CaptionDisplayMode displayMode = captionPreferences ? captionPreferences->captionDisplayMode() : CaptionUserPreferences::Automatic;
// First, find the track in the group that should be enabled (if any).
@@ -3767,15 +3438,6 @@ void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
RefPtr<TextTrack> forcedSubitleTrack;
int highestTrackScore = 0;
int highestForcedScore = 0;
-
- // If there is a visible track, it has already been configured so it won't be considered in the loop below. We don't want to choose another
- // track if it is less suitable, and we do want to disable it if another track is more suitable.
- int alreadyVisibleTrackScore = 0;
- if (group.visibleTrack && captionPreferences) {
- alreadyVisibleTrackScore = captionPreferences->textTrackSelectionScore(group.visibleTrack.get(), this);
- currentlyEnabledTracks.append(group.visibleTrack);
- }
-
for (size_t i = 0; i < group.tracks.size(); ++i) {
RefPtr<TextTrack> textTrack = group.tracks[i];
@@ -3783,7 +3445,7 @@ void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
currentlyEnabledTracks.append(textTrack);
int trackScore = captionPreferences ? captionPreferences->textTrackSelectionScore(textTrack.get(), this) : 0;
- LOG(Media, "HTMLMediaElement::configureTextTrackGroup(%p) - '%s' track with language '%s' has score %i", this, textTrack->kind().string().utf8().data(), textTrack->language().string().utf8().data(), trackScore);
+ LOG(Media, "HTMLMediaElement::configureTextTrackGroup - '%s' track with language '%s' has score %i", textTrack->kind().string().utf8().data(), textTrack->language().string().utf8().data(), trackScore);
if (trackScore) {
@@ -3796,7 +3458,7 @@ void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
// to believe is appropriate for the user, and there is no other text track in the media element's list of
// text tracks with a text track kind of chapters whose text track mode is showing
// Let the text track mode be showing.
- if (trackScore > highestTrackScore && trackScore > alreadyVisibleTrackScore) {
+ if (trackScore > highestTrackScore) {
highestTrackScore = trackScore;
trackToEnable = textTrack;
}
@@ -3850,108 +3512,12 @@ void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
}
}
- if (trackToEnable) {
+ if (trackToEnable)
trackToEnable->setMode(TextTrack::showingKeyword());
- // If user preferences indicate we should always display captions, make sure we reflect the
- // proper status via the webkitClosedCaptionsVisible API call:
- if (!webkitClosedCaptionsVisible() && closedCaptionsVisible() && displayMode == CaptionUserPreferences::AlwaysOn)
- m_webkitLegacyClosedCaptionOverride = true;
- }
-
- updateCaptionContainer();
-
m_processingPreferenceChange = false;
}
-static JSC::JSValue controllerJSValue(JSC::ExecState& exec, JSDOMGlobalObject& globalObject, HTMLMediaElement& media)
-{
- auto mediaJSWrapper = toJS(&exec, &globalObject, &media);
-
- // Retrieve the controller through the JS object graph
- JSC::JSObject* mediaJSWrapperObject = JSC::jsDynamicCast<JSC::JSObject*>(mediaJSWrapper);
- if (!mediaJSWrapperObject)
- return JSC::jsNull();
-
- JSC::Identifier controlsHost = JSC::Identifier::fromString(&exec.vm(), "controlsHost");
- JSC::JSValue controlsHostJSWrapper = mediaJSWrapperObject->get(&exec, controlsHost);
- if (exec.hadException())
- return JSC::jsNull();
-
- JSC::JSObject* controlsHostJSWrapperObject = JSC::jsDynamicCast<JSC::JSObject*>(controlsHostJSWrapper);
- if (!controlsHostJSWrapperObject)
- return JSC::jsNull();
-
- JSC::Identifier controllerID = JSC::Identifier::fromString(&exec.vm(), "controller");
- JSC::JSValue controllerJSWrapper = controlsHostJSWrapperObject->get(&exec, controllerID);
- if (exec.hadException())
- return JSC::jsNull();
-
- return controllerJSWrapper;
-}
-
-void HTMLMediaElement::updateCaptionContainer()
-{
- LOG(Media, "HTMLMediaElement::updateCaptionContainer(%p)", this);
-#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- Page* page = document().page();
- if (!page)
- return;
-
- DOMWrapperWorld& world = ensureIsolatedWorld();
-
- if (!ensureMediaControlsInjectedScript())
- return;
-
- ensureUserAgentShadowRoot();
-
- if (!m_mediaControlsHost)
- m_mediaControlsHost = MediaControlsHost::create(this);
-
- ScriptController& scriptController = document().frame()->script();
- JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world));
- JSC::ExecState* exec = globalObject->globalExec();
- JSC::JSLockHolder lock(exec);
-
- JSC::JSValue controllerValue = controllerJSValue(*exec, *globalObject, *this);
- JSC::JSObject* controllerObject = JSC::jsDynamicCast<JSC::JSObject*>(controllerValue);
- if (!controllerObject)
- return;
-
- // The media controls script must provide a method on the Controller object with the following details.
- // Name: updateCaptionContainer
- // Parameters:
- // None
- // Return value:
- // None
- JSC::JSValue methodValue = controllerObject->get(exec, JSC::Identifier::fromString(exec, "updateCaptionContainer"));
- JSC::JSObject* methodObject = JSC::jsDynamicCast<JSC::JSObject*>(methodValue);
- if (!methodObject)
- return;
-
- JSC::CallData callData;
- JSC::CallType callType = methodObject->methodTable()->getCallData(methodObject, callData);
- if (callType == JSC::CallTypeNone)
- return;
-
- JSC::MarkedArgumentBuffer noArguments;
- JSC::call(exec, methodObject, callType, callData, controllerObject, noArguments);
- exec->clearException();
-#endif
-}
-
-void HTMLMediaElement::layoutSizeChanged()
-{
-#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- RefPtr<HTMLMediaElement> strongThis = this;
- std::function<void()> task = [strongThis] {
- if (ShadowRoot* root = strongThis->userAgentShadowRoot())
- root->dispatchEvent(Event::create("resize", false, false));
- };
- m_resizeTaskQueue.enqueueTask(task);
-#endif
-}
-
void HTMLMediaElement::setSelectedTextTrack(TextTrack* trackToSelect)
{
TextTrackList* trackList = textTracks();
@@ -3969,16 +3535,13 @@ void HTMLMediaElement::setSelectedTextTrack(TextTrack* trackToSelect)
else
track->setMode(TextTrack::showingKeyword());
}
- } else if (trackToSelect == TextTrack::captionMenuOffItem()) {
- for (int i = 0, length = trackList->length(); i < length; ++i)
- trackList->item(i)->setMode(TextTrack::disabledKeyword());
}
CaptionUserPreferences* captionPreferences = document().page() ? document().page()->group().captionPreferences() : 0;
if (!captionPreferences)
return;
- CaptionUserPreferences::CaptionDisplayMode displayMode;
+ CaptionUserPreferences::CaptionDisplayMode displayMode = captionPreferences->captionDisplayMode();
if (trackToSelect == TextTrack::captionMenuOffItem())
displayMode = CaptionUserPreferences::ForcedOnly;
else if (trackToSelect == TextTrack::captionMenuAutomaticItem())
@@ -3987,6 +3550,9 @@ void HTMLMediaElement::setSelectedTextTrack(TextTrack* trackToSelect)
displayMode = CaptionUserPreferences::AlwaysOn;
if (trackToSelect->language().length())
captionPreferences->setPreferredLanguage(trackToSelect->language());
+
+ // Set m_captionDisplayMode here so we don't reconfigure again when the preference changed notification comes through.
+ m_captionDisplayMode = displayMode;
}
captionPreferences->setCaptionDisplayMode(displayMode);
@@ -4078,19 +3644,19 @@ URL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* ke
// Don't log if this was just called to find out if there are any valid <source> elements.
bool shouldLog = actionIfInvalid != DoNothing;
if (shouldLog)
- LOG(Media, "HTMLMediaElement::selectNextSourceChild(%p)", this);
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild");
#endif
if (!m_nextChildNodeToConsider) {
#if !LOG_DISABLED
if (shouldLog)
- LOG(Media, "HTMLMediaElement::selectNextSourceChild(%p) - end of list, stopping", this);
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild -> 0x0000, \"\"");
#endif
return URL();
}
URL mediaURL;
- HTMLSourceElement* source = nullptr;
+ HTMLSourceElement* source = 0;
String type;
String system;
bool lookingForStartNode = m_nextChildNodeToConsider;
@@ -4111,13 +3677,13 @@ URL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* ke
if (node.parentNode() != this)
continue;
- source = downcast<HTMLSourceElement>(&node);
+ source = toHTMLSourceElement(&node);
// If candidate does not have a src attribute, or if its src attribute's value is the empty string ... jump down to the failed step below
mediaURL = source->getNonEmptyURLAttribute(srcAttr);
#if !LOG_DISABLED
if (shouldLog)
- LOG(Media, "HTMLMediaElement::selectNextSourceChild(%p) - 'src' is %s", this, urlForLoggingMedia(mediaURL).utf8().data());
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'src' is %s", urlForLoggingMedia(mediaURL).utf8().data());
#endif
if (mediaURL.isEmpty())
goto check_again;
@@ -4127,7 +3693,7 @@ URL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* ke
RefPtr<MediaQuerySet> media = MediaQuerySet::createAllowingDescriptionSyntax(source->media());
#if !LOG_DISABLED
if (shouldLog)
- LOG(Media, "HTMLMediaElement::selectNextSourceChild(%p) - 'media' is %s", this, source->media().utf8().data());
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'media' is %s", source->media().utf8().data());
#endif
if (!screenEval.eval(media.get()))
goto check_again;
@@ -4140,7 +3706,7 @@ URL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* ke
if (!type.isEmpty() || !system.isEmpty()) {
#if !LOG_DISABLED
if (shouldLog)
- LOG(Media, "HTMLMediaElement::selectNextSourceChild(%p) - 'type' is '%s' - key system is '%s'", this, type.utf8().data(), system.utf8().data());
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'type' is '%s' - key system is '%s'", type.utf8().data(), system.utf8().data());
#endif
MediaEngineSupportParameters parameters;
ContentType contentType(type);
@@ -4153,9 +3719,6 @@ URL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* ke
#if ENABLE(MEDIA_SOURCE)
parameters.isMediaSource = mediaURL.protocolIs(mediaSourceBlobProtocol);
#endif
-#if ENABLE(MEDIA_STREAM)
- parameters.isMediaStream = mediaURL.protocolIs(mediaStreamBlobProtocol);
-#endif
if (!MediaPlayer::supportsType(parameters, this))
goto check_again;
}
@@ -4165,7 +3728,7 @@ URL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* ke
// A 'beforeload' event handler can mutate the DOM, so check to see if the source element is still a child node.
if (node.parentNode() != this) {
- LOG(Media, "HTMLMediaElement::selectNextSourceChild(%p) - 'beforeload' removed current element", this);
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild : 'beforeload' removed current element");
source = 0;
goto check_again;
}
@@ -4189,25 +3752,25 @@ check_again:
m_currentSourceNode = source;
m_nextChildNodeToConsider = source->nextSibling();
} else {
- m_currentSourceNode = nullptr;
- m_nextChildNodeToConsider = nullptr;
+ m_currentSourceNode = 0;
+ m_nextChildNodeToConsider = 0;
}
#if !LOG_DISABLED
if (shouldLog)
- LOG(Media, "HTMLMediaElement::selectNextSourceChild(%p) -> %p, %s", this, m_currentSourceNode.get(), canUseSourceElement ? urlForLoggingMedia(mediaURL).utf8().data() : "");
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild -> %p, %s", m_currentSourceNode.get(), canUseSourceElement ? urlForLoggingMedia(mediaURL).utf8().data() : "");
#endif
return canUseSourceElement ? mediaURL : URL();
}
void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source)
{
- LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - %p", this, source);
+ LOG(Media, "HTMLMediaElement::sourceWasAdded(%p)", source);
#if !LOG_DISABLED
if (source->hasTagName(sourceTag)) {
URL url = source->getNonEmptyURLAttribute(srcAttr);
- LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data());
+ LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLoggingMedia(url).utf8().data());
}
#endif
@@ -4225,7 +3788,7 @@ void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source)
}
if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) {
- LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - <source> inserted immediately after current source", this);
+ LOG(Media, "HTMLMediaElement::sourceWasAdded - <source> inserted immediately after current source");
m_nextChildNodeToConsider = source;
return;
}
@@ -4250,12 +3813,12 @@ void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source)
void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement* source)
{
- LOG(Media, "HTMLMediaElement::sourceWasRemoved(%p) - %p", this, source);
+ LOG(Media, "HTMLMediaElement::sourceWasRemoved(%p)", source);
#if !LOG_DISABLED
if (source->hasTagName(sourceTag)) {
URL url = source->getNonEmptyURLAttribute(srcAttr);
- LOG(Media, "HTMLMediaElement::sourceWasRemoved(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data());
+ LOG(Media, "HTMLMediaElement::sourceWasRemoved - 'src' is %s", urlForLoggingMedia(url).utf8().data());
}
#endif
@@ -4265,23 +3828,23 @@ void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement* source)
if (source == m_nextChildNodeToConsider) {
if (m_currentSourceNode)
m_nextChildNodeToConsider = m_currentSourceNode->nextSibling();
- LOG(Media, "HTMLMediaElement::sourceRemoved(%p) - m_nextChildNodeToConsider set to %p", this, m_nextChildNodeToConsider.get());
+ LOG(Media, "HTMLMediaElement::sourceRemoved - m_nextChildNodeToConsider set to %p", m_nextChildNodeToConsider.get());
} else if (source == m_currentSourceNode) {
// Clear the current source node pointer, but don't change the movie as the spec says:
// 4.8.8 - Dynamically modifying a source element and its attribute when the element is already
// inserted in a video or audio element will have no effect.
- m_currentSourceNode = nullptr;
- LOG(Media, "HTMLMediaElement::sourceRemoved(%p) - m_currentSourceNode set to 0", this);
+ m_currentSourceNode = 0;
+ LOG(Media, "HTMLMediaElement::sourceRemoved - m_currentSourceNode set to 0");
}
}
void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerTimeChanged(%p)", this);
+ LOG(Media, "HTMLMediaElement::mediaPlayerTimeChanged");
#if ENABLE(VIDEO_TRACK)
if (RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
- updateActiveTextTrackCues(currentMediaTime());
+ updateActiveTextTrackCues(currentTime());
#endif
beginProcessingMediaPlayerCallback();
@@ -4295,30 +3858,27 @@ void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
// Always call scheduleTimeupdateEvent when the media engine reports a time discontinuity,
// it will only queue a 'timeupdate' event if we haven't already posted one at the current
// movie time.
- else
- scheduleTimeupdateEvent(false);
+ scheduleTimeupdateEvent(false);
- MediaTime now = currentMediaTime();
- MediaTime dur = durationMediaTime();
- double playbackRate = requestedPlaybackRate();
+ double now = currentTime();
+ double dur = duration();
// When the current playback position reaches the end of the media resource then the user agent must follow these steps:
- if (dur.isValid() && dur) {
+ if (!std::isnan(dur) && dur) {
// If the media element has a loop attribute specified and does not have a current media controller,
- if (loop() && !m_mediaController && playbackRate > 0) {
+ if (loop() && !m_mediaController && m_playbackRate > 0) {
m_sentEndEvent = false;
// then seek to the earliest possible position of the media resource and abort these steps when the direction of
// playback is forwards,
if (now >= dur)
- seekInternal(MediaTime::zeroTime());
- } else if ((now <= MediaTime::zeroTime() && playbackRate < 0) || (now >= dur && playbackRate > 0)) {
+ seek(0);
+ } else if ((now <= 0 && m_playbackRate < 0) || (now >= dur && m_playbackRate > 0)) {
// If the media element does not have a current media controller, and the media element
// has still ended playback and paused is false,
if (!m_mediaController && !m_paused) {
// changes paused to true and fires a simple event named pause at the media element.
m_paused = true;
scheduleEvent(eventNames().pauseEvent);
- m_mediaSession->clientWillPausePlayback();
}
// Queue a task to fire a simple event named ended at the media element.
if (!m_sentEndEvent) {
@@ -4345,7 +3905,7 @@ void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
void HTMLMediaElement::mediaPlayerVolumeChanged(MediaPlayer*)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerVolumeChanged(%p)", this);
+ LOG(Media, "HTMLMediaElement::mediaPlayerVolumeChanged");
beginProcessingMediaPlayerCallback();
if (m_player) {
@@ -4361,7 +3921,7 @@ void HTMLMediaElement::mediaPlayerVolumeChanged(MediaPlayer*)
void HTMLMediaElement::mediaPlayerMuteChanged(MediaPlayer*)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerMuteChanged(%p)", this);
+ LOG(Media, "HTMLMediaElement::mediaPlayerMuteChanged");
beginProcessingMediaPlayerCallback();
if (m_player)
@@ -4371,31 +3931,30 @@ void HTMLMediaElement::mediaPlayerMuteChanged(MediaPlayer*)
void HTMLMediaElement::mediaPlayerDurationChanged(MediaPlayer* player)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerDurationChanged(%p)", this);
+ LOG(Media, "HTMLMediaElement::mediaPlayerDurationChanged");
beginProcessingMediaPlayerCallback();
scheduleEvent(eventNames().durationchangeEvent);
mediaPlayerCharacteristicChanged(player);
- MediaTime now = currentMediaTime();
- MediaTime dur = durationMediaTime();
+ double now = currentTime();
+ double dur = duration();
if (now > dur)
- seekInternal(dur);
+ seek(dur);
endProcessingMediaPlayerCallback();
}
void HTMLMediaElement::mediaPlayerRateChanged(MediaPlayer*)
{
+ LOG(Media, "HTMLMediaElement::mediaPlayerRateChanged");
+
beginProcessingMediaPlayerCallback();
// Stash the rate in case the one we tried to set isn't what the engine is
// using (eg. it can't handle the rate we set)
- m_reportedPlaybackRate = m_player->rate();
-
- LOG(Media, "HTMLMediaElement::mediaPlayerRateChanged(%p) - rate: %lf", this, m_reportedPlaybackRate);
-
+ m_playbackRate = m_player->rate();
if (m_playing)
invalidateCachedTime();
@@ -4406,7 +3965,7 @@ void HTMLMediaElement::mediaPlayerRateChanged(MediaPlayer*)
void HTMLMediaElement::mediaPlayerPlaybackStateChanged(MediaPlayer*)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerPlaybackStateChanged(%p)", this);
+ LOG(Media, "HTMLMediaElement::mediaPlayerPlaybackStateChanged");
if (!m_player || m_pausedInternal)
return;
@@ -4421,18 +3980,18 @@ void HTMLMediaElement::mediaPlayerPlaybackStateChanged(MediaPlayer*)
void HTMLMediaElement::mediaPlayerSawUnsupportedTracks(MediaPlayer*)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerSawUnsupportedTracks(%p)", this);
+ LOG(Media, "HTMLMediaElement::mediaPlayerSawUnsupportedTracks");
// The MediaPlayer came across content it cannot completely handle.
// This is normally acceptable except when we are in a standalone
// MediaDocument. If so, tell the document what has happened.
- if (is<MediaDocument>(document()))
- downcast<MediaDocument>(document()).mediaElementSawUnsupportedTracks();
+ if (document().isMediaDocument())
+ toMediaDocument(document()).mediaElementSawUnsupportedTracks();
}
void HTMLMediaElement::mediaPlayerResourceNotSupported(MediaPlayer*)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerResourceNotSupported(%p)", this);
+ LOG(Media, "HTMLMediaElement::mediaPlayerResourceNotSupported");
// The MediaPlayer came across content which no installed engine supports.
mediaLoadingFailed(MediaPlayer::FormatError);
@@ -4450,10 +4009,7 @@ void HTMLMediaElement::mediaPlayerRepaint(MediaPlayer*)
void HTMLMediaElement::mediaPlayerSizeChanged(MediaPlayer*)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerSizeChanged(%p)", this);
-
- if (is<MediaDocument>(document()) && m_player)
- downcast<MediaDocument>(document()).mediaElementNaturalSizeChanged(expandedIntSize(m_player->naturalSize()));
+ LOG(Media, "HTMLMediaElement::mediaPlayerSizeChanged");
beginProcessingMediaPlayerCallback();
if (renderer())
@@ -4461,20 +4017,22 @@ void HTMLMediaElement::mediaPlayerSizeChanged(MediaPlayer*)
endProcessingMediaPlayerCallback();
}
+#if USE(ACCELERATED_COMPOSITING)
bool HTMLMediaElement::mediaPlayerRenderingCanBeAccelerated(MediaPlayer*)
{
- if (is<RenderVideo>(renderer()))
- return renderer()->view().compositor().canAccelerateVideoRendering(downcast<RenderVideo>(*renderer()));
+ if (renderer() && renderer()->isVideo())
+ return renderer()->view().compositor().canAccelerateVideoRendering(toRenderVideo(*renderer()));
return false;
}
void HTMLMediaElement::mediaPlayerRenderingModeChanged(MediaPlayer*)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerRenderingModeChanged(%p)", this);
+ LOG(Media, "HTMLMediaElement::mediaPlayerRenderingModeChanged");
// Kick off a fake recalcStyle that will update the compositing tree.
setNeedsStyleRecalc(SyntheticStyleChange);
}
+#endif
#if PLATFORM(WIN) && USE(AVFOUNDATION)
GraphicsDeviceAdapter* HTMLMediaElement::mediaPlayerGraphicsDeviceAdapter(const MediaPlayer*) const
@@ -4488,7 +4046,7 @@ GraphicsDeviceAdapter* HTMLMediaElement::mediaPlayerGraphicsDeviceAdapter(const
void HTMLMediaElement::mediaPlayerEngineUpdated(MediaPlayer*)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerEngineUpdated(%p)", this);
+ LOG(Media, "HTMLMediaElement::mediaPlayerEngineUpdated");
beginProcessingMediaPlayerCallback();
if (renderer())
renderer()->updateFromElement();
@@ -4497,46 +4055,24 @@ void HTMLMediaElement::mediaPlayerEngineUpdated(MediaPlayer*)
#if ENABLE(MEDIA_SOURCE)
m_droppedVideoFrames = 0;
#endif
-
- m_havePreparedToPlay = false;
-
- m_mediaSession->mediaEngineUpdated(*this);
-
-#if ENABLE(WEB_AUDIO)
- if (m_audioSourceNode && audioSourceProvider()) {
- m_audioSourceNode->lock();
- audioSourceProvider()->setClient(m_audioSourceNode);
- m_audioSourceNode->unlock();
- }
-#endif
-
-#if PLATFORM(IOS)
- if (!m_player)
- return;
- m_player->setVideoFullscreenFrame(m_videoFullscreenFrame);
- m_player->setVideoFullscreenGravity(m_videoFullscreenGravity);
- m_player->setVideoFullscreenLayer(m_videoFullscreenLayer.get());
-#endif
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- updateMediaState(UpdateMediaState::Asynchronously);
-#endif
}
void HTMLMediaElement::mediaPlayerFirstVideoFrameAvailable(MediaPlayer*)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerFirstVideoFrameAvailable(%p) - current display mode = %i", this, (int)displayMode());
-
+ LOG(Media, "HTMLMediaElement::mediaPlayerFirstVideoFrameAvailable");
beginProcessingMediaPlayerCallback();
if (displayMode() == PosterWaitingForVideo) {
setDisplayMode(Video);
+#if USE(ACCELERATED_COMPOSITING)
mediaPlayerRenderingModeChanged(m_player.get());
+#endif
}
endProcessingMediaPlayerCallback();
}
void HTMLMediaElement::mediaPlayerCharacteristicChanged(MediaPlayer*)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerCharacteristicChanged(%p)", this);
+ LOG(Media, "HTMLMediaElement::mediaPlayerCharacteristicChanged");
beginProcessingMediaPlayerCallback();
@@ -4545,25 +4081,10 @@ void HTMLMediaElement::mediaPlayerCharacteristicChanged(MediaPlayer*)
markCaptionAndSubtitleTracksAsUnconfigured(AfterDelay);
#endif
- if (potentiallyPlaying() && displayMode() == PosterWaitingForVideo) {
- setDisplayMode(Video);
- mediaPlayerRenderingModeChanged(m_player.get());
- }
-
if (hasMediaControls())
mediaControls()->reset();
if (renderer())
renderer()->updateFromElement();
-
- if (isPlaying() && !m_mediaSession->playbackPermitted(*this))
- pauseInternal();
-
-#if ENABLE(MEDIA_SESSION)
- document().updateIsPlayingMedia(m_elementID);
-#else
- document().updateIsPlayingMedia();
-#endif
-
endProcessingMediaPlayerCallback();
}
@@ -4574,26 +4095,16 @@ PassRefPtr<TimeRanges> HTMLMediaElement::buffered() const
#if ENABLE(MEDIA_SOURCE)
if (m_mediaSource)
- return TimeRanges::create(*m_mediaSource->buffered());
+ return m_mediaSource->buffered();
#endif
- return TimeRanges::create(*m_player->buffered());
-}
-
-double HTMLMediaElement::maxBufferedTime() const
-{
- RefPtr<TimeRanges> bufferedRanges = buffered();
- unsigned numRanges = bufferedRanges->length();
- if (!numRanges)
- return 0;
-
- return bufferedRanges->end(numRanges - 1, ASSERT_NO_EXCEPTION);
+ return m_player->buffered();
}
PassRefPtr<TimeRanges> HTMLMediaElement::played()
{
if (m_playing) {
- MediaTime time = currentMediaTime();
+ double time = currentTime();
if (time > m_lastSeekTime)
addPlayedRange(m_lastSeekTime, time);
}
@@ -4606,10 +4117,7 @@ PassRefPtr<TimeRanges> HTMLMediaElement::played()
PassRefPtr<TimeRanges> HTMLMediaElement::seekable() const
{
- if (m_player)
- return TimeRanges::create(*m_player->seekable());
-
- return TimeRanges::create();
+ return m_player ? m_player->seekable() : TimeRanges::create();
}
bool HTMLMediaElement::potentiallyPlaying() const
@@ -4645,8 +4153,8 @@ bool HTMLMediaElement::couldPlayIfEnoughData() const
bool HTMLMediaElement::endedPlayback() const
{
- MediaTime dur = durationMediaTime();
- if (!m_player || !dur.isValid())
+ double dur = duration();
+ if (!m_player || std::isnan(dur))
return false;
// 4.8.10.8 Playing the media resource
@@ -4659,14 +4167,14 @@ bool HTMLMediaElement::endedPlayback() const
// and the current playback position is the end of the media resource and the direction
// of playback is forwards, Either the media element does not have a loop attribute specified,
// or the media element has a current media controller.
- MediaTime now = currentMediaTime();
- if (requestedPlaybackRate() > 0)
- return dur > MediaTime::zeroTime() && now >= dur && (!loop() || m_mediaController);
+ double now = currentTime();
+ if (m_playbackRate > 0)
+ return dur > 0 && now >= dur && (!loop() || m_mediaController);
// or the current playback position is the earliest possible position and the direction
// of playback is backwards
- if (requestedPlaybackRate() < 0)
- return now <= MediaTime::zeroTime();
+ if (m_playbackRate < 0)
+ return now <= 0;
return false;
}
@@ -4684,20 +4192,20 @@ bool HTMLMediaElement::stoppedDueToErrors() const
bool HTMLMediaElement::pausedForUserInteraction() const
{
- if (m_mediaSession->state() == PlatformMediaSession::Interrupted)
+ if (m_mediaSession->state() == MediaSession::Interrupted)
return true;
return false;
}
-MediaTime HTMLMediaElement::minTimeSeekable() const
+double HTMLMediaElement::minTimeSeekable() const
{
- return m_player ? m_player->minTimeSeekable() : MediaTime::zeroTime();
+ return m_player ? m_player->minTimeSeekable() : 0;
}
-MediaTime HTMLMediaElement::maxTimeSeekable() const
+double HTMLMediaElement::maxTimeSeekable() const
{
- return m_player ? m_player->maxTimeSeekable() : MediaTime::zeroTime();
+ return m_player ? m_player->maxTimeSeekable() : 0;
}
void HTMLMediaElement::updateVolume()
@@ -4717,20 +4225,16 @@ void HTMLMediaElement::updateVolume()
if (!processingMediaPlayerCallback()) {
Page* page = document().page();
double volumeMultiplier = page ? page->mediaVolume() : 1;
- bool shouldMute = effectiveMuted();
+ bool shouldMute = muted();
if (m_mediaController) {
volumeMultiplier *= m_mediaController->volume();
- shouldMute = m_mediaController->muted() || (page && page->isMuted());
+ shouldMute = m_mediaController->muted();
}
-#if ENABLE(MEDIA_SESSION)
- if (m_shouldDuck)
- volumeMultiplier *= 0.25;
-#endif
-
m_player->setMuted(shouldMute);
- m_player->setVolume(m_volume * volumeMultiplier);
+ if (m_volumeInitialized)
+ m_player->setVolume(m_volume * volumeMultiplier);
}
if (hasMediaControls())
@@ -4757,7 +4261,17 @@ void HTMLMediaElement::updatePlayState()
bool shouldBePlaying = potentiallyPlaying();
bool playerPaused = m_player->paused();
- LOG(Media, "HTMLMediaElement::updatePlayState(%p) - shouldBePlaying = %s, playerPaused = %s", this, boolString(shouldBePlaying), boolString(playerPaused));
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy()) {
+ if (shouldBePlaying && !m_requestingPlay && !m_player->readyForPlayback())
+ shouldBePlaying = false;
+ else if (!shouldBePlaying && m_requestingPlay && m_player->readyForPlayback())
+ shouldBePlaying = true;
+ }
+#endif
+
+ LOG(Media, "HTMLMediaElement::updatePlayState - shouldBePlaying = %s, playerPaused = %s",
+ boolString(shouldBePlaying), boolString(playerPaused));
if (shouldBePlaying) {
setDisplayMode(Video);
@@ -4766,20 +4280,13 @@ void HTMLMediaElement::updatePlayState()
if (playerPaused) {
m_mediaSession->clientWillBeginPlayback();
- if (m_mediaSession->requiresFullscreenForVideoPlayback(*this) && !isFullscreen())
+ if (m_mediaSession->requiresFullscreenForVideoPlayback(*this))
enterFullscreen();
// Set rate, muted before calling play in case they were set before the media engine was setup.
// The media engine should just stash the rate and muted values since it isn't already playing.
- m_player->setRate(requestedPlaybackRate());
- m_player->setMuted(effectiveMuted());
-
- if (m_firstTimePlaying) {
- // Log that a media element was played.
- if (Frame* frame = document().frame())
- frame->mainFrame().diagnosticLoggingClient().logDiagnosticMessageWithValue(DiagnosticLoggingKeys::mediaKey(), isVideo() ? DiagnosticLoggingKeys::videoKey() : DiagnosticLoggingKeys::audioKey(), DiagnosticLoggingKeys::playedKey(), ShouldSample::No);
- m_firstTimePlaying = false;
- }
+ m_player->setRate(m_playbackRate);
+ m_player->setMuted(muted());
m_player->play();
}
@@ -4787,18 +4294,19 @@ void HTMLMediaElement::updatePlayState()
if (hasMediaControls())
mediaControls()->playbackStarted();
if (document().page())
- m_activityToken = document().page()->pageThrottler().mediaActivityToken();
+ m_activityToken = document().page()->createActivityToken();
startPlaybackProgressTimer();
- setPlaying(true);
- } else {
+ m_playing = true;
+
+ } else { // Should not be playing right now
if (!playerPaused)
m_player->pause();
refreshCachedTime();
m_playbackProgressTimer.stop();
- setPlaying(false);
- MediaTime time = currentMediaTime();
+ m_playing = false;
+ double time = currentTime();
if (time > m_lastSeekTime)
addPlayedRange(m_lastSeekTime, time);
@@ -4810,30 +4318,16 @@ void HTMLMediaElement::updatePlayState()
m_activityToken = nullptr;
}
+#if PLATFORM(IOS)
+ m_requestingPlay = false;
+#endif
+
updateMediaController();
if (renderer())
renderer()->updateFromElement();
}
-void HTMLMediaElement::setPlaying(bool playing)
-{
- if (m_playing == playing)
- return;
-
- m_playing = playing;
-
-#if ENABLE(MEDIA_SESSION)
- document().updateIsPlayingMedia(m_elementID);
-#else
- document().updateIsPlayingMedia();
-#endif
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- updateMediaState(UpdateMediaState::Asynchronously);
-#endif
-}
-
void HTMLMediaElement::setPausedInternal(bool b)
{
m_pausedInternal = b;
@@ -4848,7 +4342,7 @@ void HTMLMediaElement::stopPeriodicTimers()
void HTMLMediaElement::userCancelledLoad()
{
- LOG(Media, "HTMLMediaElement::userCancelledLoad(%p)", this);
+ LOG(Media, "HTMLMediaElement::userCancelledLoad");
// FIXME: We should look to reconcile the iOS and non-iOS code (below).
#if PLATFORM(IOS)
@@ -4862,7 +4356,7 @@ void HTMLMediaElement::userCancelledLoad()
// If the media data fetching process is aborted by the user:
// 1 - The user agent should cancel the fetching process.
- clearMediaPlayer(EveryDelayedAction);
+ clearMediaPlayer(-1);
// 2 - Set the error attribute to a new MediaError object whose code attribute is set to MEDIA_ERR_ABORTED.
m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED);
@@ -4889,51 +4383,41 @@ void HTMLMediaElement::userCancelledLoad()
setShouldDelayLoadEvent(false);
// 6 - Abort the overall resource selection algorithm.
- m_currentSourceNode = nullptr;
+ m_currentSourceNode = 0;
// Reset m_readyState since m_player is gone.
m_readyState = HAVE_NOTHING;
updateMediaController();
#if ENABLE(VIDEO_TRACK)
if (RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
- updateActiveTextTrackCues(MediaTime::zeroTime());
+ updateActiveTextTrackCues(0);
#endif
}
void HTMLMediaElement::clearMediaPlayer(int flags)
{
- LOG(Media, "HTMLMediaElement::clearMediaPlayer(%p) - flags = %x", this, (unsigned)flags);
-
#if USE(PLATFORM_TEXT_TRACK_MENU)
if (platformTextTrackMenu()) {
- m_platformMenu->setClient(nullptr);
- m_platformMenu = nullptr;
+ m_platformMenu->setClient(0);
+ m_platformMenu = 0;
}
#endif
#if ENABLE(VIDEO_TRACK)
- forgetResourceSpecificTracks();
+ removeAllInbandTracks();
#endif
#if ENABLE(MEDIA_SOURCE)
closeMediaSource();
#endif
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent)) {
- m_hasPlaybackTargetAvailabilityListeners = false;
- m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, false);
-
- // Send an availability event in case scripts want to hide the picker when the element
- // doesn't support playback to a target.
- enqueuePlaybackTargetAvailabilityChangedEvent();
- }
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (!shouldUseVideoPluginProxy())
#endif
-
- m_player = nullptr;
+ m_player.clear();
stopPeriodicTimers();
- m_pendingActionTimer.stop();
+ m_loadTimer.stop();
clearFlags(m_pendingActionFlags, flags);
m_loadState = WaitingForSource;
@@ -4946,75 +4430,49 @@ void HTMLMediaElement::clearMediaPlayer(int flags)
updateSleepDisabling();
}
-bool HTMLMediaElement::canSuspendForPageCache() const
+bool HTMLMediaElement::canSuspend() const
{
return true;
}
-const char* HTMLMediaElement::activeDOMObjectName() const
-{
- return "HTMLMediaElement";
-}
-
-void HTMLMediaElement::stopWithoutDestroyingMediaPlayer()
+void HTMLMediaElement::stop()
{
- LOG(Media, "HTMLMediaElement::stopWithoutDestroyingMediaPlayer(%p)", this);
-
- if (m_videoFullscreenMode != VideoFullscreenModeNone)
+ LOG(Media, "HTMLMediaElement::stop");
+ if (m_isFullscreen)
exitFullscreen();
m_inActiveDocument = false;
-
+ userCancelledLoad();
+
// Stop the playback without generating events
- setPlaying(false);
+ m_playing = false;
setPausedInternal(true);
- m_mediaSession->clientWillPausePlayback();
-
- userCancelledLoad();
-
+
if (renderer())
renderer()->updateFromElement();
stopPeriodicTimers();
-
- updateSleepDisabling();
-}
-
-void HTMLMediaElement::contextDestroyed()
-{
- m_seekTaskQueue.close();
- m_resizeTaskQueue.close();
- m_shadowDOMTaskQueue.close();
-
- ActiveDOMObject::contextDestroyed();
-}
-
-void HTMLMediaElement::stop()
-{
- LOG(Media, "HTMLMediaElement::stop(%p)", this);
-
- stopWithoutDestroyingMediaPlayer();
+ cancelPendingEventsAndCallbacks();
m_asyncEventQueue.close();
// Once an active DOM object has been stopped it can not be restarted, so we can deallocate
- // the media player now. Note that userCancelledLoad will already called clearMediaPlayer
- // if the media was not fully loaded, but we need the same cleanup if the file was completely
- // loaded and calling it again won't cause any problems.
- clearMediaPlayer(EveryDelayedAction);
+ // the media player now. Note that userCancelledLoad will already have cleared the player
+ // if the media was not fully loaded. This handles all other cases.
+ m_player.clear();
+
+ updateSleepDisabling();
}
void HTMLMediaElement::suspend(ReasonForSuspension why)
{
- LOG(Media, "HTMLMediaElement::suspend(%p)", this);
+ LOG(Media, "HTMLMediaElement::suspend");
switch (why)
{
- case PageCache:
- stopWithoutDestroyingMediaPlayer();
- m_asyncEventQueue.suspend();
- setShouldBufferData(false);
- m_mediaSession->addBehaviorRestriction(MediaElementSession::RequirePageConsentToResumeMedia);
+ case DocumentWillBecomeInactive:
+ stop();
+ m_mediaSession->addBehaviorRestriction(HTMLMediaSession::RequirePageConsentToResumeMedia);
break;
case DocumentWillBePaused:
case JavaScriptDebuggerPaused:
@@ -5027,26 +4485,25 @@ void HTMLMediaElement::suspend(ReasonForSuspension why)
void HTMLMediaElement::resume()
{
- LOG(Media, "HTMLMediaElement::resume(%p)", this);
+ LOG(Media, "HTMLMediaElement::resume");
m_inActiveDocument = true;
- m_asyncEventQueue.resume();
-
- setShouldBufferData(true);
-
if (!m_mediaSession->pageAllowsPlaybackAfterResuming(*this))
document().addMediaCanStartListener(this);
else
setPausedInternal(false);
- m_mediaSession->removeBehaviorRestriction(MediaElementSession::RequirePageConsentToResumeMedia);
+ m_mediaSession->removeBehaviorRestriction(HTMLMediaSession::RequirePageConsentToResumeMedia);
if (m_error && m_error->code() == MediaError::MEDIA_ERR_ABORTED) {
// Restart the load if it was aborted in the middle by moving the document to the page cache.
// m_error is only left at MEDIA_ERR_ABORTED when the document becomes inactive (it is set to
// MEDIA_ERR_ABORTED while the abortEvent is being sent, but cleared immediately afterwards).
// This behavior is not specified but it seems like a sensible thing to do.
+#if PLATFORM(IOS)
+ // FIXME: <rdar://problem/9751303> Merge: Does r1033092 need to be refixed in ToT?
+#endif
// As it is not safe to immedately start loading now, let's schedule a load.
scheduleDelayedAction(LoadMediaResource);
}
@@ -5062,22 +4519,50 @@ bool HTMLMediaElement::hasPendingActivity() const
void HTMLMediaElement::mediaVolumeDidChange()
{
- LOG(Media, "HTMLMediaElement::mediaVolumeDidChange(%p)", this);
+ LOG(Media, "HTMLMediaElement::mediaVolumeDidChange");
updateVolume();
}
+#if ENABLE(PAGE_VISIBILITY_API)
void HTMLMediaElement::visibilityStateChanged()
{
- LOG(Media, "HTMLMediaElement::visibilityStateChanged(%p)", this);
- m_elementIsHidden = document().hidden();
+ LOG(Media, "HTMLMediaElement::visibilityStateChanged");
+ m_isDisplaySleepDisablingSuspended = document().hidden();
updateSleepDisabling();
- m_mediaSession->visibilityChanged();
}
+#endif
+
+void HTMLMediaElement::defaultEventHandler(Event* event)
+{
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy()) {
+ auto renderer = this->renderer();
+ if (!renderer || !renderer->isWidget())
+ return;
+
+ if (Widget* widget = toRenderWidget(renderer)->widget())
+ widget->handleEvent(event);
+ return;
+ }
+#endif
+ HTMLElement::defaultEventHandler(event);
+}
+
+#if !PLATFORM(IOS)
+bool HTMLMediaElement::willRespondToMouseClickEvents()
+{
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy())
+ return true;
+#endif
+ return HTMLElement::willRespondToMouseClickEvents();
+}
+#endif // !PLATFORM(IOS)
#if ENABLE(VIDEO_TRACK)
bool HTMLMediaElement::requiresTextTrackRepresentation() const
{
- return (m_videoFullscreenMode != VideoFullscreenModeNone) && m_player ? m_player->requiresTextTrackRepresentation() : false;
+ return m_player ? m_player->requiresTextTrackRepresentation() : 0;
}
void HTMLMediaElement::setTextTrackRepresentation(TextTrackRepresentation* representation)
@@ -5085,46 +4570,223 @@ void HTMLMediaElement::setTextTrackRepresentation(TextTrackRepresentation* repre
if (m_player)
m_player->setTextTrackRepresentation(representation);
}
+#endif // ENABLE(VIDEO_TRACK)
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+
+void HTMLMediaElement::ensureMediaPlayer()
+{
+ if (!m_player)
+ createMediaPlayer();
+}
-void HTMLMediaElement::syncTextTrackBounds()
+void HTMLMediaElement::deliverNotification(MediaPlayerProxyNotificationType notification)
{
+ if (notification == MediaPlayerNotificationPlayPauseButtonPressed) {
+#if PLATFORM(IOS)
+ removeBehaviorsRestrictionsAfterFirstUserGesture();
+#endif
+ togglePlayState();
+ return;
+ }
+#if PLATFORM(IOS)
+ else if (notification == MediaPlayerRequestBeginPlayback) {
+ if (m_paused)
+ playInternal();
+ } else if (notification == MediaPlayerRequestPausePlayback) {
+ if (!m_paused)
+ pauseInternal();
+ } else if (notification == MediaPlayerNotificationLoseFocus) {
+ if (!m_paused)
+ pauseInternal();
+ } else if (notification == MediaPlayerNotificationDidPlayToTheEnd) {
+ if (!m_paused && !loop())
+ pauseInternal();
+ } else if (notification == MediaPlayerNotificationMediaValidated || notification == MediaPlayerNotificationReadyForInspection) {
+ // The media player sometimes reports an apparently spurious error just as we request playback, and then follows almost
+ // immediately with ReadyForInspection and/or MediaValidated. The spec doesn't deal with a "fatal" error followed
+ // by ressurection, so if we have set an error clear it now.
+ m_error = 0;
+ } else if (notification == MediaPlayerNotificationEnteredFullscreen) {
+ scheduleEvent(eventNames().webkitbeginfullscreenEvent);
+ m_isFullscreen = true;
+ } else if (notification == MediaPlayerNotificationExitedFullscreen) {
+ scheduleEvent(eventNames().webkitendfullscreenEvent);
+ m_isFullscreen = false;
+ }
+#endif
+
if (m_player)
- m_player->syncTextTrackBounds();
+ m_player->deliverNotification(notification);
+
+#if PLATFORM(IOS)
+ if (notification == MediaPlayerNotificationMediaValidated) {
+ // If the element is supposed to autoplay and we allow it, tell the media engine to begin loading
+ // data now. Playback will begin automatically when enough data has loaded.
+ if (m_autoplaying && m_paused && autoplay())
+ prepareToPlay();
+ } else if (notification == MediaPlayerNotificationEnteredFullscreen)
+ didBecomeFullscreenElement();
+ else if (notification == MediaPlayerNotificationExitedFullscreen)
+ willStopBeingFullscreenElement();
+#endif
}
-#endif // ENABLE(VIDEO_TRACK)
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-void HTMLMediaElement::webkitShowPlaybackTargetPicker()
+void HTMLMediaElement::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
{
- LOG(Media, "HTMLMediaElement::webkitShowPlaybackTargetPicker(%p)", this);
- m_mediaSession->showPlaybackTargetPicker(*this);
+ ensureMediaPlayer();
+ m_player->setMediaPlayerProxy(proxy);
}
-bool HTMLMediaElement::webkitCurrentPlaybackTargetIsWireless() const
+void HTMLMediaElement::getPluginProxyParams(URL& url, Vector<String>& names, Vector<String>& values)
{
- return m_player && m_player->isCurrentPlaybackTargetWireless();
+ Ref<HTMLMediaElement> protect(*this); // selectNextSourceChild may fire 'beforeload', which can make arbitrary DOM mutations.
+
+ Frame* frame = document().frame();
+
+ if (isVideo()) {
+ HTMLVideoElement* video = toHTMLVideoElement(this);
+ URL posterURL = video->posterImageURL();
+ if (!posterURL.isEmpty() && frame && frame->loader().willLoadMediaElementURL(posterURL)) {
+ names.append(ASCIILiteral("_media_element_poster_"));
+ values.append(posterURL.string());
+ }
+ }
+
+ if (controls()) {
+ names.append(ASCIILiteral("_media_element_controls_"));
+ values.append(ASCIILiteral("true"));
+ }
+
+#if PLATFORM(IOS)
+ // Don't pass the URL to the plug-in as part of the initialization arguments, we always pass the URL
+ // in loadResource and calling selectNextSourceChild here can mess up the processing of <source>
+ // elements later.
+ UNUSED_PARAM(url);
+#else
+ url = getNonEmptyURLAttribute(srcAttr);
+ if (!isSafeToLoadURL(url, Complain))
+ url = selectNextSourceChild(0, 0, DoNothing);
+
+ m_currentSrc = url;
+ if (url.isValid() && frame && frame->loader().willLoadMediaElementURL(url)) {
+ names.append(ASCIILiteral("_media_element_src_"));
+ values.append(m_currentSrc.string());
+ }
+#endif
+
+#if PLATFORM(IOS)
+ Settings* settings = document().settings();
+ if (settings && settings->mediaPlaybackAllowsInline() && (applicationIsDumpRenderTree() || fastHasAttribute(webkit_playsinlineAttr))) {
+ names.append(ASCIILiteral("_media_element_allow_inline_"));
+ values.append(ASCIILiteral("true"));
+ }
+
+ String airplay = fastGetAttribute(webkitairplayAttr);
+ if (equalIgnoringCase(airplay, "allow") || equalIgnoringCase(airplay, "deny")) {
+ names.append(ASCIILiteral("_media_element_airplay_"));
+ values.append(airplay.lower());
+ }
+
+ if (fastHasAttribute(data_youtube_idAttr)) {
+ names.append(ASCIILiteral("_media_element_youtube_video_id_"));
+ values.append(fastGetAttribute(data_youtube_idAttr));
+ }
+
+ String interfaceName = settings ? settings->networkInterfaceName() : String();
+ if (!interfaceName.isEmpty()) {
+ names.append(ASCIILiteral("_media_element_network_interface_name"));
+ values.append(interfaceName);
+ }
+
+ if (fastHasAttribute(titleAttr)) {
+ names.append(titleAttr.toString());
+ values.append(fastGetAttribute(titleAttr));
+ }
+#endif
+
+#if ENABLE(IOS_AIRPLAY)
+ if (isVideo() && fastHasAttribute(webkitwirelessvideoplaybackdisabledAttr)) {
+ names.append(ASCIILiteral("_media_element_wireless_video_playback_disabled"));
+ values.append(ASCIILiteral("true"));
+ }
+#endif
}
-void HTMLMediaElement::wirelessRoutesAvailableDidChange()
+void HTMLMediaElement::createMediaPlayerProxy()
{
- enqueuePlaybackTargetAvailabilityChangedEvent();
+ ensureMediaPlayer();
+
+ if (m_proxyWidget || (inDocument() && !m_needWidgetUpdate))
+ return;
+
+ Frame* frame = document().frame();
+ if (!frame)
+ return;
+
+ LOG(Media, "HTMLMediaElement::createMediaPlayerProxy");
+
+ URL url;
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+
+ getPluginProxyParams(url, paramNames, paramValues);
+
+ // Hang onto the proxy widget so it won't be destroyed if the plug-in is set to
+ // display:none
+ m_proxyWidget = frame->loader().subframeLoader().loadMediaPlayerProxyPlugin(*this, url, paramNames, paramValues);
+ if (m_proxyWidget)
+ m_needWidgetUpdate = false;
}
-void HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*)
+void HTMLMediaElement::updateWidget(PluginCreationOption)
{
- LOG(Media, "HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged(%p) - webkitCurrentPlaybackTargetIsWireless = %s", this, boolString(webkitCurrentPlaybackTargetIsWireless()));
+ setNeedWidgetUpdate(false);
- configureMediaControls();
+ // FIXME: What if document().frame() is 0?
+
+ URL url;
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+
+ getPluginProxyParams(url, paramNames, paramValues);
+ SubframeLoader& loader = document().frame()->loader().subframeLoader();
+ loader.loadMediaPlayerProxyPlugin(*this, url, paramNames, paramValues);
+}
+
+#endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+
+#if ENABLE(IOS_AIRPLAY)
+void HTMLMediaElement::webkitShowPlaybackTargetPicker()
+{
+ if (!document().page())
+ return;
+
+ if (!m_player)
+ return;
+
+ if (!m_mediaSession->showingPlaybackTargetPickerPermitted(*this))
+ return;
+
+ if (document().settings()->mediaPlaybackAllowsAirPlay())
+ return;
+
+ m_player->showPlaybackTargetPicker();
+}
+
+bool HTMLMediaElement::webkitCurrentPlaybackTargetIsWireless() const
+{
+ return m_player && m_player->isCurrentPlaybackTargetWireless();
+}
+
+void HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*)
+{
scheduleEvent(eventNames().webkitcurrentplaybacktargetiswirelesschangedEvent);
- updateMediaState(UpdateMediaState::Asynchronously);
}
-bool HTMLMediaElement::dispatchEvent(PassRefPtr<Event> prpEvent)
+void HTMLMediaElement::mediaPlayerPlaybackTargetAvailabilityChanged(MediaPlayer*)
{
- RefPtr<Event> event = prpEvent;
- if (event->type() == eventNames().webkitcurrentplaybacktargetiswirelesschangedEvent)
- scheduleDelayedAction(CheckPlaybackTargetCompatablity);
- return HTMLElement::dispatchEvent(event);
+ enqueuePlaybackTargetAvailabilityChangedEvent();
}
bool HTMLMediaElement::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
@@ -5135,14 +4797,9 @@ bool HTMLMediaElement::addEventListener(const AtomicString& eventType, PassRefPt
bool isFirstAvailabilityChangedListener = !hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent);
if (!Node::addEventListener(eventType, listener, useCapture))
return false;
+ if (m_player && isFirstAvailabilityChangedListener)
+ m_player->setHasPlaybackTargetAvailabilityListeners(true);
- if (isFirstAvailabilityChangedListener) {
- m_hasPlaybackTargetAvailabilityListeners = true;
- m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, true);
- }
-
- LOG(Media, "HTMLMediaElement::addEventListener(%p) - 'webkitplaybacktargetavailabilitychanged'", this);
-
enqueuePlaybackTargetAvailabilityChangedEvent(); // Ensure the event listener gets at least one event.
return true;
}
@@ -5156,80 +4813,25 @@ bool HTMLMediaElement::removeEventListener(const AtomicString& eventType, EventL
return false;
bool didRemoveLastAvailabilityChangedListener = !hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent);
- LOG(Media, "HTMLMediaElement::removeEventListener(%p) - removed last listener = %s", this, boolString(didRemoveLastAvailabilityChangedListener));
- if (didRemoveLastAvailabilityChangedListener) {
- m_hasPlaybackTargetAvailabilityListeners = false;
- m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, false);
- updateMediaState(UpdateMediaState::Asynchronously);
- }
-
+ if (m_player && didRemoveLastAvailabilityChangedListener)
+ m_player->setHasPlaybackTargetAvailabilityListeners(false);
return true;
}
void HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent()
{
- bool hasTargets = m_mediaSession->hasWirelessPlaybackTargets(*this);
- LOG(Media, "HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent(%p) - hasTargets = %s", this, boolString(hasTargets));
- RefPtr<Event> event = WebKitPlaybackTargetAvailabilityEvent::create(eventNames().webkitplaybacktargetavailabilitychangedEvent, hasTargets);
+ if (!m_player)
+ return;
+ bool isAirPlayAvailable = m_player->hasWirelessPlaybackTargets();
+ RefPtr<Event> event = WebKitPlaybackTargetAvailabilityEvent::create(eventNames().webkitplaybacktargetavailabilitychangedEvent, isAirPlayAvailable);
event->setTarget(this);
m_asyncEventQueue.enqueueEvent(event.release());
- updateMediaState(UpdateMediaState::Asynchronously);
-}
-
-void HTMLMediaElement::setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&& device)
-{
- LOG(Media, "HTMLMediaElement::setWirelessPlaybackTarget(%p)", this);
- if (m_player)
- m_player->setWirelessPlaybackTarget(WTF::move(device));
-}
-
-bool HTMLMediaElement::canPlayToWirelessPlaybackTarget() const
-{
- bool canPlay = m_player && m_player->canPlayToWirelessPlaybackTarget();
-
- LOG(Media, "HTMLMediaElement::canPlayToWirelessPlaybackTarget(%p) - returning %s", this, boolString(canPlay));
-
- return canPlay;
-}
-
-bool HTMLMediaElement::isPlayingToWirelessPlaybackTarget() const
-{
- bool isPlaying = m_player && m_player->isCurrentPlaybackTargetWireless();
-
- LOG(Media, "HTMLMediaElement::isPlayingToWirelessPlaybackTarget(%p) - returning %s", this, boolString(isPlaying));
-
- return isPlaying;
-}
-
-void HTMLMediaElement::setShouldPlayToPlaybackTarget(bool shouldPlay)
-{
- LOG(Media, "HTMLMediaElement::setShouldPlayToPlaybackTarget(%p) - shouldPlay = %s", this, boolString(shouldPlay));
-
- if (m_player)
- m_player->setShouldPlayToPlaybackTarget(shouldPlay);
-}
-#else // ENABLE(WIRELESS_PLAYBACK_TARGET)
-
-bool HTMLMediaElement::webkitCurrentPlaybackTargetIsWireless() const
-{
- return false;
-}
-
-#endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
-
-double HTMLMediaElement::minFastReverseRate() const
-{
- return m_player ? m_player->minFastReverseRate() : 0;
}
+#endif
-double HTMLMediaElement::maxFastForwardRate() const
-{
- return m_player ? m_player->maxFastForwardRate() : 0;
-}
-
bool HTMLMediaElement::isFullscreen() const
{
- if (m_videoFullscreenMode != VideoFullscreenModeNone)
+ if (m_isFullscreen)
return true;
#if ENABLE(FULLSCREEN_API)
@@ -5242,7 +4844,7 @@ bool HTMLMediaElement::isFullscreen() const
void HTMLMediaElement::toggleFullscreenState()
{
- LOG(Media, "HTMLMediaElement::toggleFullscreenState(%p) - isFullscreen() is %s", this, boolString(isFullscreen()));
+ LOG(Media, "HTMLMediaElement::toggleFullscreenState - isFullscreen() is %s", boolString(isFullscreen()));
if (isFullscreen())
exitFullscreen();
@@ -5250,13 +4852,9 @@ void HTMLMediaElement::toggleFullscreenState()
enterFullscreen();
}
-void HTMLMediaElement::enterFullscreen(VideoFullscreenMode mode)
+void HTMLMediaElement::enterFullscreen()
{
- LOG(Media, "HTMLMediaElement::enterFullscreen(%p)", this);
- ASSERT(mode != VideoFullscreenModeNone);
-
- if (m_videoFullscreenMode == mode)
- return;
+ LOG(Media, "HTMLMediaElement::enterFullscreen");
#if ENABLE(FULLSCREEN_API)
if (document().settings() && document().settings()->fullScreenEnabled()) {
@@ -5264,27 +4862,25 @@ void HTMLMediaElement::enterFullscreen(VideoFullscreenMode mode)
return;
}
#endif
-
- fullscreenModeChanged(mode);
+ ASSERT(!m_isFullscreen);
+ m_isFullscreen = true;
if (hasMediaControls())
mediaControls()->enteredFullscreen();
- if (document().page() && is<HTMLVideoElement>(*this)) {
- HTMLVideoElement& asVideo = downcast<HTMLVideoElement>(*this);
- if (document().page()->chrome().client().supportsVideoFullscreen()) {
- document().page()->chrome().client().enterVideoFullscreenForVideoElement(asVideo, m_videoFullscreenMode);
+ if (document().page()) {
+ if (document().page()->chrome().client().supportsFullscreenForNode(this)) {
+ document().page()->chrome().client().enterFullscreenForNode(this);
scheduleEvent(eventNames().webkitbeginfullscreenEvent);
}
+#if PLATFORM(IOS)
+ else if (m_player)
+ m_player->enterFullscreen();
+#endif
}
}
-void HTMLMediaElement::enterFullscreen()
-{
- enterFullscreen(VideoFullscreenModeStandard);
-}
-
void HTMLMediaElement::exitFullscreen()
{
- LOG(Media, "HTMLMediaElement::exitFullscreen(%p)", this);
+ LOG(Media, "HTMLMediaElement::exitFullscreen");
#if ENABLE(FULLSCREEN_API)
if (document().settings() && document().settings()->fullScreenEnabled()) {
@@ -5293,18 +4889,22 @@ void HTMLMediaElement::exitFullscreen()
return;
}
#endif
- ASSERT(m_videoFullscreenMode != VideoFullscreenModeNone);
- fullscreenModeChanged(VideoFullscreenModeNone);
+ ASSERT(m_isFullscreen);
+ m_isFullscreen = false;
if (hasMediaControls())
mediaControls()->exitedFullscreen();
- if (document().page() && is<HTMLVideoElement>(*this)) {
- if (m_mediaSession->requiresFullscreenForVideoPlayback(*this))
+ if (document().page()) {
+ if (document().page()->chrome().requiresFullscreenForVideoPlayback())
pauseInternal();
- if (document().page()->chrome().client().supportsVideoFullscreen()) {
- document().page()->chrome().client().exitVideoFullscreenForVideoElement(downcast<HTMLVideoElement>(*this));
+ if (document().page()->chrome().client().supportsFullscreenForNode(this)) {
+ document().page()->chrome().client().exitFullscreenForNode(this);
scheduleEvent(eventNames().webkitendfullscreenEvent);
}
+#if PLATFORM(IOS)
+ else if (m_player)
+ m_player->exitFullscreen();
+#endif
}
}
@@ -5325,40 +4925,36 @@ PlatformMedia HTMLMediaElement::platformMedia() const
return m_player ? m_player->platformMedia() : NoPlatformMedia;
}
+#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* HTMLMediaElement::platformLayer() const
{
+#if PLATFORM(IOS)
+ if (m_platformLayerBorrowed)
+ return nullptr;
+#endif
return m_player ? m_player->platformLayer() : nullptr;
}
#if PLATFORM(IOS)
-void HTMLMediaElement::setVideoFullscreenLayer(PlatformLayer* platformLayer)
-{
- m_videoFullscreenLayer = platformLayer;
- if (!m_player)
- return;
-
- m_player->setVideoFullscreenLayer(platformLayer);
- setNeedsStyleRecalc(SyntheticStyleChange);
-#if ENABLE(VIDEO_TRACK)
- if (RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled())
- updateTextTrackDisplay();
-#endif
-}
-
-void HTMLMediaElement::setVideoFullscreenFrame(FloatRect frame)
+PlatformLayer* HTMLMediaElement::borrowPlatformLayer()
{
- m_videoFullscreenFrame = frame;
- if (m_player)
- m_player->setVideoFullscreenFrame(frame);
+ ASSERT(!m_platformLayerBorrowed);
+ m_platformLayerBorrowed = true;
+ if (renderer())
+ renderer()->updateFromElement();
+ return m_player ? m_player->platformLayer() : nullptr;
}
-void HTMLMediaElement::setVideoFullscreenGravity(MediaPlayer::VideoGravity gravity)
+void HTMLMediaElement::returnPlatformLayer(PlatformLayer* platformLayer)
{
- m_videoFullscreenGravity = gravity;
- if (m_player)
- m_player->setVideoFullscreenGravity(gravity);
+ ASSERT_UNUSED(platformLayer, platformLayer == (m_player ? m_player->platformLayer() : nullptr));
+ ASSERT(m_platformLayerBorrowed);
+ m_platformLayerBorrowed = false;
+ if (renderer())
+ renderer()->updateFromElement();
}
#endif
+#endif
bool HTMLMediaElement::hasClosedCaptions() const
{
@@ -5388,26 +4984,22 @@ bool HTMLMediaElement::closedCaptionsVisible() const
}
#if ENABLE(VIDEO_TRACK)
-
void HTMLMediaElement::updateTextTrackDisplay()
{
#if ENABLE(MEDIA_CONTROLS_SCRIPT)
ensureUserAgentShadowRoot();
- ASSERT(m_mediaControlsHost);
- m_mediaControlsHost->updateTextTrackContainer();
-#else
+ return;
+#endif
if (!hasMediaControls() && !createMediaControls())
return;
mediaControls()->updateTextTrackDisplay();
-#endif
}
-
#endif
void HTMLMediaElement::setClosedCaptionsVisible(bool closedCaptionVisible)
{
- LOG(Media, "HTMLMediaElement::setClosedCaptionsVisible(%p) - %s", this, boolString(closedCaptionVisible));
+ LOG(Media, "HTMLMediaElement::setClosedCaptionsVisible(%s)", boolString(closedCaptionVisible));
m_closedCaptionsVisible = false;
@@ -5463,7 +5055,7 @@ unsigned HTMLMediaElement::webkitVideoDecodedByteCount() const
void HTMLMediaElement::mediaCanStart()
{
- LOG(Media, "HTMLMediaElement::mediaCanStart(%p)", this);
+ LOG(Media, "HTMLMediaElement::mediaCanStart");
ASSERT(m_isWaitingUntilMediaCanStart || m_pausedInternal);
if (m_isWaitingUntilMediaCanStart) {
@@ -5484,7 +5076,7 @@ void HTMLMediaElement::setShouldDelayLoadEvent(bool shouldDelay)
if (m_shouldDelayLoadEvent == shouldDelay)
return;
- LOG(Media, "HTMLMediaElement::setShouldDelayLoadEvent(%p) - %s", this, boolString(shouldDelay));
+ LOG(Media, "HTMLMediaElement::setShouldDelayLoadEvent(%s)", boolString(shouldDelay));
m_shouldDelayLoadEvent = shouldDelay;
if (shouldDelay)
@@ -5519,8 +5111,9 @@ void HTMLMediaElement::privateBrowsingStateDidChange()
if (!m_player)
return;
- bool privateMode = document().page() && document().page()->usesEphemeralSession();
- LOG(Media, "HTMLMediaElement::privateBrowsingStateDidChange(%p) - %s", this, boolString(privateMode));
+ Settings* settings = document().settings();
+ bool privateMode = !settings || settings->privateBrowsingEnabled();
+ LOG(Media, "HTMLMediaElement::privateBrowsingStateDidChange(%s)", boolString(privateMode));
m_player->setPrivateBrowsingMode(privateMode);
}
@@ -5578,28 +5171,26 @@ bool HTMLMediaElement::createMediaControls()
void HTMLMediaElement::configureMediaControls()
{
- bool requireControls = controls();
-
- // Always create controls for video when fullscreen playback is required.
- if (isVideo() && m_mediaSession->requiresFullscreenForVideoPlayback(*this))
- requireControls = true;
-
- // Always create controls when in full screen mode.
- if (isFullscreen())
- requireControls = true;
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy()) {
+ if (m_player)
+ m_player->setControls(controls());
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- if (m_player && m_player->isCurrentPlaybackTargetWireless())
- requireControls = true;
+ if (!hasMediaControls() && inDocument())
+ createMediaControls();
+ return;
+ }
#endif
#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- if (!requireControls || !inDocument() || !inActiveDocument())
+ if (!controls() || !inDocument())
return;
ensureUserAgentShadowRoot();
-#else
- if (!requireControls || !inDocument() || !inActiveDocument()) {
+ return;
+#endif
+
+ if (!controls() || !inDocument()) {
if (hasMediaControls())
mediaControls()->hide();
return;
@@ -5609,7 +5200,6 @@ void HTMLMediaElement::configureMediaControls()
return;
mediaControls()->show();
-#endif
}
#if ENABLE(VIDEO_TRACK)
@@ -5620,8 +5210,7 @@ void HTMLMediaElement::configureTextTrackDisplay(TextTrackVisibilityCheckType ch
if (m_processingPreferenceChange)
return;
- if (document().activeDOMObjectsAreStopped())
- return;
+ LOG(Media, "HTMLMediaElement::configureTextTrackDisplay");
bool haveVisibleTextTrack = false;
for (unsigned i = 0; i < m_textTracks->length(); ++i) {
@@ -5632,7 +5221,7 @@ void HTMLMediaElement::configureTextTrackDisplay(TextTrackVisibilityCheckType ch
}
if (checkType == CheckTextTrackVisibility && m_haveVisibleTextTrack == haveVisibleTextTrack) {
- updateActiveTextTrackCues(currentMediaTime());
+ updateActiveTextTrackCues(currentTime());
return;
}
@@ -5644,7 +5233,9 @@ void HTMLMediaElement::configureTextTrackDisplay(TextTrackVisibilityCheckType ch
return;
ensureUserAgentShadowRoot();
-#else
+ return;
+#endif
+
if (!m_haveVisibleTextTrack && !hasMediaControls())
return;
if (!hasMediaControls() && !createMediaControls())
@@ -5654,9 +5245,8 @@ void HTMLMediaElement::configureTextTrackDisplay(TextTrackVisibilityCheckType ch
if (RuntimeEnabledFeatures::sharedFeatures().webkitVideoTrackEnabled()) {
updateTextTrackDisplay();
- updateActiveTextTrackCues(currentMediaTime());
+ updateActiveTextTrackCues(currentTime());
}
-#endif
}
void HTMLMediaElement::captionPreferencesChanged()
@@ -5667,14 +5257,6 @@ void HTMLMediaElement::captionPreferencesChanged()
if (hasMediaControls())
mediaControls()->textTrackPreferencesChanged();
-#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- if (m_mediaControlsHost)
- m_mediaControlsHost->updateCaptionDisplaySizes();
-#endif
-
- if (m_player)
- m_player->tracksChanged();
-
if (!document().page())
return;
@@ -5683,7 +5265,7 @@ void HTMLMediaElement::captionPreferencesChanged()
return;
m_captionDisplayMode = displayMode;
- setWebkitClosedCaptionsVisible(m_captionDisplayMode == CaptionUserPreferences::AlwaysOn);
+ setClosedCaptionsVisible(m_captionDisplayMode == CaptionUserPreferences::AlwaysOn);
}
void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured(ReconfigureMode mode)
@@ -5691,7 +5273,7 @@ void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured(ReconfigureMod
if (!m_textTracks)
return;
- LOG(Media, "HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured(%p)", this);
+ LOG(Media, "HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured");
// Mark all tracks as not "configured" so that configureTextTracks()
// will reconsider which tracks to display in light of new user preferences
@@ -5719,8 +5301,6 @@ void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured(ReconfigureMod
void HTMLMediaElement::createMediaPlayer()
{
- LOG(Media, "HTMLMediaElement::createMediaPlayer(%p)", this);
-
#if ENABLE(WEB_AUDIO)
if (m_audioSourceNode)
m_audioSourceNode->lock();
@@ -5732,9 +5312,9 @@ void HTMLMediaElement::createMediaPlayer()
#endif
#if ENABLE(VIDEO_TRACK)
- forgetResourceSpecificTracks();
+ removeAllInbandTracks();
#endif
- m_player = std::make_unique<MediaPlayer>(static_cast<MediaPlayerClient&>(*this));
+ m_player = MediaPlayer::create(this);
#if ENABLE(WEB_AUDIO)
if (m_audioSourceNode) {
@@ -5746,10 +5326,9 @@ void HTMLMediaElement::createMediaPlayer()
}
#endif
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#if ENABLE(IOS_AIRPLAY)
if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent)) {
- m_hasPlaybackTargetAvailabilityListeners = true;
- m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, true);
+ m_player->setHasPlaybackTargetAvailabilityListeners(true);
enqueuePlaybackTargetAvailabilityChangedEvent(); // Ensure the event listener gets at least one event.
}
#endif
@@ -5873,31 +5452,31 @@ bool HTMLMediaElement::isBlockedOnMediaController() const
void HTMLMediaElement::prepareMediaFragmentURI()
{
MediaFragmentURIParser fragmentParser(m_currentSrc);
- MediaTime dur = durationMediaTime();
+ double dur = duration();
- MediaTime start = fragmentParser.startTime();
- if (start.isValid() && start > MediaTime::zeroTime()) {
+ double start = fragmentParser.startTime();
+ if (start != MediaFragmentURIParser::invalidTimeValue() && start > 0) {
m_fragmentStartTime = start;
if (m_fragmentStartTime > dur)
m_fragmentStartTime = dur;
} else
- m_fragmentStartTime = MediaTime::invalidTime();
+ m_fragmentStartTime = MediaPlayer::invalidTime();
- MediaTime end = fragmentParser.endTime();
- if (end.isValid() && end > MediaTime::zeroTime() && (!m_fragmentStartTime.isValid() || end > m_fragmentStartTime)) {
+ double end = fragmentParser.endTime();
+ if (end != MediaFragmentURIParser::invalidTimeValue() && end > 0 && end > m_fragmentStartTime) {
m_fragmentEndTime = end;
if (m_fragmentEndTime > dur)
m_fragmentEndTime = dur;
} else
- m_fragmentEndTime = MediaTime::invalidTime();
+ m_fragmentEndTime = MediaPlayer::invalidTime();
- if (m_fragmentStartTime.isValid() && m_readyState < HAVE_FUTURE_DATA)
+ if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE_FUTURE_DATA)
prepareToPlay();
}
void HTMLMediaElement::applyMediaFragmentURI()
{
- if (m_fragmentStartTime.isValid()) {
+ if (m_fragmentStartTime != MediaPlayer::invalidTime()) {
m_sentEndEvent = false;
seek(m_fragmentStartTime);
}
@@ -5905,23 +5484,25 @@ void HTMLMediaElement::applyMediaFragmentURI()
void HTMLMediaElement::updateSleepDisabling()
{
+#if PLATFORM(MAC)
if (!shouldDisableSleep() && m_sleepDisabler)
m_sleepDisabler = nullptr;
else if (shouldDisableSleep() && !m_sleepDisabler)
m_sleepDisabler = DisplaySleepDisabler::create("com.apple.WebCore: HTMLMediaElement playback");
+#endif
}
+#if PLATFORM(MAC)
bool HTMLMediaElement::shouldDisableSleep() const
{
-#if !PLATFORM(COCOA)
- return false;
-#endif
-
- if (m_elementIsHidden)
+#if ENABLE(PAGE_VISIBILITY_API)
+ if (m_isDisplaySleepDisablingSuspended)
return false;
+#endif
return m_player && !m_player->paused() && hasVideo() && hasAudio() && !loop();
}
+#endif
String HTMLMediaElement::mediaPlayerReferrer() const
{
@@ -5939,52 +5520,17 @@ String HTMLMediaElement::mediaPlayerUserAgent() const
return String();
return frame->loader().userAgent(m_currentSrc);
+
}
-#if ENABLE(AVF_CAPTIONS)
-Vector<RefPtr<PlatformTextTrack>> HTMLMediaElement::outOfBandTrackSources()
+MediaPlayerClient::CORSMode HTMLMediaElement::mediaPlayerCORSMode() const
{
- Vector<RefPtr<PlatformTextTrack>> outOfBandTrackSources;
- for (auto& trackElement : childrenOfType<HTMLTrackElement>(*this)) {
-
- if (!trackElement.fastHasAttribute(srcAttr))
- continue;
-
- URL url = trackElement.getNonEmptyURLAttribute(srcAttr);
- if (url.isEmpty())
- continue;
-
- if (!document().contentSecurityPolicy()->allowMediaFromSource(url, trackElement.isInUserAgentShadowTree()))
- continue;
-
- PlatformTextTrack::TrackKind platformKind = PlatformTextTrack::Caption;
- if (trackElement.kind() == TextTrack::captionsKeyword())
- platformKind = PlatformTextTrack::Caption;
- else if (trackElement.kind() == TextTrack::subtitlesKeyword())
- platformKind = PlatformTextTrack::Subtitle;
- else if (trackElement.kind() == TextTrack::descriptionsKeyword())
- platformKind = PlatformTextTrack::Description;
- else if (trackElement.kind() == TextTrack::forcedKeyword())
- platformKind = PlatformTextTrack::Forced;
- else
- continue;
-
- const AtomicString& mode = trackElement.track()->mode();
-
- PlatformTextTrack::TrackMode platformMode = PlatformTextTrack::Disabled;
- if (TextTrack::hiddenKeyword() == mode)
- platformMode = PlatformTextTrack::Hidden;
- else if (TextTrack::disabledKeyword() == mode)
- platformMode = PlatformTextTrack::Disabled;
- else if (TextTrack::showingKeyword() == mode)
- platformMode = PlatformTextTrack::Showing;
-
- outOfBandTrackSources.append(PlatformTextTrack::createOutOfBand(trackElement.label(), trackElement.srclang(), url.string(), platformMode, platformKind, trackElement.track()->uniqueId(), trackElement.isDefault()));
- }
-
- return outOfBandTrackSources;
+ if (!fastHasAttribute(HTMLNames::crossoriginAttr))
+ return Unspecified;
+ if (equalIgnoringCase(fastGetAttribute(HTMLNames::crossoriginAttr), "use-credentials"))
+ return UseCredentials;
+ return Anonymous;
}
-#endif
bool HTMLMediaElement::mediaPlayerNeedsSiteSpecificHacks() const
{
@@ -6025,17 +5571,10 @@ bool HTMLMediaElement::mediaPlayerIsVideo() const
LayoutRect HTMLMediaElement::mediaPlayerContentBoxRect() const
{
if (renderer())
- return renderer()->enclosingBox().contentBoxRect();
+ return renderer()->enclosingBox()->contentBoxRect();
return LayoutRect();
}
-float HTMLMediaElement::mediaPlayerContentsScale() const
-{
- if (auto page = document().page())
- return page->pageScaleFactor() * page->deviceScaleFactor();
- return 1;
-}
-
void HTMLMediaElement::mediaPlayerSetSize(const IntSize& size)
{
setIntegralAttribute(widthAttr, size.width());
@@ -6067,14 +5606,19 @@ bool HTMLMediaElement::mediaPlayerIsLooping() const
return loop();
}
-CachedResourceLoader* HTMLMediaElement::mediaPlayerCachedResourceLoader()
+HostWindow* HTMLMediaElement::mediaPlayerHostWindow()
{
- return &document().cachedResourceLoader();
+ return mediaPlayerOwningDocument()->view()->hostWindow();
}
-RefPtr<PlatformMediaResourceLoader> HTMLMediaElement::mediaPlayerCreateResourceLoader(std::unique_ptr<PlatformMediaResourceLoaderClient> client)
+IntRect HTMLMediaElement::mediaPlayerWindowClipRect()
+{
+ return mediaPlayerOwningDocument()->view()->windowClipRect();
+}
+
+CachedResourceLoader* HTMLMediaElement::mediaPlayerCachedResourceLoader()
{
- return adoptRef(*new MediaResourceLoader(document(), fastGetAttribute(HTMLNames::crossoriginAttr), WTF::move(client)));
+ return mediaPlayerOwningDocument()->cachedResourceLoader();
}
bool HTMLMediaElement::mediaPlayerShouldWaitForResponseToAuthenticationChallenge(const AuthenticationChallenge& challenge)
@@ -6098,81 +5642,22 @@ bool HTMLMediaElement::mediaPlayerShouldWaitForResponseToAuthenticationChallenge
return true;
}
-String HTMLMediaElement::mediaPlayerSourceApplicationIdentifier() const
-{
- if (Frame* frame = document().frame()) {
- if (NetworkingContext* networkingContext = frame->loader().networkingContext())
- return networkingContext->sourceApplicationIdentifier();
- }
- return emptyString();
-}
-
-Vector<String> HTMLMediaElement::mediaPlayerPreferredAudioCharacteristics() const
-{
- Page* page = document().page();
- if (CaptionUserPreferences* captionPreferences = page ? page->group().captionPreferences() : nullptr)
- return captionPreferences->preferredAudioCharacteristics();
- return Vector<String>();
-}
-
-#if PLATFORM(IOS)
-String HTMLMediaElement::mediaPlayerNetworkInterfaceName() const
-{
- Settings* settings = document().settings();
- if (!settings)
- return emptyString();
-
- return settings->networkInterfaceName();
-}
-
-bool HTMLMediaElement::mediaPlayerGetRawCookies(const URL& url, Vector<Cookie>& cookies) const
+void HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture()
{
- return getRawCookies(&document(), url, cookies);
-}
+ m_mediaSession->removeBehaviorRestriction(HTMLMediaSession::RequireUserGestureForLoad);
+ m_mediaSession->removeBehaviorRestriction(HTMLMediaSession::RequireUserGestureForRateChange);
+ m_mediaSession->removeBehaviorRestriction(HTMLMediaSession::RequireUserGestureForFullscreen);
+#if ENABLE(IOS_AIRPLAY)
+ m_mediaSession->removeBehaviorRestriction(HTMLMediaSession::RequireUserGestureToShowPlaybackTargetPicker);
#endif
-
-bool HTMLMediaElement::mediaPlayerIsInMediaDocument() const
-{
- return document().isMediaDocument();
-}
-
-void HTMLMediaElement::mediaPlayerEngineFailedToLoad() const
-{
- if (!m_player)
- return;
-
- if (Frame* frame = document().frame())
- frame->mainFrame().diagnosticLoggingClient().logDiagnosticMessageWithValue(DiagnosticLoggingKeys::engineFailedToLoadKey(), m_player->engineDescription(), String::number(m_player->platformErrorCode()), ShouldSample::No);
}
-double HTMLMediaElement::mediaPlayerRequestedPlaybackRate() const
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+bool HTMLMediaElement::shouldUseVideoPluginProxy() const
{
- return potentiallyPlaying() ? requestedPlaybackRate() : 0;
+ return document().settings() && document().settings()->isVideoPluginProxyEnabled();
}
-
-#if USE(GSTREAMER)
-void HTMLMediaElement::requestInstallMissingPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback& callback)
-{
- if (!document().page())
- return;
-
- document().page()->chrome().client().requestInstallMissingMediaPlugins(details, description, callback);
-}
-#endif
-
-void HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture()
-{
- MediaElementSession::BehaviorRestrictions restrictionsToRemove = MediaElementSession::RequireUserGestureForLoad
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- | MediaElementSession::RequireUserGestureToShowPlaybackTargetPicker
- | MediaElementSession::RequireUserGestureToAutoplayToExternalDevice
#endif
- | MediaElementSession::RequireUserGestureForLoad
- | MediaElementSession::RequireUserGestureForRateChange
- | MediaElementSession::RequireUserGestureForAudioRateChange
- | MediaElementSession::RequireUserGestureForFullscreen;
- m_mediaSession->removeBehaviorRestriction(restrictionsToRemove);
-}
#if ENABLE(MEDIA_SOURCE)
RefPtr<VideoPlaybackQuality> HTMLMediaElement::getVideoPlaybackQuality()
@@ -6183,7 +5668,7 @@ RefPtr<VideoPlaybackQuality> HTMLMediaElement::getVideoPlaybackQuality()
double now = performance ? performance->now() : 0;
#else
DocumentLoader* loader = document().loader();
- double now = loader ? 1000.0 * loader->timing().monotonicTimeToZeroBasedDocumentTime(monotonicallyIncreasingTime()) : 0;
+ double now = loader ? 1000.0 * loader->timing()->monotonicTimeToZeroBasedDocumentTime(monotonicallyIncreasingTime()) : 0;
#endif
if (!m_player)
@@ -6193,7 +5678,7 @@ RefPtr<VideoPlaybackQuality> HTMLMediaElement::getVideoPlaybackQuality()
m_droppedVideoFrames + m_player->totalVideoFrames(),
m_droppedVideoFrames + m_player->droppedVideoFrames(),
m_player->corruptedVideoFrames(),
- m_player->totalFrameDelay().toDouble());
+ m_player->totalFrameDelay());
}
#endif
@@ -6207,7 +5692,6 @@ DOMWrapperWorld& HTMLMediaElement::ensureIsolatedWorld()
bool HTMLMediaElement::ensureMediaControlsInjectedScript()
{
- LOG(Media, "HTMLMediaElement::ensureMediaControlsInjectedScript(%p)", this);
Page* page = document().page();
if (!page)
return false;
@@ -6217,22 +5701,15 @@ bool HTMLMediaElement::ensureMediaControlsInjectedScript()
return false;
DOMWrapperWorld& world = ensureIsolatedWorld();
- ScriptController& scriptController = document().frame()->script();
+ ScriptController& scriptController = page->mainFrame().script();
JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world));
JSC::ExecState* exec = globalObject->globalExec();
- JSC::JSLockHolder lock(exec);
- JSC::JSValue functionValue = globalObject->get(exec, JSC::Identifier::fromString(exec, "createControls"));
- if (functionValue.isFunction())
+ JSC::JSValue overlayValue = globalObject->get(exec, JSC::Identifier(exec, "createControls"));
+ if (overlayValue.isFunction())
return true;
-#ifndef NDEBUG
- // Setting a scriptURL allows the source to be debuggable in the inspector.
- URL scriptURL = URL(ParsedURLString, ASCIILiteral("mediaControlsScript"));
-#else
- URL scriptURL;
-#endif
- scriptController.evaluateInWorld(ScriptSourceCode(mediaControlsScript, scriptURL), world);
+ scriptController.evaluateInWorld(ScriptSourceCode(mediaControlsScript), world);
if (exec->hadException()) {
exec->clearException();
return false;
@@ -6241,17 +5718,13 @@ bool HTMLMediaElement::ensureMediaControlsInjectedScript()
return true;
}
-static void setPageScaleFactorProperty(JSC::ExecState* exec, JSC::JSValue controllerValue, float pageScaleFactor)
-{
- JSC::PutPropertySlot propertySlot(controllerValue);
- JSC::JSObject* controllerObject = controllerValue.toObject(exec);
- controllerObject->methodTable()->put(controllerObject, exec, JSC::Identifier::fromString(exec, "pageScaleFactor"), JSC::jsNumber(pageScaleFactor), propertySlot);
-}
-
void HTMLMediaElement::didAddUserAgentShadowRoot(ShadowRoot* root)
{
- LOG(Media, "HTMLMediaElement::didAddUserAgentShadowRoot(%p)", this);
-
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ // JavaScript controls are not enabled with the video plugin proxy.
+ if (shouldUseVideoPluginProxy())
+ return;
+#endif
Page* page = document().page();
if (!page)
return;
@@ -6261,110 +5734,34 @@ void HTMLMediaElement::didAddUserAgentShadowRoot(ShadowRoot* root)
if (!ensureMediaControlsInjectedScript())
return;
- ScriptController& scriptController = document().frame()->script();
+ ScriptController& scriptController = page->mainFrame().script();
JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world));
JSC::ExecState* exec = globalObject->globalExec();
JSC::JSLockHolder lock(exec);
- // The media controls script must provide a method with the following details.
- // Name: createControls
- // Parameters:
- // 1. The ShadowRoot element that will hold the controls.
- // 2. This object (and HTMLMediaElement).
- // 3. The MediaControlsHost object.
- // Return value:
- // A reference to the created media controller instance.
-
- JSC::JSValue functionValue = globalObject->get(exec, JSC::Identifier::fromString(exec, "createControls"));
- if (functionValue.isUndefinedOrNull())
+ // It is expected the JS file provides a createControls(shadowRoot, video, mediaControlsHost) function.
+ JSC::JSValue overlayValue = globalObject->get(exec, JSC::Identifier(exec, "createControls"));
+ if (overlayValue.isUndefinedOrNull())
return;
if (!m_mediaControlsHost)
m_mediaControlsHost = MediaControlsHost::create(this);
- auto mediaJSWrapper = toJS(exec, globalObject, this);
- auto mediaControlsHostJSWrapper = toJS(exec, globalObject, m_mediaControlsHost.get());
-
JSC::MarkedArgumentBuffer argList;
argList.append(toJS(exec, globalObject, root));
- argList.append(mediaJSWrapper);
- argList.append(mediaControlsHostJSWrapper);
+ argList.append(toJS(exec, globalObject, this));
+ argList.append(toJS(exec, globalObject, m_mediaControlsHost.get()));
- JSC::JSObject* function = functionValue.toObject(exec);
+ JSC::JSObject* overlay = overlayValue.toObject(exec);
JSC::CallData callData;
- JSC::CallType callType = function->methodTable()->getCallData(function, callData);
+ JSC::CallType callType = overlay->methodTable()->getCallData(overlay, callData);
if (callType == JSC::CallTypeNone)
return;
- JSC::JSValue controllerValue = JSC::call(exec, function, callType, callData, globalObject, argList);
- exec->clearException();
- JSC::JSObject* controllerObject = JSC::jsDynamicCast<JSC::JSObject*>(controllerValue);
- if (!controllerObject)
- return;
-
- // Connect the Media, MediaControllerHost, and Controller so the GC knows about their relationship
- JSC::JSObject* mediaJSWrapperObject = mediaJSWrapper.toObject(exec);
- JSC::Identifier controlsHost = JSC::Identifier::fromString(&exec->vm(), "controlsHost");
-
- ASSERT(!mediaJSWrapperObject->hasProperty(exec, controlsHost));
-
- mediaJSWrapperObject->putDirect(exec->vm(), controlsHost, mediaControlsHostJSWrapper, JSC::DontDelete | JSC::DontEnum | JSC::ReadOnly);
-
- JSC::JSObject* mediaControlsHostJSWrapperObject = JSC::jsDynamicCast<JSC::JSObject*>(mediaControlsHostJSWrapper);
- if (!mediaControlsHostJSWrapperObject)
- return;
-
- JSC::Identifier controller = JSC::Identifier::fromString(&exec->vm(), "controller");
-
- ASSERT(!controllerObject->hasProperty(exec, controller));
-
- mediaControlsHostJSWrapperObject->putDirect(exec->vm(), controller, controllerValue, JSC::DontDelete | JSC::DontEnum | JSC::ReadOnly);
-
- setPageScaleFactorProperty(exec, controllerValue, page->pageScaleFactor());
-
+ JSC::call(exec, overlay, callType, callData, globalObject, argList);
if (exec->hadException())
exec->clearException();
}
-
-void HTMLMediaElement::setMediaControlsDependOnPageScaleFactor(bool dependsOnPageScale)
-{
- LOG(Media, "MediaElement::setMediaControlsDependPageScaleFactor(%p) = %s", this, boolString(dependsOnPageScale));
-
- Settings* settings = document().settings();
- if (settings && settings->mediaControlsScaleWithPageZoom()) {
- LOG(Media, "MediaElement::setMediaControlsDependPageScaleFactor(%p) forced to false by Settings value", this);
- m_mediaControlsDependOnPageScaleFactor = false;
- return;
- }
-
- if (m_mediaControlsDependOnPageScaleFactor == dependsOnPageScale)
- return;
-
- m_mediaControlsDependOnPageScaleFactor = dependsOnPageScale;
-
- if (m_mediaControlsDependOnPageScaleFactor)
- document().registerForPageScaleFactorChangedCallbacks(this);
- else
- document().unregisterForPageScaleFactorChangedCallbacks(this);
-}
-
-void HTMLMediaElement::pageScaleFactorChanged()
-{
- Page* page = document().page();
- if (!page)
- return;
-
- LOG(Media, "HTMLMediaElement::pageScaleFactorChanged(%p) = %f", this, page->pageScaleFactor());
- DOMWrapperWorld& world = ensureIsolatedWorld();
- ScriptController& scriptController = document().frame()->script();
- JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world));
- JSC::ExecState* exec = globalObject->globalExec();
- JSC::JSLockHolder lock(exec);
-
- JSC::JSValue controllerValue = controllerJSValue(*exec, *globalObject, *this);
-
- setPageScaleFactorProperty(exec, controllerValue, page->pageScaleFactor());
-}
#endif // ENABLE(MEDIA_CONTROLS_SCRIPT)
unsigned long long HTMLMediaElement::fileSize() const
@@ -6375,284 +5772,39 @@ unsigned long long HTMLMediaElement::fileSize() const
return 0;
}
-PlatformMediaSession::MediaType HTMLMediaElement::mediaType() const
-{
- if (m_player && m_readyState >= HAVE_METADATA)
- return hasVideo() ? PlatformMediaSession::Video : PlatformMediaSession::Audio;
-
- return presentationType();
-}
-
-PlatformMediaSession::MediaType HTMLMediaElement::presentationType() const
+MediaSession::MediaType HTMLMediaElement::mediaType() const
{
if (hasTagName(HTMLNames::videoTag))
- return PlatformMediaSession::Video;
-
- return PlatformMediaSession::Audio;
-}
-
-PlatformMediaSession::DisplayType HTMLMediaElement::displayType() const
-{
- if (m_videoFullscreenMode == VideoFullscreenModeStandard)
- return PlatformMediaSession::Fullscreen;
- if (m_videoFullscreenMode & VideoFullscreenModePictureInPicture)
- return PlatformMediaSession::Optimized;
- if (m_videoFullscreenMode == VideoFullscreenModeNone)
- return PlatformMediaSession::Normal;
-
- ASSERT_NOT_REACHED();
- return PlatformMediaSession::Normal;
-}
-
-#if ENABLE(MEDIA_SOURCE)
-size_t HTMLMediaElement::maximumSourceBufferSize(const SourceBuffer& buffer) const
-{
- return m_mediaSession->maximumMediaSourceBufferSize(buffer);
-}
-#endif
+ return MediaSession::Video;
-void HTMLMediaElement::suspendPlayback()
-{
- LOG(Media, "HTMLMediaElement::pausePlayback(%p) - paused = %s", this, boolString(paused()));
- if (!paused())
- pause();
+ return MediaSession::Audio;
}
-void HTMLMediaElement::mayResumePlayback(bool shouldResume)
-{
- LOG(Media, "HTMLMediaElement::resumePlayback(%p) - paused = %s", this, boolString(paused()));
- if (paused() && shouldResume)
- play();
-}
-
-String HTMLMediaElement::mediaSessionTitle() const
+void HTMLMediaElement::beginInterruption()
{
- if (fastHasAttribute(titleAttr))
- return fastGetAttribute(titleAttr);
+ LOG(Media, "HTMLMediaElement::beginInterruption");
- return m_currentSrc;
-}
-
-void HTMLMediaElement::didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType command)
-{
- LOG(Media, "HTMLMediaElement::didReceiveRemoteControlCommand(%p) - %i", this, static_cast<int>(command));
-
- switch (command) {
- case PlatformMediaSession::PlayCommand:
- play();
- break;
- case PlatformMediaSession::PauseCommand:
+ m_resumePlaybackAfterInterruption = !paused();
+ if (m_resumePlaybackAfterInterruption)
pause();
- break;
- case PlatformMediaSession::TogglePlayPauseCommand:
- canPlay() ? play() : pause();
- break;
- case PlatformMediaSession::BeginSeekingBackwardCommand:
- beginScanning(Backward);
- break;
- case PlatformMediaSession::BeginSeekingForwardCommand:
- beginScanning(Forward);
- break;
- case PlatformMediaSession::EndSeekingBackwardCommand:
- case PlatformMediaSession::EndSeekingForwardCommand:
- endScanning();
- break;
- default:
- { } // Do nothing
- }
-}
-
-bool HTMLMediaElement::overrideBackgroundPlaybackRestriction() const
-{
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- if (m_player && m_player->isCurrentPlaybackTargetWireless())
- return true;
-#endif
- if (m_videoFullscreenMode & VideoFullscreenModePictureInPicture)
- return true;
-#if PLATFORM(IOS)
- if (m_videoFullscreenMode == VideoFullscreenModeStandard && wkIsOptimizedFullscreenSupported() && isPlaying())
- return true;
-#endif
- return false;
-}
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-void HTMLMediaElement::updateMediaState(UpdateMediaState updateState)
-{
- if (updateState == UpdateMediaState::Asynchronously) {
- scheduleDelayedAction(CheckMediaState);
- return;
- }
-
- MediaProducer::MediaStateFlags state = mediaState();
- if (m_mediaState == state)
- return;
-
- m_mediaState = state;
- m_mediaSession->mediaStateDidChange(*this, m_mediaState);
-}
-#endif
-
-MediaProducer::MediaStateFlags HTMLMediaElement::mediaState() const
-{
-
- MediaStateFlags state = IsNotPlaying;
-
- bool hasActiveVideo = isVideo() && hasVideo();
- bool hasAudio = this->hasAudio();
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- if (m_player && m_player->isCurrentPlaybackTargetWireless())
- state |= IsPlayingToExternalDevice;
-
- if (m_player && m_hasPlaybackTargetAvailabilityListeners && !m_mediaSession->wirelessVideoPlaybackDisabled(*this))
- state |= RequiresPlaybackTargetMonitoring;
-
- bool requireUserGesture = m_mediaSession->hasBehaviorRestriction(MediaElementSession::RequireUserGestureToAutoplayToExternalDevice);
- if (m_readyState >= HAVE_METADATA && !requireUserGesture && !m_failedToPlayToWirelessTarget)
- state |= ExternalDeviceAutoPlayCandidate;
-
- if (hasActiveVideo && endedPlayback())
- state |= DidPlayToEnd;
-#endif
-
- if (!isPlaying())
- return state;
-
- if (hasAudio && !muted())
- state |= IsPlayingAudio;
-
- if (hasActiveVideo)
- state |= IsPlayingVideo;
-
- return state;
-}
-
-void HTMLMediaElement::pageMutedStateDidChange()
-{
- updateVolume();
-}
-
-bool HTMLMediaElement::effectiveMuted() const
-{
- return muted() || (document().page() && document().page()->isMuted());
-}
-
-bool HTMLMediaElement::doesHaveAttribute(const AtomicString& attribute, AtomicString* value) const
-{
- QualifiedName attributeName(nullAtom, attribute, nullAtom);
-
- AtomicString elementValue = fastGetAttribute(attributeName);
- if (elementValue.isNull())
- return false;
-
- if (Settings* settings = document().settings()) {
- if (attributeName == HTMLNames::x_itunes_inherit_uri_query_componentAttr && !settings->enableInheritURIQueryComponent())
- return false;
- }
-
- if (value)
- *value = elementValue;
-
- return true;
}
-void HTMLMediaElement::setShouldBufferData(bool shouldBuffer)
+void HTMLMediaElement::endInterruption(MediaSession::EndInterruptionFlags flags)
{
- if (m_player)
- m_player->setShouldBufferData(shouldBuffer);
-}
+ bool shouldResumePlayback = m_resumePlaybackAfterInterruption;
+ m_resumePlaybackAfterInterruption = false;
-void HTMLMediaElement::purgeBufferedDataIfPossible()
-{
-#if PLATFORM(IOS)
- // This is called to relieve memory pressure. Turning off buffering causes the media playback
- // daemon to release memory associated with queued-up video frames.
- // We turn it back on right away, but new frames won't get loaded unless playback is resumed.
- setShouldBufferData(false);
- setShouldBufferData(true);
-#endif
-}
-
-bool HTMLMediaElement::canSaveMediaData() const
-{
- if (m_player)
- return m_player->canSaveMediaData();
-
- return false;
-}
-
-#if ENABLE(MEDIA_SESSION)
-double HTMLMediaElement::playerVolume() const
-{
- return m_player ? m_player->volume() : 0;
-}
-
-MediaSession* HTMLMediaElement::session() const
-{
- MediaSession* session = m_session.get();
- if (session && session->kindEnum() == MediaSession::Kind::Default)
- return nullptr;
- return session;
-}
-
-void HTMLMediaElement::setSession(MediaSession* session)
-{
- // 6.1
- // 1. Let m be the media element in question.
- // 2. Let old media session be m's current media session, if it has one, and null otherwise.
- // 3. Let new media session be null.
- // 4. Set m's current media session to null, if it currently has one.
- // 5. Let m's current media session be the new value or the top-level browsing context's media session if the new
- // value is null.
- // 6. If the new value is null, then set the m's kind IDL attribute to the empty string. Otherwise, set m's kind IDL
- // attribute to the value of current media session's kind attribute.
- // 7. Let new media session be m's current media session.
- // 8. Update media sessions: If old media session and new media session are the same (whether both null or both the
- // same media session), then terminate these steps.
- // 9. If m is an active audio-producing participant of old media session, then pause m and remove m from old media
- // session's active audio-producing participants.
- // 10. If old media session is not null and no longer has one or more active audio-producing participants, then run
- // the media session release algorithm for old media session.
-
- if (m_session) {
- if (m_session->isMediaElementActive(*this))
- pause();
-
- m_session->removeMediaElement(*this);
-
- if (!m_session->hasActiveMediaElements())
- m_session->releaseSession();
- }
-
- if (session)
- setSessionInternal(*session);
- else
- setSessionInternal(document().defaultMediaSession());
-}
-
-void HTMLMediaElement::setSessionInternal(MediaSession& session)
-{
- m_session = &session;
- session.addMediaElement(*this);
- m_kind = session.kind();
-}
-
-void HTMLMediaElement::setShouldDuck(bool duck)
-{
- if (m_shouldDuck == duck)
+ if (!flags & MediaSession::MayResumePlaying)
return;
- m_shouldDuck = duck;
- updateVolume();
+ if (shouldResumePlayback)
+ play();
}
-#endif
-
-void HTMLMediaElement::allowsMediaDocumentInlinePlaybackChanged()
+void HTMLMediaElement::pausePlayback()
{
- if (potentiallyPlaying() && m_mediaSession->requiresFullscreenForVideoPlayback(*this) && !isFullscreen())
- enterFullscreen();
+ if (!paused())
+ pause();
}
}
diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h
index 58d88c233..07faa23cc 100644
--- a/Source/WebCore/html/HTMLMediaElement.h
+++ b/Source/WebCore/html/HTMLMediaElement.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,13 +30,16 @@
#include "HTMLElement.h"
#include "ActiveDOMObject.h"
#include "GenericEventQueue.h"
-#include "GenericTaskQueue.h"
-#include "HTMLMediaElementEnums.h"
+#include "HTMLMediaSession.h"
#include "MediaCanStartListener.h"
#include "MediaControllerInterface.h"
-#include "MediaElementSession.h"
-#include "MediaProducer.h"
-#include "PageThrottler.h"
+#include "MediaPlayer.h"
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "HTMLFrameOwnerElement.h"
+#include "HTMLPlugInImageElement.h"
+#include "MediaPlayerProxy.h"
+#endif
#if ENABLE(VIDEO_TRACK)
#include "AudioTrack.h"
@@ -44,21 +47,20 @@
#include "PODIntervalTree.h"
#include "TextTrack.h"
#include "TextTrackCue.h"
-#include "VTTCue.h"
#include "VideoTrack.h"
#endif
-#ifndef NDEBUG
-#include <wtf/StringPrintStream.h>
+#if ENABLE(MEDIA_STREAM)
+#include "MediaStream.h"
#endif
+
namespace WebCore {
#if ENABLE(WEB_AUDIO)
class AudioSourceProvider;
class MediaElementAudioSourceNode;
#endif
-class DisplaySleepDisabler;
class Event;
class HTMLSourceElement;
class HTMLTrackElement;
@@ -67,17 +69,18 @@ class MediaController;
class MediaControls;
class MediaControlsHost;
class MediaError;
-class MediaPlayer;
+class PageActivityAssertionToken;
class TimeRanges;
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+class Widget;
+#endif
+#if PLATFORM(MAC)
+class DisplaySleepDisabler;
+#endif
#if ENABLE(ENCRYPTED_MEDIA_V2)
class MediaKeys;
#endif
-#if ENABLE(MEDIA_SESSION)
-class MediaSession;
-#endif
#if ENABLE(MEDIA_SOURCE)
-class MediaSource;
-class SourceBuffer;
class VideoPlaybackQuality;
#endif
@@ -89,18 +92,18 @@ class TextTrackList;
class VideoTrackList;
class VideoTrackPrivate;
-typedef PODIntervalTree<MediaTime, TextTrackCue*> CueIntervalTree;
+typedef PODIntervalTree<double, TextTrackCue*> CueIntervalTree;
typedef CueIntervalTree::IntervalType CueInterval;
typedef Vector<CueInterval> CueList;
#endif
-#if ENABLE(MEDIA_STREAM)
-class MediaStream;
-#endif
-
class HTMLMediaElement
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ : public HTMLFrameOwnerElement
+#else
: public HTMLElement
- , private MediaPlayerClient, public MediaPlayerSupportsTypeClient, private MediaCanStartListener, public ActiveDOMObject, public MediaControllerInterface , public PlatformMediaSessionClient, private MediaProducer
+#endif
+ , private MediaPlayerClient, public MediaPlayerSupportsTypeClient, private MediaCanStartListener, public ActiveDOMObject, public MediaControllerInterface , public MediaSessionClient
#if ENABLE(VIDEO_TRACK)
, private AudioTrackClient
, private TextTrackClient
@@ -117,39 +120,36 @@ public:
virtual bool hasVideo() const override { return false; }
virtual bool hasAudio() const override;
- static HashSet<HTMLMediaElement*>& allMediaElements();
-
void rewind(double timeDelta);
- WEBCORE_EXPORT virtual void returnToRealtime() override;
+ virtual void returnToRealtime() override;
// Eventually overloaded in HTMLVideoElement
virtual bool supportsFullscreen() const override { return false; };
+ virtual bool supportsSave() const;
virtual bool supportsScanning() const override;
-
- bool canSaveMediaData() const;
-
- virtual bool doesHaveAttribute(const AtomicString&, AtomicString* value = nullptr) const override;
-
- WEBCORE_EXPORT PlatformMedia platformMedia() const;
+
+ PlatformMedia platformMedia() const;
+#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* platformLayer() const;
#if PLATFORM(IOS)
- void setVideoFullscreenLayer(PlatformLayer*);
- PlatformLayer* videoFullscreenLayer() const { return m_videoFullscreenLayer.get(); }
- void setVideoFullscreenFrame(FloatRect);
- void setVideoFullscreenGravity(MediaPlayerEnums::VideoGravity);
- MediaPlayerEnums::VideoGravity videoFullscreenGravity() const { return m_videoFullscreenGravity; }
+ PlatformLayer* borrowPlatformLayer();
+ void returnPlatformLayer(PlatformLayer*);
+#endif
#endif
- using HTMLMediaElementEnums::DelayedActionType;
+ enum DelayedActionType {
+ LoadMediaResource = 1 << 0,
+ ConfigureTextTracks = 1 << 1,
+ TextTrackChangesNotification = 1 << 2,
+ ConfigureTextTrackDisplay = 1 << 3,
+ };
void scheduleDelayedAction(DelayedActionType);
- MediaPlayerEnums::MovieLoadType movieLoadType() const;
+ MediaPlayer::MovieLoadType movieLoadType() const;
bool inActiveDocument() const { return m_inActiveDocument; }
-
- const Document* hostingDocument() const override { return &document(); }
-
+
// DOM API
// error state
PassRefPtr<MediaError> error() const;
@@ -163,7 +163,7 @@ public:
#endif
// network state
- using HTMLMediaElementEnums::NetworkState;
+ enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE };
NetworkState networkState() const;
String preload() const;
@@ -174,53 +174,36 @@ public:
String canPlayType(const String& mimeType, const String& keySystem = String(), const URL& = URL()) const;
// ready state
- using HTMLMediaElementEnums::ReadyState;
virtual ReadyState readyState() const override;
bool seeking() const;
// playback state
- WEBCORE_EXPORT virtual double currentTime() const override;
+ virtual double currentTime() const override;
virtual void setCurrentTime(double) override;
- virtual void setCurrentTime(double, ExceptionCode&);
- virtual double getStartDate() const;
- WEBCORE_EXPORT virtual double duration() const override;
- WEBCORE_EXPORT virtual bool paused() const override;
+ virtual double duration() const override;
+ virtual bool paused() const override;
virtual double defaultPlaybackRate() const override;
virtual void setDefaultPlaybackRate(double) override;
- WEBCORE_EXPORT virtual double playbackRate() const override;
+ virtual double playbackRate() const override;
virtual void setPlaybackRate(double) override;
-
-// MediaTime versions of playback state
- MediaTime currentMediaTime() const;
- void setCurrentTime(const MediaTime&);
- MediaTime durationMediaTime() const;
- void fastSeek(const MediaTime&);
-
void updatePlaybackRate();
bool webkitPreservesPitch() const;
void setWebkitPreservesPitch(bool);
virtual PassRefPtr<TimeRanges> played() override;
virtual PassRefPtr<TimeRanges> seekable() const override;
- WEBCORE_EXPORT bool ended() const;
+ bool ended() const;
bool autoplay() const;
bool loop() const;
void setLoop(bool b);
- WEBCORE_EXPORT virtual void play() override;
- WEBCORE_EXPORT virtual void pause() override;
- virtual void setShouldBufferData(bool) override;
+ virtual void play() override;
+ virtual void pause() override;
void fastSeek(double);
- double minFastReverseRate() const;
- double maxFastForwardRate() const;
-
- void purgeBufferedDataIfPossible();
// captions
bool webkitHasClosedCaptions() const;
bool webkitClosedCaptionsVisible() const;
void setWebkitClosedCaptionsVisible(bool);
- virtual bool elementIsHidden() const override { return m_elementIsHidden; }
-
#if ENABLE(MEDIA_STATISTICS)
// Statistics
unsigned webkitAudioDecodedByteCount() const;
@@ -231,7 +214,6 @@ public:
// Media Source.
void closeMediaSource();
void incrementDroppedFrameCount() { ++m_droppedVideoFrames; }
- size_t maximumSourceBufferSize(const SourceBuffer&) const;
#endif
#if ENABLE(ENCRYPTED_MEDIA)
@@ -240,32 +222,33 @@ public:
void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionCode&);
void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, ExceptionCode&);
void webkitCancelKeyRequest(const String& keySystem, const String& sessionId, ExceptionCode&);
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyadded);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyerror);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeymessage);
+#endif
+#if ENABLE(ENCRYPTED_MEDIA) || ENABLE(ENCRYPTED_MEDIA_V2)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitneedkey);
#endif
#if ENABLE(ENCRYPTED_MEDIA_V2)
MediaKeys* keys() const { return m_mediaKeys.get(); }
void setMediaKeys(MediaKeys*);
-
- void keyAdded();
#endif
// controls
bool controls() const;
void setControls(bool);
- WEBCORE_EXPORT virtual double volume() const override;
+ virtual double volume() const override;
virtual void setVolume(double, ExceptionCode&) override;
- WEBCORE_EXPORT virtual bool muted() const override;
- WEBCORE_EXPORT virtual void setMuted(bool) override;
-
- WEBCORE_EXPORT void togglePlayState();
- WEBCORE_EXPORT virtual void beginScrubbing() override;
- WEBCORE_EXPORT virtual void endScrubbing() override;
-
- virtual void beginScanning(ScanDirection) override;
- virtual void endScanning() override;
- double nextScanRate();
+ virtual bool muted() const override;
+ virtual void setMuted(bool) override;
- WEBCORE_EXPORT virtual bool canPlay() const override;
+ void togglePlayState();
+ virtual void beginScrubbing() override;
+ virtual void endScrubbing() override;
+
+ virtual bool canPlay() const override;
double percentLoaded() const;
@@ -284,9 +267,9 @@ public:
void addTextTrack(PassRefPtr<TextTrack>);
void addVideoTrack(PassRefPtr<VideoTrack>);
void removeAudioTrack(AudioTrack*);
- void removeTextTrack(TextTrack*, bool scheduleEvent = true);
+ void removeTextTrack(TextTrack*);
void removeVideoTrack(VideoTrack*);
- void forgetResourceSpecificTracks();
+ void removeAllInbandTracks();
void closeCaptionTracksChanged();
void notifyMediaPlayerOfTextTrackChanges();
@@ -300,17 +283,30 @@ public:
virtual void mediaPlayerDidRemoveTextTrack(PassRefPtr<InbandTextTrackPrivate>) override;
virtual void mediaPlayerDidRemoveVideoTrack(PassRefPtr<VideoTrackPrivate>) override;
-#if ENABLE(AVF_CAPTIONS)
- virtual Vector<RefPtr<PlatformTextTrack>> outOfBandTrackSources() override;
-#endif
-
#if USE(PLATFORM_TEXT_TRACK_MENU)
virtual void setSelectedTextTrack(PassRefPtr<PlatformTextTrack>) override;
virtual Vector<RefPtr<PlatformTextTrack>> platformTextTracks() override;
PlatformTextTrackMenuInterface* platformTextTrackMenu();
#endif
- struct TrackGroup;
+ struct TrackGroup {
+ enum GroupKind { CaptionsAndSubtitles, Description, Chapter, Metadata, Other };
+
+ TrackGroup(GroupKind kind)
+ : visibleTrack(0)
+ , defaultTrack(0)
+ , kind(kind)
+ , hasSrcLang(false)
+ {
+ }
+
+ Vector<RefPtr<TextTrack>> tracks;
+ RefPtr<TextTrack> visibleTrack;
+ RefPtr<TextTrack> defaultTrack;
+ GroupKind kind;
+ bool hasSrcLang;
+ };
+
void configureTextTrackGroupForLanguage(const TrackGroup&) const;
void configureTextTracks();
void configureTextTrackGroup(const TrackGroup&);
@@ -318,7 +314,7 @@ public:
void setSelectedTextTrack(TextTrack*);
bool textTracksAreReady() const;
- using HTMLMediaElementEnums::TextTrackVisibilityCheckType;
+ enum TextTrackVisibilityCheckType { CheckTextTrackVisibility, AssumeTextTrackVisibilityChanged };
void configureTextTrackDisplay(TextTrackVisibilityCheckType checkType = CheckTextTrackVisibility);
void updateTextTrackDisplay();
@@ -339,21 +335,28 @@ public:
bool requiresTextTrackRepresentation() const;
void setTextTrackRepresentation(TextTrackRepresentation*);
- void syncTextTrackBounds();
#endif
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ void ensureMediaPlayer();
+ void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; }
+ void deliverNotification(MediaPlayerProxyNotificationType notification);
+ void setMediaPlayerProxy(WebMediaPlayerProxy* proxy);
+ void getPluginProxyParams(URL& url, Vector<String>& names, Vector<String>& values);
+ void createMediaPlayerProxy();
+ void updateWidget(PluginCreationOption);
+#endif
+
+#if ENABLE(IOS_AIRPLAY)
void webkitShowPlaybackTargetPicker();
+ bool webkitCurrentPlaybackTargetIsWireless() const;
+
virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) override;
virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
- virtual void wirelessRoutesAvailableDidChange() override;
- virtual bool canPlayToWirelessPlaybackTarget() const override;
- virtual bool isPlayingToWirelessPlaybackTarget() const override;
- virtual void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
- virtual void setShouldPlayToPlaybackTarget(bool) override;
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitcurrentplaybacktargetiswirelesschanged);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitplaybacktargetavailabilitychanged);
#endif
- bool webkitCurrentPlaybackTargetIsWireless() const;
// EventTarget function.
// Both Node (via HTMLElement) and ActiveDOMObject define this method, which
@@ -364,16 +367,10 @@ public:
bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
- WEBCORE_EXPORT virtual bool isFullscreen() const override;
+ virtual bool isFullscreen() const override;
void toggleFullscreenState();
-
- using MediaPlayerEnums::VideoFullscreenMode;
- VideoFullscreenMode fullscreenMode() const { return m_videoFullscreenMode; }
- virtual void fullscreenModeChanged(VideoFullscreenMode mode) { m_videoFullscreenMode = mode; }
-
- void enterFullscreen(VideoFullscreenMode);
virtual void enterFullscreen() override;
- WEBCORE_EXPORT void exitFullscreen();
+ void exitFullscreen();
virtual bool hasClosedCaptions() const override;
virtual bool closedCaptionsVisible() const override;
@@ -387,9 +384,9 @@ public:
virtual void privateBrowsingStateDidChange() override;
// Media cache management.
- WEBCORE_EXPORT static void getSitesInMediaCache(Vector<String>&);
- WEBCORE_EXPORT static void clearMediaCache();
- WEBCORE_EXPORT static void clearMediaCacheForSite(const String&);
+ static void getSitesInMediaCache(Vector<String>&);
+ static void clearMediaCache();
+ static void clearMediaCacheForSite(const String&);
static void resetMediaEngines();
bool isPlaying() const { return m_playing; }
@@ -403,7 +400,7 @@ public:
AudioSourceProvider* audioSourceProvider();
#endif
- using HTMLMediaElementEnums::InvalidURLAction;
+ enum InvalidURLAction { DoNothing, Complain };
bool isSafeToLoadURL(const URL&, InvalidURLAction);
const String& mediaGroup() const;
@@ -412,50 +409,26 @@ public:
MediaController* controller() const;
void setController(PassRefPtr<MediaController>);
- void enteredOrExitedFullscreen() { configureMediaControls(); }
-
- unsigned long long fileSize() const;
-
- void mediaLoadingFailed(MediaPlayerEnums::NetworkState);
- void mediaLoadingFailedFatally(MediaPlayerEnums::NetworkState);
-
-#if ENABLE(MEDIA_SESSION)
- WEBCORE_EXPORT double playerVolume() const;
+#if !PLATFORM(IOS)
+ virtual bool willRespondToMouseClickEvents() override;
+#endif
- const String& kind() const { return m_kind; }
- void setKind(const String& kind) { m_kind = kind; }
+ void enteredOrExitedFullscreen() { configureMediaControls(); }
- MediaSession* session() const;
- void setSession(MediaSession*);
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ bool shouldUseVideoPluginProxy() const;
+#endif
- void setShouldDuck(bool);
+ unsigned long long fileSize() const;
- static HTMLMediaElement* elementWithID(uint64_t);
- uint64_t elementID() const { return m_elementID; }
-#endif
+ void mediaLoadingFailed(MediaPlayer::NetworkState);
+ void mediaLoadingFailedFatally(MediaPlayer::NetworkState);
#if ENABLE(MEDIA_SOURCE)
RefPtr<VideoPlaybackQuality> getVideoPlaybackQuality();
#endif
- MediaPlayerEnums::Preload preloadValue() const { return m_preload; }
- MediaElementSession& mediaSession() const { return *m_mediaSession; }
-
-#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- void pageScaleFactorChanged();
-#endif
-
- MediaControlsHost* mediaControlsHost() { return m_mediaControlsHost.get(); }
-
- bool isDisablingSleep() const { return m_sleepDisabler.get(); }
-
- double maxBufferedTime() const;
-
- virtual MediaProducer::MediaStateFlags mediaState() const override;
-
- void layoutSizeChanged();
-
- void allowsMediaDocumentInlinePlaybackChanged();
+ MediaPlayer::Preload preloadValue() const { return m_preload; }
protected:
HTMLMediaElement(const QualifiedName&, Document&, bool);
@@ -473,7 +446,7 @@ protected:
DisplayMode displayMode() const { return m_displayMode; }
virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
- virtual bool isMediaElement() const override final { return true; }
+ virtual bool isMediaElement() const override { return true; }
#if ENABLE(VIDEO_TRACK)
bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0 || !m_textTracks || !m_cueTree.size(); }
@@ -481,19 +454,15 @@ protected:
void endIgnoringTrackDisplayUpdateRequests();
#endif
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
-#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- bool mediaControlsDependOnPageScaleFactor() const { return m_mediaControlsDependOnPageScaleFactor; }
- void setMediaControlsDependOnPageScaleFactor(bool);
-#endif
-
- void scheduleEvent(const AtomicString& eventName);
+ HTMLMediaSession& mediaSession() const { return *m_mediaSession; }
private:
void createMediaPlayer();
virtual bool alwaysCreateUserAgentShadowRoot() const override { return true; }
+ virtual bool areAuthorShadowsAllowed() const override { return false; }
virtual bool hasCustomFocusLogic() const override;
virtual bool supportsFocus() const override;
@@ -504,30 +473,29 @@ private:
virtual void removedFrom(ContainerNode&) override;
virtual void didRecalcStyle(Style::Change) override;
+ virtual void defaultEventHandler(Event*) override;
+
virtual void didBecomeFullscreenElement() override;
virtual void willStopBeingFullscreenElement() override;
- // ActiveDOMObject API.
- const char* activeDOMObjectName() const override;
- bool canSuspendForPageCache() const override;
- void suspend(ReasonForSuspension) override;
- void resume() override;
- void stop() override;
- void stopWithoutDestroyingMediaPlayer();
- virtual void contextDestroyed() override;
+ // ActiveDOMObject functions.
+ virtual bool canSuspend() const override;
+ virtual void suspend(ReasonForSuspension) override;
+ virtual void resume() override;
+ virtual void stop() override;
virtual void mediaVolumeDidChange() override;
+#if ENABLE(PAGE_VISIBILITY_API)
virtual void visibilityStateChanged() override;
+#endif
virtual void updateDisplayState() { }
- void setReadyState(MediaPlayerEnums::ReadyState);
- void setNetworkState(MediaPlayerEnums::NetworkState);
-
- double effectivePlaybackRate() const;
- double requestedPlaybackRate() const;
+ void setReadyState(MediaPlayer::ReadyState);
+ void setNetworkState(MediaPlayer::NetworkState);
+ virtual Document* mediaPlayerOwningDocument() override;
virtual void mediaPlayerNetworkStateChanged(MediaPlayer*) override;
virtual void mediaPlayerReadyStateChanged(MediaPlayer*) override;
virtual void mediaPlayerTimeChanged(MediaPlayer*) override;
@@ -540,8 +508,10 @@ private:
virtual void mediaPlayerResourceNotSupported(MediaPlayer*) override;
virtual void mediaPlayerRepaint(MediaPlayer*) override;
virtual void mediaPlayerSizeChanged(MediaPlayer*) override;
+#if USE(ACCELERATED_COMPOSITING)
virtual bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*) override;
virtual void mediaPlayerRenderingModeChanged(MediaPlayer*) override;
+#endif
virtual void mediaPlayerEngineUpdated(MediaPlayer*) override;
virtual void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*) override;
@@ -555,29 +525,18 @@ private:
#endif
#if ENABLE(ENCRYPTED_MEDIA_V2)
- virtual RefPtr<ArrayBuffer> mediaPlayerCachedKeyForKeyId(const String& keyId) const override;
virtual bool mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array*) override;
- virtual String mediaPlayerMediaKeysStorageDirectory() const override;
-#endif
-
-#if ENABLE(MEDIA_STREAM)
- virtual String mediaPlayerMediaDeviceIdentifierStorageDirectory() const override;
#endif
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#if ENABLE(IOS_AIRPLAY)
virtual void mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*) override;
+ virtual void mediaPlayerPlaybackTargetAvailabilityChanged(MediaPlayer*) override;
void enqueuePlaybackTargetAvailabilityChangedEvent();
-
- using EventTarget::dispatchEvent;
- virtual bool dispatchEvent(PassRefPtr<Event>) override;
-#endif
-
-#if ENABLE(MEDIA_SESSION)
- void setSessionInternal(MediaSession&);
#endif
virtual String mediaPlayerReferrer() const override;
virtual String mediaPlayerUserAgent() const override;
+ virtual CORSMode mediaPlayerCORSMode() const override;
virtual bool mediaPlayerNeedsSiteSpecificHacks() const override;
virtual String mediaPlayerDocumentHost() const override;
@@ -588,58 +547,38 @@ private:
virtual bool mediaPlayerIsFullscreenPermitted() const override;
virtual bool mediaPlayerIsVideo() const override;
virtual LayoutRect mediaPlayerContentBoxRect() const override;
- virtual float mediaPlayerContentsScale() const override;
virtual void mediaPlayerSetSize(const IntSize&) override;
virtual void mediaPlayerPause() override;
virtual void mediaPlayerPlay() override;
virtual bool mediaPlayerPlatformVolumeConfigurationRequired() const override;
virtual bool mediaPlayerIsPaused() const override;
virtual bool mediaPlayerIsLooping() const override;
+ virtual HostWindow* mediaPlayerHostWindow() override;
+ virtual IntRect mediaPlayerWindowClipRect() override;
virtual CachedResourceLoader* mediaPlayerCachedResourceLoader() override;
- virtual RefPtr<PlatformMediaResourceLoader> mediaPlayerCreateResourceLoader(std::unique_ptr<PlatformMediaResourceLoaderClient>) override;
#if PLATFORM(WIN) && USE(AVFOUNDATION)
virtual GraphicsDeviceAdapter* mediaPlayerGraphicsDeviceAdapter(const MediaPlayer*) const override;
#endif
virtual bool mediaPlayerShouldWaitForResponseToAuthenticationChallenge(const AuthenticationChallenge&) override;
- virtual void mediaPlayerHandlePlaybackCommand(PlatformMediaSession::RemoteControlCommandType command) override { didReceiveRemoteControlCommand(command); }
- virtual String mediaPlayerSourceApplicationIdentifier() const override;
- virtual Vector<String> mediaPlayerPreferredAudioCharacteristics() const override;
-#if PLATFORM(IOS)
- virtual String mediaPlayerNetworkInterfaceName() const override;
- virtual bool mediaPlayerGetRawCookies(const URL&, Vector<Cookie>&) const override;
-#endif
-
- virtual bool mediaPlayerIsInMediaDocument() const override final;
- virtual void mediaPlayerEngineFailedToLoad() const override final;
-
- virtual double mediaPlayerRequestedPlaybackRate() const override final;
- virtual VideoFullscreenMode mediaPlayerFullscreenMode() const override final { return fullscreenMode(); }
-
-#if USE(GSTREAMER)
- virtual void requestInstallMissingPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback&) override final;
-#endif
-
- void pendingActionTimerFired();
- void progressEventTimerFired();
- void playbackProgressTimerFired();
- void scanTimerFired();
- void seekTask();
+ void loadTimerFired(Timer<HTMLMediaElement>&);
+ void progressEventTimerFired(Timer<HTMLMediaElement>&);
+ void playbackProgressTimerFired(Timer<HTMLMediaElement>&);
void startPlaybackProgressTimer();
void startProgressEventTimer();
void stopPeriodicTimers();
- void seek(const MediaTime&);
- void seekInternal(const MediaTime&);
- void seekWithTolerance(const MediaTime&, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance, bool fromDOM);
+ void seek(double time);
+ void seekWithTolerance(double time, double negativeTolerance, double positiveTolerance);
void finishSeek();
void checkIfSeekNeeded();
- void addPlayedRange(const MediaTime& start, const MediaTime& end);
+ void addPlayedRange(double start, double end);
void scheduleTimeupdateEvent(bool periodicEvent);
-
+ void scheduleEvent(const AtomicString& eventName);
+
// loading
void selectMediaResource();
void loadResource(const URL&, ContentType&, const String& keySystem);
@@ -656,7 +595,7 @@ private:
URL selectNextSourceChild(ContentType*, String* keySystem, InvalidURLAction);
#if ENABLE(VIDEO_TRACK)
- void updateActiveTextTrackCues(const MediaTime&);
+ void updateActiveTextTrackCues(double);
HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const;
enum ReconfigureMode {
@@ -681,15 +620,18 @@ private:
void updateVolume();
void updatePlayState();
- void setPlaying(bool);
bool potentiallyPlaying() const;
bool endedPlayback() const;
bool stoppedDueToErrors() const;
bool pausedForUserInteraction() const;
bool couldPlayIfEnoughData() const;
- MediaTime minTimeSeekable() const;
- MediaTime maxTimeSeekable() const;
+ double minTimeSeekable() const;
+ double maxTimeSeekable() const;
+
+#if PLATFORM(IOS)
+ bool parseMediaPlayerAttribute(const QualifiedName&, const AtomicString&);
+#endif
// Pauses playback without changing any states or generating events
void setPausedInternal(bool);
@@ -699,7 +641,7 @@ private:
virtual void mediaCanStart() override;
void setShouldDelayLoadEvent(bool);
- void invalidateCachedTime() const;
+ void invalidateCachedTime();
void refreshCachedTime() const;
bool hasMediaControls() const;
@@ -717,11 +659,13 @@ private:
bool isBlocked() const;
bool isBlockedOnMediaController() const;
virtual bool hasCurrentSrc() const override { return !m_currentSrc.isEmpty(); }
- virtual bool isLiveStream() const override { return movieLoadType() == MediaPlayerEnums::LiveStream; }
+ virtual bool isLiveStream() const override { return movieLoadType() == MediaPlayer::LiveStream; }
bool isAutoplaying() const { return m_autoplaying; }
void updateSleepDisabling();
+#if PLATFORM(MAC)
bool shouldDisableSleep() const;
+#endif
#if ENABLE(MEDIA_CONTROLS_SCRIPT)
virtual void didAddUserAgentShadowRoot(ShadowRoot*) override;
@@ -729,51 +673,19 @@ private:
bool ensureMediaControlsInjectedScript();
#endif
- // PlatformMediaSessionClient Overrides
- virtual PlatformMediaSession::MediaType mediaType() const override;
- virtual PlatformMediaSession::MediaType presentationType() const override;
- virtual PlatformMediaSession::DisplayType displayType() const override;
- virtual void suspendPlayback() override;
- virtual void mayResumePlayback(bool shouldResume) override;
- virtual String mediaSessionTitle() const override;
- virtual double mediaSessionDuration() const override { return duration(); }
- virtual double mediaSessionCurrentTime() const override { return currentTime(); }
- virtual bool canReceiveRemoteControlCommands() const override { return true; }
- virtual void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType) override;
- virtual bool overrideBackgroundPlaybackRestriction() const override;
-
- virtual void pageMutedStateDidChange() override;
-
- bool effectiveMuted() const;
+ virtual MediaSession::MediaType mediaType() const override;
- void registerWithDocument(Document&);
- void unregisterWithDocument(Document&);
+ virtual void beginInterruption() override;
+ virtual void endInterruption(MediaSession::EndInterruptionFlags) override;
+ virtual void pausePlayback() override;
- void updateCaptionContainer();
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- virtual void documentWillSuspendForPageCache() override final;
- virtual void documentDidResumeFromPageCache() override final;
-
- enum class UpdateMediaState {
- Asynchronously,
- Synchronously,
- };
- void updateMediaState(UpdateMediaState updateState = UpdateMediaState::Synchronously);
-#endif
-
- Timer m_pendingActionTimer;
- Timer m_progressEventTimer;
- Timer m_playbackProgressTimer;
- Timer m_scanTimer;
- GenericTaskQueue<ScriptExecutionContext> m_seekTaskQueue;
- GenericTaskQueue<ScriptExecutionContext> m_resizeTaskQueue;
- GenericTaskQueue<ScriptExecutionContext> m_shadowDOMTaskQueue;
+ Timer<HTMLMediaElement> m_loadTimer;
+ Timer<HTMLMediaElement> m_progressEventTimer;
+ Timer<HTMLMediaElement> m_playbackProgressTimer;
RefPtr<TimeRanges> m_playedTimeRanges;
GenericEventQueue m_asyncEventQueue;
- double m_requestedPlaybackRate;
- double m_reportedPlaybackRate;
+ double m_playbackRate;
double m_defaultPlaybackRate;
bool m_webkitPreservesPitch;
NetworkState m_networkState;
@@ -783,32 +695,18 @@ private:
RefPtr<MediaError> m_error;
- struct PendingSeek {
- PendingSeek(const MediaTime& now, const MediaTime& targetTime, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance)
- : now(now)
- , targetTime(targetTime)
- , negativeTolerance(negativeTolerance)
- , positiveTolerance(positiveTolerance)
- {
- }
- MediaTime now;
- MediaTime targetTime;
- MediaTime negativeTolerance;
- MediaTime positiveTolerance;
- };
- std::unique_ptr<PendingSeek> m_pendingSeek;
-
double m_volume;
bool m_volumeInitialized;
- MediaTime m_lastSeekTime;
+ double m_lastSeekTime;
+ unsigned m_previousProgress;
double m_previousProgressTime;
// The last time a timeupdate event was sent (based on monotonic clock).
double m_clockTimeAtLastUpdateEvent;
// The last time a timeupdate event was sent in movie time.
- MediaTime m_lastTimeUpdateEventMovieTime;
+ double m_lastTimeUpdateEventMovieTime;
// Loading state.
enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
@@ -816,16 +714,12 @@ private:
RefPtr<HTMLSourceElement> m_currentSourceNode;
RefPtr<Node> m_nextChildNodeToConsider;
- VideoFullscreenMode m_videoFullscreenMode;
-#if PLATFORM(IOS)
- RetainPtr<PlatformLayer> m_videoFullscreenLayer;
- FloatRect m_videoFullscreenFrame;
- MediaPlayerEnums::VideoGravity m_videoFullscreenGravity;
+ OwnPtr<MediaPlayer> m_player;
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ RefPtr<Widget> m_proxyWidget;
#endif
- std::unique_ptr<MediaPlayer> m_player;
-
- MediaPlayerEnums::Preload m_preload;
+ MediaPlayer::Preload m_preload;
DisplayMode m_displayMode;
@@ -833,38 +727,21 @@ private:
// calling the media engine recursively.
int m_processingMediaPlayerCallback;
-#if ENABLE(MEDIA_SESSION)
- String m_kind;
- RefPtr<MediaSession> m_session;
- bool m_shouldDuck { false };
- uint64_t m_elementID;
-#endif
-
#if ENABLE(MEDIA_SOURCE)
- RefPtr<MediaSource> m_mediaSource;
+ RefPtr<HTMLMediaSource> m_mediaSource;
unsigned long m_droppedVideoFrames;
#endif
- mutable MediaTime m_cachedTime;
+ mutable double m_cachedTime;
mutable double m_clockTimeAtLastCachedTimeUpdate;
mutable double m_minimumClockTimeToUpdateCachedTime;
- MediaTime m_fragmentStartTime;
- MediaTime m_fragmentEndTime;
+ double m_fragmentStartTime;
+ double m_fragmentEndTime;
typedef unsigned PendingActionFlags;
PendingActionFlags m_pendingActionFlags;
- enum ActionAfterScanType {
- Nothing, Play, Pause
- };
- ActionAfterScanType m_actionAfterScan;
-
- enum ScanType { Seek, Scan };
- ScanType m_scanType;
- ScanDirection m_scanDirection;
-
- bool m_firstTimePlaying : 1;
bool m_playing : 1;
bool m_isWaitingUntilMediaCanStart : 1;
bool m_shouldDelayLoadEvent : 1;
@@ -873,7 +750,6 @@ private:
bool m_autoplaying : 1;
bool m_muted : 1;
bool m_explicitlyMuted : 1;
- bool m_initiallyMuted : 1;
bool m_paused : 1;
bool m_seeking : 1;
@@ -889,24 +765,35 @@ private:
// support progress events so setting m_sendProgressEvents disables them
bool m_sendProgressEvents : 1;
+ bool m_isFullscreen : 1;
bool m_closedCaptionsVisible : 1;
bool m_webkitLegacyClosedCaptionOverride : 1;
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ bool m_needWidgetUpdate : 1;
+#endif
+
bool m_completelyLoaded : 1;
bool m_havePreparedToPlay : 1;
bool m_parsingInProgress : 1;
- bool m_elementIsHidden : 1;
+#if ENABLE(PAGE_VISIBILITY_API)
+ bool m_isDisplaySleepDisablingSuspended : 1;
+#endif
-#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- bool m_mediaControlsDependOnPageScaleFactor : 1;
+#if PLATFORM(IOS)
+ bool m_requestingPlay : 1;
+ bool m_platformLayerBorrowed : 1;
#endif
+ bool m_resumePlaybackAfterInterruption : 1;
+
#if ENABLE(VIDEO_TRACK)
bool m_tracksAreReady : 1;
bool m_haveVisibleTextTrack : 1;
bool m_processingPreferenceChange : 1;
String m_subtitleTrackLanguage;
- MediaTime m_lastTextTrackUpdateTime;
+ float m_lastTextTrackUpdateTime;
CaptionUserPreferences::CaptionDisplayMode m_captionDisplayMode;
@@ -919,8 +806,6 @@ private:
CueList m_currentlyActiveCues;
int m_ignoreTrackDisplayUpdate;
-
- bool m_requireCaptionPreferencesChangedCallbacks { false };
#endif
#if ENABLE(WEB_AUDIO)
@@ -934,7 +819,9 @@ private:
friend class MediaController;
RefPtr<MediaController> m_mediaController;
- std::unique_ptr<DisplaySleepDisabler> m_sleepDisabler;
+#if PLATFORM(MAC)
+ OwnPtr<DisplaySleepDisabler> m_sleepDisabler;
+#endif
friend class TrackDisplayUpdateScope;
@@ -946,12 +833,11 @@ private:
RefPtr<PlatformTextTrackMenuInterface> m_platformMenu;
#endif
- std::unique_ptr<MediaElementSession> m_mediaSession;
- PageActivityAssertionToken m_activityToken;
+ std::unique_ptr<HTMLMediaSession> m_mediaSession;
+ std::unique_ptr<PageActivityAssertionToken> m_activityToken;
size_t m_reportedExtraMemoryCost;
#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- friend class MediaControlsHost;
RefPtr<MediaControlsHost> m_mediaControlsHost;
RefPtr<DOMWrapperWorld> m_isolatedWorld;
#endif
@@ -959,12 +845,6 @@ private:
#if ENABLE(MEDIA_STREAM)
RefPtr<MediaStream> m_mediaStreamSrcObject;
#endif
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
- bool m_hasPlaybackTargetAvailabilityListeners { false };
- bool m_failedToPlayToWirelessTarget { false };
-#endif
};
#if ENABLE(VIDEO_TRACK)
@@ -974,31 +854,20 @@ template <>
struct ValueToString<TextTrackCue*> {
static String string(TextTrackCue* const& cue)
{
- String text;
- if (cue->isRenderable())
- text = toVTTCue(cue)->text();
- return String::format("%p id=%s interval=%s-->%s cue=%s)", cue, cue->id().utf8().data(), toString(cue->startTime()).utf8().data(), toString(cue->endTime()).utf8().data(), text.utf8().data());
+ return String::format("%p id=%s interval=%f-->%f cue=%s)", cue, cue->id().utf8().data(), cue->startTime(), cue->endTime(), cue->text().utf8().data());
}
};
#endif
#endif
-#ifndef NDEBUG
-template<>
-struct ValueToString<MediaTime> {
- static String string(const MediaTime& time)
- {
- return toString(time);
- }
-};
-#endif
+void isHTMLMediaElement(const HTMLMediaElement&); // Catch unnecessary runtime check of type known at compile time.
+inline bool isHTMLMediaElement(const Element& element) { return element.isMediaElement(); }
+inline bool isHTMLMediaElement(const Node& node) { return node.isElementNode() && toElement(node).isMediaElement(); }
+template <> inline bool isElementOfType<const HTMLMediaElement>(const Element& element) { return element.isMediaElement(); }
-} // namespace WebCore
+NODE_TYPE_CASTS(HTMLMediaElement)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLMediaElement)
- static bool isType(const WebCore::Element& element) { return element.isMediaElement(); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+} //namespace
#endif
#endif
diff --git a/Source/WebCore/html/HTMLMediaElement.idl b/Source/WebCore/html/HTMLMediaElement.idl
index 26cfc8b0e..b233dde81 100644
--- a/Source/WebCore/html/HTMLMediaElement.idl
+++ b/Source/WebCore/html/HTMLMediaElement.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -63,12 +63,11 @@
readonly attribute boolean seeking;
// playback state
- [SetterRaisesException] attribute unrestricted double currentTime;
- readonly attribute unrestricted double duration;
- [TreatReturnedNaNDateAs=NaN] Date getStartDate();
+ attribute double currentTime;
+ readonly attribute double duration;
readonly attribute boolean paused;
- attribute unrestricted double defaultPlaybackRate;
- attribute unrestricted double playbackRate;
+ attribute double defaultPlaybackRate;
+ attribute double playbackRate;
readonly attribute TimeRanges played;
readonly attribute TimeRanges seekable;
readonly attribute boolean ended;
@@ -76,11 +75,11 @@
[Reflect] attribute boolean loop;
void play();
void pause();
- void fastSeek(unrestricted double time);
+ void fastSeek(double time);
// controls
attribute boolean controls;
- [SetterRaisesException] attribute unrestricted double volume;
+ [SetterRaisesException] attribute double volume;
attribute boolean muted;
[Reflect=muted] attribute boolean defaultMuted;
@@ -94,18 +93,26 @@
[Conditional=MEDIA_STATISTICS] readonly attribute unsigned long webkitAudioDecodedByteCount;
[Conditional=MEDIA_STATISTICS] readonly attribute unsigned long webkitVideoDecodedByteCount;
-#if !defined(LANGUAGE_GOBJECT) || !LANGUAGE_GOBJECT // Work around shortcomings in the gobject binding generator handling of conditional features by turning these off for gobject.
- [Conditional=ENCRYPTED_MEDIA, RaisesException] void webkitGenerateKeyRequest([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, optional Uint8Array initData);
- [Conditional=ENCRYPTED_MEDIA, RaisesException] void webkitAddKey([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, Uint8Array key, optional Uint8Array initData, [Default=NullString] optional DOMString sessionId);
- [Conditional=ENCRYPTED_MEDIA, RaisesException] void webkitCancelKeyRequest([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, [Default=NullString] optional DOMString sessionId);
+#if defined(ENABLE_ENCRYPTED_MEDIA) && ENABLE_ENCRYPTED_MEDIA
+ [RaisesException] void webkitGenerateKeyRequest([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, optional Uint8Array initData);
+ [RaisesException] void webkitAddKey([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, Uint8Array key, optional Uint8Array initData, [Default=NullString] optional DOMString sessionId);
+ [RaisesException] void webkitCancelKeyRequest([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, [Default=NullString] optional DOMString sessionId);
- [Conditional=ENCRYPTED_MEDIA_V2, ImplementedAs=keys] readonly attribute MediaKeys webkitKeys;
- [Conditional=ENCRYPTED_MEDIA_V2, ImplementedAs=setMediaKeys] void webkitSetMediaKeys(MediaKeys mediaKeys);
+ attribute EventListener onwebkitkeyadded;
+ attribute EventListener onwebkitkeyerror;
+ attribute EventListener onwebkitkeymessage;
+#endif
+ [Conditional=ENCRYPTED_MEDIA|ENCRYPTED_MEDIA_V2] attribute EventListener onwebkitneedkey;
+#if defined(ENABLE_ENCRYPTED_MEDIA_V2) && ENABLE_ENCRYPTED_MEDIA_V2
+ [ImplementedAs=keys] readonly attribute MediaKeys webkitKeys;
+ [ImplementedAs=setMediaKeys] void webkitSetMediaKeys(MediaKeys mediaKeys);
+#endif
- [Conditional=VIDEO_TRACK, RaisesException] TextTrack addTextTrack(DOMString kind, optional DOMString label, optional DOMString language);
- [Conditional=VIDEO_TRACK] readonly attribute AudioTrackList audioTracks;
- [Conditional=VIDEO_TRACK] readonly attribute TextTrackList textTracks;
- [Conditional=VIDEO_TRACK] readonly attribute VideoTrackList videoTracks;
+#if defined(ENABLE_VIDEO_TRACK) && ENABLE_VIDEO_TRACK
+ [RaisesException] TextTrack addTextTrack(DOMString kind, optional DOMString label, optional DOMString language);
+ readonly attribute AudioTrackList audioTracks;
+ readonly attribute TextTrackList textTracks;
+ readonly attribute VideoTrackList videoTracks;
#endif
[Reflect, TreatNullAs=NullString] attribute DOMString mediaGroup;
@@ -115,6 +122,8 @@
[Conditional=MEDIA_SOURCE] VideoPlaybackQuality getVideoPlaybackQuality();
#endif
- [Conditional=WIRELESS_PLAYBACK_TARGET] void webkitShowPlaybackTargetPicker();
- [Conditional=WIRELESS_PLAYBACK_TARGET] readonly attribute boolean webkitCurrentPlaybackTargetIsWireless;
+ [Conditional=IOS_AIRPLAY] void webkitShowPlaybackTargetPicker();
+ [Conditional=IOS_AIRPLAY] readonly attribute boolean webkitCurrentPlaybackTargetIsWireless;
+ [Conditional=IOS_AIRPLAY] attribute EventListener onwebkitcurrentplaybacktargetiswirelesschanged;
+ [Conditional=IOS_AIRPLAY] attribute EventListener onwebkitplaybacktargetavailabilitychanged;
};
diff --git a/Source/WebCore/html/HTMLMediaElementEnums.h b/Source/WebCore/html/HTMLMediaElementEnums.h
deleted file mode 100644
index 519def80f..000000000
--- a/Source/WebCore/html/HTMLMediaElementEnums.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLMediaElementEnums_h
-#define HTMLMediaElementEnums_h
-
-#include "MediaPlayerEnums.h"
-
-namespace WebCore {
-
-class HTMLMediaElementEnums : public MediaPlayerEnums {
-public:
- using MediaPlayerEnums::VideoFullscreenMode;
-
- enum DelayedActionType {
- LoadMediaResource = 1 << 0,
- ConfigureTextTracks = 1 << 1,
- TextTrackChangesNotification = 1 << 2,
- ConfigureTextTrackDisplay = 1 << 3,
- CheckPlaybackTargetCompatablity = 1 << 4,
- CheckMediaState = 1 << 5,
-
- EveryDelayedAction = LoadMediaResource | ConfigureTextTracks | TextTrackChangesNotification | ConfigureTextTrackDisplay | CheckPlaybackTargetCompatablity | CheckMediaState,
- };
-
- enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
- enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE };
- enum TextTrackVisibilityCheckType { CheckTextTrackVisibility, AssumeTextTrackVisibilityChanged };
- enum InvalidURLAction { DoNothing, Complain };
-};
-
-}
-
-#endif
diff --git a/Source/WebCore/html/HTMLMediaSession.cpp b/Source/WebCore/html/HTMLMediaSession.cpp
new file mode 100644
index 000000000..2978d67ad
--- /dev/null
+++ b/Source/WebCore/html/HTMLMediaSession.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(VIDEO)
+
+#include "HTMLMediaSession.h"
+
+#include "HTMLMediaElement.h"
+#include "Logging.h"
+#include "MediaSessionManager.h"
+#include "Page.h"
+#include "ScriptController.h"
+
+#if PLATFORM(IOS)
+#include "AudioSession.h"
+#include "RuntimeApplicationChecksIOS.h"
+#endif
+
+namespace WebCore {
+
+static void initializeAudioSession()
+{
+#if PLATFORM(IOS)
+ static bool wasAudioSessionInitialized;
+ if (wasAudioSessionInitialized)
+ return;
+
+ wasAudioSessionInitialized = true;
+ if (!WebCore::applicationIsMobileSafari())
+ return;
+
+ AudioSession::sharedSession().setCategory(AudioSession::MediaPlayback);
+#endif
+}
+
+std::unique_ptr<HTMLMediaSession> HTMLMediaSession::create(MediaSessionClient& client)
+{
+ return std::make_unique<HTMLMediaSession>(client);
+}
+
+HTMLMediaSession::HTMLMediaSession(MediaSessionClient& client)
+ : MediaSession(client)
+ , m_restrictions(NoRestrictions)
+{
+ initializeAudioSession();
+}
+
+void HTMLMediaSession::addBehaviorRestriction(BehaviorRestrictions restriction)
+{
+ m_restrictions |= restriction;
+}
+
+void HTMLMediaSession::removeBehaviorRestriction(BehaviorRestrictions restriction)
+{
+ m_restrictions &= ~restriction;
+}
+
+bool HTMLMediaSession::playbackPermitted(const HTMLMediaElement&) const
+{
+ if (m_restrictions & RequireUserGestureForRateChange && !ScriptController::processingUserGesture()) {
+ LOG(Media, "HTMLMediaSession::playbackPermitted - returning FALSE");
+ return false;
+ }
+
+ return true;
+}
+
+bool HTMLMediaSession::dataLoadingPermitted(const HTMLMediaElement&) const
+{
+ if (m_restrictions & RequireUserGestureForLoad && !ScriptController::processingUserGesture()) {
+ LOG(Media, "HTMLMediaSession::dataLoadingPermitted - returning FALSE");
+ return false;
+ }
+
+ return true;
+}
+
+bool HTMLMediaSession::fullscreenPermitted(const HTMLMediaElement&) const
+{
+ if (m_restrictions & RequireUserGestureForFullscreen && !ScriptController::processingUserGesture()) {
+ LOG(Media, "HTMLMediaSession::fullscreenPermitted - returning FALSE");
+ return false;
+ }
+
+ return true;
+}
+
+bool HTMLMediaSession::pageAllowsDataLoading(const HTMLMediaElement& element) const
+{
+ Page* page = element.document().page();
+ if (m_restrictions & RequirePageConsentToLoadMedia && page && !page->canStartMedia()) {
+ LOG(Media, "HTMLMediaSession::pageAllowsDataLoading - returning FALSE");
+ return false;
+ }
+
+ return true;
+}
+
+bool HTMLMediaSession::pageAllowsPlaybackAfterResuming(const HTMLMediaElement& element) const
+{
+ Page* page = element.document().page();
+ if (m_restrictions & RequirePageConsentToResumeMedia && page && !page->canStartMedia()) {
+ LOG(Media, "HTMLMediaSession::pageAllowsPlaybackAfterResuming - returning FALSE");
+ return false;
+ }
+
+ return true;
+}
+
+#if ENABLE(IOS_AIRPLAY)
+bool HTMLMediaSession::showingPlaybackTargetPickerPermitted(const HTMLMediaElement&) const
+{
+ if (m_restrictions & RequireUserGestureToShowPlaybackTargetPicker && !ScriptController::processingUserGesture()) {
+ LOG(Media, "HTMLMediaSession::showingPlaybackTargetPickerPermitted - returning FALSE");
+ return false;
+ }
+
+ return true;
+}
+#endif
+
+MediaPlayer::Preload HTMLMediaSession::effectivePreloadForElement(const HTMLMediaElement& element) const
+{
+ MediaSessionManager::SessionRestrictions restrictions = MediaSessionManager::sharedManager().restrictions(mediaType());
+ MediaPlayer::Preload preload = element.preloadValue();
+
+ if ((restrictions & MediaSessionManager::MetadataPreloadingNotPermitted) == MediaSessionManager::MetadataPreloadingNotPermitted)
+ return MediaPlayer::None;
+
+ if ((restrictions & MediaSessionManager::AutoPreloadingNotPermitted) == MediaSessionManager::AutoPreloadingNotPermitted) {
+ if (preload > MediaPlayer::MetaData)
+ return MediaPlayer::MetaData;
+ }
+
+ return preload;
+}
+
+void HTMLMediaSession::clientWillBeginPlayback() const
+{
+ MediaSessionManager::sharedManager().sessionWillBeginPlayback(*this);
+}
+
+bool HTMLMediaSession::requiresFullscreenForVideoPlayback(const HTMLMediaElement& element) const
+{
+ if (!MediaSessionManager::sharedManager().sessionRestrictsInlineVideoPlayback(*this))
+ return false;
+
+ Settings* settings = element.document().settings();
+ if (!settings || !settings->mediaPlaybackAllowsInline())
+ return true;
+
+ if (element.fastHasAttribute(HTMLNames::webkit_playsinlineAttr))
+ return false;
+
+#if PLATFORM(IOS)
+ if (applicationIsDumpRenderTree())
+ return false;
+#endif
+
+ return true;
+}
+
+}
+
+#endif // ENABLE(VIDEO)
diff --git a/Source/WebCore/html/HTMLMediaSession.h b/Source/WebCore/html/HTMLMediaSession.h
new file mode 100644
index 000000000..55ea520c5
--- /dev/null
+++ b/Source/WebCore/html/HTMLMediaSession.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLMediaSession_h
+#define HTMLMediaSession_h
+
+#if ENABLE(VIDEO)
+
+#include "MediaPlayer.h"
+#include "MediaSession.h"
+
+namespace WebCore {
+
+class HTMLMediaElement;
+
+class HTMLMediaSession : public MediaSession {
+public:
+ static std::unique_ptr<HTMLMediaSession> create(MediaSessionClient&);
+
+ HTMLMediaSession(MediaSessionClient&);
+ virtual ~HTMLMediaSession() { }
+
+ void clientWillBeginPlayback() const;
+
+ bool playbackPermitted(const HTMLMediaElement&) const;
+ bool dataLoadingPermitted(const HTMLMediaElement&) const;
+ bool fullscreenPermitted(const HTMLMediaElement&) const;
+ bool pageAllowsDataLoading(const HTMLMediaElement&) const;
+ bool pageAllowsPlaybackAfterResuming(const HTMLMediaElement&) const;
+#if ENABLE(IOS_AIRPLAY)
+ bool showingPlaybackTargetPickerPermitted(const HTMLMediaElement&) const;
+#endif
+ bool requiresFullscreenForVideoPlayback(const HTMLMediaElement&) const;
+ MediaPlayer::Preload effectivePreloadForElement(const HTMLMediaElement&) const;
+
+ // Restrictions to modify default behaviors.
+ enum BehaviorRestrictionFlags {
+ NoRestrictions = 0,
+ RequireUserGestureForLoad = 1 << 0,
+ RequireUserGestureForRateChange = 1 << 1,
+ RequireUserGestureForFullscreen = 1 << 2,
+ RequirePageConsentToLoadMedia = 1 << 3,
+ RequirePageConsentToResumeMedia = 1 << 4,
+#if ENABLE(IOS_AIRPLAY)
+ RequireUserGestureToShowPlaybackTargetPicker = 1 << 5,
+#endif
+ };
+ typedef unsigned BehaviorRestrictions;
+
+ void addBehaviorRestriction(BehaviorRestrictions);
+ void removeBehaviorRestriction(BehaviorRestrictions);
+
+private:
+ BehaviorRestrictions m_restrictions;
+};
+
+}
+
+#endif // MediaSession_h
+
+#endif // ENABLE(VIDEO)
diff --git a/Source/WebCore/html/parser/ParsingUtilities.h b/Source/WebCore/html/HTMLMediaSource.cpp
index 882b800bf..15ba14143 100644
--- a/Source/WebCore/html/parser/ParsingUtilities.h
+++ b/Source/WebCore/html/HTMLMediaSource.cpp
@@ -28,56 +28,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ParsingUtilities_h
-#define ParsingUtilities_h
+#include "config.h"
+#include "HTMLMediaSource.h"
-template<typename CharType>
-bool skipExactly(const CharType*& position, const CharType* end, CharType delimiter)
-{
- if (position < end && *position == delimiter) {
- ++position;
- return true;
- }
- return false;
-}
+namespace WebCore {
-template<typename CharType, bool characterPredicate(CharType)>
-bool skipExactly(const CharType*& position, const CharType* end)
-{
- if (position < end && characterPredicate(*position)) {
- ++position;
- return true;
- }
- return false;
-}
+URLRegistry* HTMLMediaSource::s_registry = 0;
-template<typename CharType>
-void skipUntil(const CharType*& position, const CharType* end, CharType delimiter)
+void HTMLMediaSource::setRegistry(URLRegistry* registry)
{
- while (position < end && *position != delimiter)
- ++position;
+ ASSERT(!s_registry);
+ s_registry = registry;
}
-template<typename CharType, bool characterPredicate(CharType)>
-void skipUntil(const CharType*& position, const CharType* end)
-{
- while (position < end && !characterPredicate(*position))
- ++position;
}
-
-template<typename CharType, bool characterPredicate(CharType)>
-void skipWhile(const CharType*& position, const CharType* end)
-{
- while (position < end && characterPredicate(*position))
- ++position;
-}
-
-template<typename CharType, bool characterPredicate(CharType)>
-void reverseSkipWhile(const CharType*& position, const CharType* start)
-{
- while (position >= start && characterPredicate(*position))
- --position;
-}
-
-#endif
-
diff --git a/Source/WebCore/html/HTMLMediaSource.h b/Source/WebCore/html/HTMLMediaSource.h
new file mode 100644
index 000000000..88bcf59f7
--- /dev/null
+++ b/Source/WebCore/html/HTMLMediaSource.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLMediaSource_h
+#define HTMLMediaSource_h
+
+#include "URLRegistry.h"
+#include <wtf/Forward.h>
+#include <wtf/MediaTime.h>
+
+namespace WebCore {
+
+class HTMLMediaElement;
+class MediaSourcePrivate;
+class TimeRanges;
+
+class HTMLMediaSource : public URLRegistrable {
+public:
+ static void setRegistry(URLRegistry*);
+ static HTMLMediaSource* lookup(const String& url) { return s_registry ? static_cast<HTMLMediaSource*>(s_registry->lookup(url)) : 0; }
+
+ void ref() { refHTMLMediaSource(); }
+ void deref() { derefHTMLMediaSource(); }
+
+ // Called when an HTMLMediaElement is attempting to attach to this object,
+ // and helps enforce attachment to at most one element at a time.
+ // If already attached, returns false. Otherwise, must be in
+ // 'closed' state, and returns true to indicate attachment success.
+ // Reattachment allowed by first calling close() (even if already in 'closed').
+ virtual bool attachToElement(HTMLMediaElement*) = 0;
+ virtual void setPrivateAndOpen(PassRef<MediaSourcePrivate>) = 0;
+ virtual void close() = 0;
+ virtual bool isClosed() const = 0;
+ virtual double duration() const = 0;
+ virtual PassRefPtr<TimeRanges> buffered() const = 0;
+ virtual void refHTMLMediaSource() = 0;
+ virtual void derefHTMLMediaSource() = 0;
+ virtual void monitorSourceBuffers() = 0;
+
+ // URLRegistrable
+ virtual URLRegistry& registry() const override { return *s_registry; }
+
+private:
+ static URLRegistry* s_registry;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/HTMLMenuElement.cpp b/Source/WebCore/html/HTMLMenuElement.cpp
index 799d26444..74f0bb7ad 100644
--- a/Source/WebCore/html/HTMLMenuElement.cpp
+++ b/Source/WebCore/html/HTMLMenuElement.cpp
@@ -35,9 +35,9 @@ inline HTMLMenuElement::HTMLMenuElement(const QualifiedName& tagName, Document&
ASSERT(hasTagName(menuTag));
}
-Ref<HTMLMenuElement> HTMLMenuElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLMenuElement> HTMLMenuElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLMenuElement(tagName, document));
+ return adoptRef(new HTMLMenuElement(tagName, document));
}
}
diff --git a/Source/WebCore/html/HTMLMenuElement.h b/Source/WebCore/html/HTMLMenuElement.h
index ff9282999..2c7f08fea 100644
--- a/Source/WebCore/html/HTMLMenuElement.h
+++ b/Source/WebCore/html/HTMLMenuElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLMenuElement final : public HTMLElement {
public:
- static Ref<HTMLMenuElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLMenuElement> create(const QualifiedName&, Document&);
private:
HTMLMenuElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLMetaElement.cpp b/Source/WebCore/html/HTMLMetaElement.cpp
index 177081253..6f360fe2b 100644
--- a/Source/WebCore/html/HTMLMetaElement.cpp
+++ b/Source/WebCore/html/HTMLMetaElement.cpp
@@ -37,9 +37,9 @@ inline HTMLMetaElement::HTMLMetaElement(const QualifiedName& tagName, Document&
ASSERT(hasTagName(metaTag));
}
-Ref<HTMLMetaElement> HTMLMetaElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLMetaElement> HTMLMetaElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLMetaElement(tagName, document));
+ return adoptRef(new HTMLMetaElement(tagName, document));
}
void HTMLMetaElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -81,6 +81,12 @@ void HTMLMetaElement::process()
#endif
else if (equalIgnoringCase(name(), "referrer"))
document().processReferrerPolicy(contentValue);
+#if ENABLE(LEGACY_VIEWPORT_ADAPTION)
+ else if (equalIgnoringCase(name(), "handheldfriendly") && equalIgnoringCase(contentValue, "true"))
+ document().processViewport("width=device-width", ViewportArguments::HandheldFriendlyMeta);
+ else if (equalIgnoringCase(name(), "mobileoptimized"))
+ document().processViewport("width=device-width, initial-scale=1", ViewportArguments::MobileOptimizedMeta);
+#endif
// Get the document to process the tag, but only if we're actually part of DOM tree (changing a meta tag while
// it's not in the tree shouldn't have any effect on the document)
@@ -89,17 +95,17 @@ void HTMLMetaElement::process()
document().processHttpEquiv(httpEquivValue, contentValue);
}
-const AtomicString& HTMLMetaElement::content() const
+String HTMLMetaElement::content() const
{
- return fastGetAttribute(contentAttr);
+ return getAttribute(contentAttr);
}
-const AtomicString& HTMLMetaElement::httpEquiv() const
+String HTMLMetaElement::httpEquiv() const
{
- return fastGetAttribute(http_equivAttr);
+ return getAttribute(http_equivAttr);
}
-const AtomicString& HTMLMetaElement::name() const
+String HTMLMetaElement::name() const
{
return getNameAttribute();
}
diff --git a/Source/WebCore/html/HTMLMetaElement.h b/Source/WebCore/html/HTMLMetaElement.h
index 407a3ee7f..159c3aa73 100644
--- a/Source/WebCore/html/HTMLMetaElement.h
+++ b/Source/WebCore/html/HTMLMetaElement.h
@@ -29,11 +29,11 @@ namespace WebCore {
class HTMLMetaElement final : public HTMLElement {
public:
- static Ref<HTMLMetaElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLMetaElement> create(const QualifiedName&, Document&);
- const AtomicString& content() const;
- const AtomicString& httpEquiv() const;
- const AtomicString& name() const;
+ String content() const;
+ String httpEquiv() const;
+ String name() const;
private:
HTMLMetaElement(const QualifiedName&, Document&);
@@ -44,6 +44,8 @@ private:
void process();
};
+NODE_TYPE_CASTS(HTMLMetaElement)
+
} // namespace WebCore
#endif
diff --git a/Source/WebCore/html/HTMLMeterElement.cpp b/Source/WebCore/html/HTMLMeterElement.cpp
index 22b2f3981..f7a470a14 100644
--- a/Source/WebCore/html/HTMLMeterElement.cpp
+++ b/Source/WebCore/html/HTMLMeterElement.cpp
@@ -50,19 +50,19 @@ HTMLMeterElement::~HTMLMeterElement()
{
}
-Ref<HTMLMeterElement> HTMLMeterElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLMeterElement> HTMLMeterElement::create(const QualifiedName& tagName, Document& document)
{
- Ref<HTMLMeterElement> meter = adoptRef(*new HTMLMeterElement(tagName, document));
+ RefPtr<HTMLMeterElement> meter = adoptRef(new HTMLMeterElement(tagName, document));
meter->ensureUserAgentShadowRoot();
return meter;
}
-RenderPtr<RenderElement> HTMLMeterElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLMeterElement::createElementRenderer(PassRef<RenderStyle> style)
{
- if (!document().page()->theme().supportsMeter(style.get().appearance()))
- return RenderElement::createFor(*this, WTF::move(style));
+ if (hasAuthorShadowRoot() || !document().page()->theme().supportsMeter(style.get().appearance()))
+ return RenderElement::createFor(*this, std::move(style));
- return createRenderer<RenderMeter>(*this, WTF::move(style));
+ return createRenderer<RenderMeter>(*this, std::move(style));
}
bool HTMLMeterElement::childShouldCreateRenderer(const Node& child) const
@@ -220,9 +220,9 @@ void HTMLMeterElement::didElementStateChange()
RenderMeter* HTMLMeterElement::renderMeter() const
{
- if (is<RenderMeter>(renderer()))
- return downcast<RenderMeter>(renderer());
- return downcast<RenderMeter>(descendantsOfType<Element>(*userAgentShadowRoot()).first()->renderer());
+ if (renderer() && renderer()->isMeter())
+ return toRenderMeter(renderer());
+ return toRenderMeter(descendantsOfType<Element>(*userAgentShadowRoot()).first()->renderer());
}
void HTMLMeterElement::didAddUserAgentShadowRoot(ShadowRoot* root)
diff --git a/Source/WebCore/html/HTMLMeterElement.h b/Source/WebCore/html/HTMLMeterElement.h
index d2364b17c..e16ff3dd0 100644
--- a/Source/WebCore/html/HTMLMeterElement.h
+++ b/Source/WebCore/html/HTMLMeterElement.h
@@ -31,7 +31,7 @@ class RenderMeter;
class HTMLMeterElement final : public LabelableElement {
public:
- static Ref<HTMLMeterElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLMeterElement> create(const QualifiedName&, Document&);
enum GaugeRegion {
GaugeRegionOptimum,
@@ -66,11 +66,13 @@ private:
HTMLMeterElement(const QualifiedName&, Document&);
virtual ~HTMLMeterElement();
+ virtual bool areAuthorShadowsAllowed() const override { return false; }
RenderMeter* renderMeter() const;
virtual bool supportLabels() const override { return true; }
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual bool recalcWillValidate() const { return false; }
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual bool childShouldCreateRenderer(const Node&) const override;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
@@ -80,6 +82,8 @@ private:
RefPtr<MeterValueElement> m_value;
};
+NODE_TYPE_CASTS(HTMLMeterElement)
+
} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLMeterElement.idl b/Source/WebCore/html/HTMLMeterElement.idl
index 6287e19a9..15575dd87 100644
--- a/Source/WebCore/html/HTMLMeterElement.idl
+++ b/Source/WebCore/html/HTMLMeterElement.idl
@@ -20,11 +20,11 @@
[
Conditional=METER_ELEMENT
] interface HTMLMeterElement : HTMLElement {
- [SetterRaisesException] attribute unrestricted double value;
- [SetterRaisesException] attribute unrestricted double min;
- [SetterRaisesException] attribute unrestricted double max;
- [SetterRaisesException] attribute unrestricted double low;
- [SetterRaisesException] attribute unrestricted double high;
- [SetterRaisesException] attribute unrestricted double optimum;
+ [SetterRaisesException] attribute double value;
+ [SetterRaisesException] attribute double min;
+ [SetterRaisesException] attribute double max;
+ [SetterRaisesException] attribute double low;
+ [SetterRaisesException] attribute double high;
+ [SetterRaisesException] attribute double optimum;
readonly attribute NodeList labels;
};
diff --git a/Source/WebCore/html/HTMLModElement.cpp b/Source/WebCore/html/HTMLModElement.cpp
index f62690afa..2a7e472ca 100644
--- a/Source/WebCore/html/HTMLModElement.cpp
+++ b/Source/WebCore/html/HTMLModElement.cpp
@@ -34,9 +34,9 @@ inline HTMLModElement::HTMLModElement(const QualifiedName& tagName, Document& do
{
}
-Ref<HTMLModElement> HTMLModElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLModElement> HTMLModElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLModElement(tagName, document));
+ return adoptRef(new HTMLModElement(tagName, document));
}
bool HTMLModElement::isURLAttribute(const Attribute& attribute) const
diff --git a/Source/WebCore/html/HTMLModElement.h b/Source/WebCore/html/HTMLModElement.h
index 6cd2788e9..1fb865be7 100644
--- a/Source/WebCore/html/HTMLModElement.h
+++ b/Source/WebCore/html/HTMLModElement.h
@@ -30,7 +30,7 @@ namespace WebCore {
class HTMLModElement final : public HTMLElement {
public:
- static Ref<HTMLModElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLModElement> create(const QualifiedName&, Document&);
private:
HTMLModElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLNameCollection.cpp b/Source/WebCore/html/HTMLNameCollection.cpp
index 37f58c14e..50eda4826 100644
--- a/Source/WebCore/html/HTMLNameCollection.cpp
+++ b/Source/WebCore/html/HTMLNameCollection.cpp
@@ -49,46 +49,46 @@ HTMLNameCollection::~HTMLNameCollection()
document().nodeLists()->removeCachedCollection(this, m_name);
}
-bool WindowNameCollection::elementMatchesIfNameAttributeMatch(const Element& element)
+bool WindowNameCollection::nodeMatchesIfNameAttributeMatch(Element* element)
{
- return is<HTMLImageElement>(element) || is<HTMLFormElement>(element) || is<HTMLAppletElement>(element)
- || is<HTMLEmbedElement>(element) || is<HTMLObjectElement>(element);
+ return isHTMLImageElement(element) || isHTMLFormElement(element) || element->hasTagName(appletTag)
+ || element->hasTagName(embedTag) || element->hasTagName(objectTag);
}
-bool WindowNameCollection::elementMatches(const Element& element, const AtomicStringImpl* name)
+bool WindowNameCollection::nodeMatches(Element* element, const AtomicStringImpl* name)
{
// Find only images, forms, applets, embeds and objects by name, but anything by id
- if (elementMatchesIfNameAttributeMatch(element) && element.getNameAttribute().impl() == name)
+ if (nodeMatchesIfNameAttributeMatch(element) && element->getNameAttribute().impl() == name)
return true;
- return element.getIdAttribute().impl() == name;
+ return element->getIdAttribute().impl() == name;
}
-bool DocumentNameCollection::elementMatchesIfIdAttributeMatch(const Element& element)
+bool DocumentNameCollection::nodeMatchesIfIdAttributeMatch(Element* element)
{
// FIXME: we need to fix HTMLImageElement to update the hash map for us when name attribute has been removed.
- return is<HTMLAppletElement>(element) || (is<HTMLObjectElement>(element) && downcast<HTMLObjectElement>(element).isDocNamedItem())
- || (is<HTMLImageElement>(element) && element.hasName());
+ return element->hasTagName(appletTag) || (element->hasTagName(objectTag) && toHTMLObjectElement(element)->isDocNamedItem())
+ || (isHTMLImageElement(element) && element->hasName());
}
-bool DocumentNameCollection::elementMatchesIfNameAttributeMatch(const Element& element)
+bool DocumentNameCollection::nodeMatchesIfNameAttributeMatch(Element* element)
{
- return is<HTMLFormElement>(element) || is<HTMLEmbedElement>(element) || is<HTMLIFrameElement>(element)
- || is<HTMLAppletElement>(element) || (is<HTMLObjectElement>(element) && downcast<HTMLObjectElement>(element).isDocNamedItem())
- || is<HTMLImageElement>(element);
+ return isHTMLFormElement(element) || element->hasTagName(embedTag) || element->hasTagName(iframeTag)
+ || element->hasTagName(appletTag) || (element->hasTagName(objectTag) && toHTMLObjectElement(element)->isDocNamedItem())
+ || isHTMLImageElement(element);
}
-bool DocumentNameCollection::elementMatches(const Element& element, const AtomicStringImpl* name)
+bool DocumentNameCollection::nodeMatches(Element* element, const AtomicStringImpl* name)
{
// Find images, forms, applets, embeds, objects and iframes by name, applets and object by id, and images by id
// but only if they have a name attribute (this very strange rule matches IE)
- if (is<HTMLFormElement>(element) || is<HTMLEmbedElement>(element) || is<HTMLIFrameElement>(element))
- return element.getNameAttribute().impl() == name;
- if (is<HTMLAppletElement>(element))
- return element.getNameAttribute().impl() == name || element.getIdAttribute().impl() == name;
- if (is<HTMLObjectElement>(element))
- return (element.getNameAttribute().impl() == name || element.getIdAttribute().impl() == name) && downcast<HTMLObjectElement>(element).isDocNamedItem();
- if (is<HTMLImageElement>(element))
- return element.getNameAttribute().impl() == name || (element.getIdAttribute().impl() == name && element.hasName());
+ if (isHTMLFormElement(element) || element->hasTagName(embedTag) || element->hasTagName(iframeTag))
+ return element->getNameAttribute().impl() == name;
+ if (element->hasTagName(appletTag))
+ return element->getNameAttribute().impl() == name || element->getIdAttribute().impl() == name;
+ if (element->hasTagName(objectTag))
+ return (element->getNameAttribute().impl() == name || element->getIdAttribute().impl() == name) && toHTMLObjectElement(element)->isDocNamedItem();
+ if (isHTMLImageElement(element))
+ return element->getNameAttribute().impl() == name || (element->getIdAttribute().impl() == name && element->hasName());
return false;
}
diff --git a/Source/WebCore/html/HTMLNameCollection.h b/Source/WebCore/html/HTMLNameCollection.h
index 320743d5a..94a808d27 100644
--- a/Source/WebCore/html/HTMLNameCollection.h
+++ b/Source/WebCore/html/HTMLNameCollection.h
@@ -24,6 +24,7 @@
#define HTMLNameCollection_h
#include "HTMLCollection.h"
+
#include <wtf/text/AtomicString.h>
namespace WebCore {
@@ -32,9 +33,9 @@ class Document;
class HTMLNameCollection : public HTMLCollection {
public:
- virtual ~HTMLNameCollection();
+ ~HTMLNameCollection();
- Document& document() { return downcast<Document>(ownerNode()); }
+ Document& document() { return toDocument(ownerNode()); }
protected:
HTMLNameCollection(Document&, CollectionType, const AtomicString& name);
@@ -44,16 +45,16 @@ protected:
class WindowNameCollection final : public HTMLNameCollection {
public:
- static Ref<WindowNameCollection> create(Document& document, CollectionType type, const AtomicString& name)
+ static PassRef<WindowNameCollection> create(Document& document, CollectionType type, const AtomicString& name)
{
return adoptRef(*new WindowNameCollection(document, type, name));
}
- bool elementMatches(const Element& element) const { return elementMatches(element, m_name.impl()); }
+ bool nodeMatches(Element* element) const { return nodeMatches(element, m_name.impl()); }
- static bool elementMatchesIfIdAttributeMatch(const Element&) { return true; }
- static bool elementMatchesIfNameAttributeMatch(const Element&);
- static bool elementMatches(const Element&, const AtomicStringImpl*);
+ static bool nodeMatchesIfIdAttributeMatch(Element*) { return true; }
+ static bool nodeMatchesIfNameAttributeMatch(Element*);
+ static bool nodeMatches(Element*, const AtomicStringImpl*);
private:
WindowNameCollection(Document& document, CollectionType type, const AtomicString& name)
@@ -65,16 +66,16 @@ private:
class DocumentNameCollection final : public HTMLNameCollection {
public:
- static Ref<DocumentNameCollection> create(Document& document, CollectionType type, const AtomicString& name)
+ static PassRef<DocumentNameCollection> create(Document& document, CollectionType type, const AtomicString& name)
{
return adoptRef(*new DocumentNameCollection(document, type, name));
}
- static bool elementMatchesIfIdAttributeMatch(const Element&);
- static bool elementMatchesIfNameAttributeMatch(const Element&);
- bool elementMatches(const Element& element) const { return elementMatches(element, m_name.impl()); }
+ static bool nodeMatchesIfIdAttributeMatch(Element*);
+ static bool nodeMatchesIfNameAttributeMatch(Element*);
+ bool nodeMatches(Element* element) const { return nodeMatches(element, m_name.impl()); }
- static bool elementMatches(const Element&, const AtomicStringImpl*);
+ static bool nodeMatches(Element*, const AtomicStringImpl*);
private:
DocumentNameCollection(Document& document, CollectionType type, const AtomicString& name)
@@ -84,9 +85,6 @@ private:
}
};
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_HTMLCOLLECTION(WindowNameCollection, WindowNamedItems)
-SPECIALIZE_TYPE_TRAITS_HTMLCOLLECTION(DocumentNameCollection, DocumentNamedItems)
+}
-#endif // HTMLNameCollection_h
+#endif
diff --git a/Source/WebCore/html/HTMLOListElement.cpp b/Source/WebCore/html/HTMLOListElement.cpp
index 17d404473..9b6a5084b 100644
--- a/Source/WebCore/html/HTMLOListElement.cpp
+++ b/Source/WebCore/html/HTMLOListElement.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLOListElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
@@ -43,14 +44,14 @@ HTMLOListElement::HTMLOListElement(const QualifiedName& tagName, Document& docum
ASSERT(hasTagName(olTag));
}
-Ref<HTMLOListElement> HTMLOListElement::create(Document& document)
+PassRefPtr<HTMLOListElement> HTMLOListElement::create(Document& document)
{
- return adoptRef(*new HTMLOListElement(olTag, document));
+ return adoptRef(new HTMLOListElement(olTag, document));
}
-Ref<HTMLOListElement> HTMLOListElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLOListElement> HTMLOListElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLOListElement(tagName, document));
+ return adoptRef(new HTMLOListElement(tagName, document));
}
bool HTMLOListElement::isPresentationAttribute(const QualifiedName& name) const
@@ -105,12 +106,12 @@ void HTMLOListElement::setStart(int start)
void HTMLOListElement::updateItemValues()
{
- RenderListItem::updateItemValuesForOrderedList(*this);
+ RenderListItem::updateItemValuesForOrderedList(this);
}
void HTMLOListElement::recalculateItemCount()
{
- m_itemCount = RenderListItem::itemCountForOrderedList(*this);
+ m_itemCount = RenderListItem::itemCountForOrderedList(this);
m_shouldRecalculateItemCount = false;
}
diff --git a/Source/WebCore/html/HTMLOListElement.h b/Source/WebCore/html/HTMLOListElement.h
index 6892a8e75..989d79592 100644
--- a/Source/WebCore/html/HTMLOListElement.h
+++ b/Source/WebCore/html/HTMLOListElement.h
@@ -29,8 +29,8 @@ namespace WebCore {
class HTMLOListElement final : public HTMLElement {
public:
- static Ref<HTMLOListElement> create(Document&);
- static Ref<HTMLOListElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLOListElement> create(Document&);
+ static PassRefPtr<HTMLOListElement> create(const QualifiedName&, Document&);
int start() const { return m_hasExplicitStart ? m_start : (m_isReversed ? itemCount() : 1); }
void setStart(int);
@@ -65,6 +65,8 @@ private:
bool m_shouldRecalculateItemCount : 1;
};
+NODE_TYPE_CASTS(HTMLOListElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLObjectElement.cpp b/Source/WebCore/html/HTMLObjectElement.cpp
index f9d198650..222f99d43 100644
--- a/Source/WebCore/html/HTMLObjectElement.cpp
+++ b/Source/WebCore/html/HTMLObjectElement.cpp
@@ -69,24 +69,24 @@ inline HTMLObjectElement::HTMLObjectElement(const QualifiedName& tagName, Docume
, m_useFallbackContent(false)
{
ASSERT(hasTagName(objectTag));
- setForm(form);
+ setForm(form ? form : HTMLFormElement::findClosestFormAncestor(*this));
}
inline HTMLObjectElement::~HTMLObjectElement()
{
}
-Ref<HTMLObjectElement> HTMLObjectElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form, bool createdByParser)
+PassRefPtr<HTMLObjectElement> HTMLObjectElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form, bool createdByParser)
{
- return adoptRef(*new HTMLObjectElement(tagName, document, form, createdByParser));
+ return adoptRef(new HTMLObjectElement(tagName, document, form, createdByParser));
}
-RenderWidget* HTMLObjectElement::renderWidgetLoadingPlugin() const
+RenderWidget* HTMLObjectElement::renderWidgetForJSBindings() const
{
// Needs to load the plugin immediatedly because this function is called
// when JavaScript code accesses the plugin.
// FIXME: <rdar://16893708> Check if dispatching events here is safe.
- document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
+ document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasksSynchronously);
return renderWidget(); // This will return 0 if the renderer is not a RenderWidget.
}
@@ -107,35 +107,34 @@ void HTMLObjectElement::collectStyleForPresentationAttribute(const QualifiedName
void HTMLObjectElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- bool invalidateRenderer = false;
-
if (name == formAttr)
formAttributeChanged();
else if (name == typeAttr) {
- m_serviceType = value.string().left(value.find(';')).lower();
- invalidateRenderer = !fastHasAttribute(classidAttr);
- setNeedsWidgetUpdate(true);
+ m_serviceType = value.lower();
+ size_t pos = m_serviceType.find(";");
+ if (pos != notFound)
+ m_serviceType = m_serviceType.left(pos);
+ if (renderer())
+ setNeedsWidgetUpdate(true);
} else if (name == dataAttr) {
m_url = stripLeadingAndTrailingHTMLSpaces(value);
document().updateStyleIfNeeded();
- if (isImageType() && renderer()) {
- if (!m_imageLoader)
- m_imageLoader = std::make_unique<HTMLImageLoader>(*this);
- m_imageLoader->updateFromElementIgnoringPreviousError();
+ if (renderer()) {
+ setNeedsWidgetUpdate(true);
+ if (isImageType()) {
+ if (!m_imageLoader)
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader->updateFromElementIgnoringPreviousError();
+ }
}
- invalidateRenderer = !fastHasAttribute(classidAttr);
- setNeedsWidgetUpdate(true);
} else if (name == classidAttr) {
- invalidateRenderer = true;
- setNeedsWidgetUpdate(true);
- } else
+ m_classId = value;
+ if (renderer())
+ setNeedsWidgetUpdate(true);
+ } else if (name == onbeforeloadAttr)
+ setAttributeEventListener(eventNames().beforeloadEvent, name, value);
+ else
HTMLPlugInImageElement::parseAttribute(name, value);
-
- if (!invalidateRenderer || !inDocument() || !renderer())
- return;
-
- clearUseFallbackContent();
- setNeedsStyleRecalc(ReconstructRenderTree);
}
static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramValues)
@@ -187,7 +186,7 @@ void HTMLObjectElement::parametersForPlugin(Vector<String>& paramNames, Vector<S
// FIXME: serviceType calculation does not belong in this function.
if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
serviceType = param.value();
- size_t pos = serviceType.find(';');
+ size_t pos = serviceType.find(";");
if (pos != notFound)
serviceType = serviceType.left(pos);
}
@@ -238,10 +237,10 @@ bool HTMLObjectElement::hasFallbackContent() const
{
for (Node* child = firstChild(); child; child = child->nextSibling()) {
// Ignore whitespace-only text, and <param> tags, any other content is fallback content.
- if (is<Text>(*child)) {
- if (!downcast<Text>(*child).containsOnlyWhitespace())
+ if (child->isTextNode()) {
+ if (!toText(child)->containsOnlyWhitespace())
return true;
- } else if (!is<HTMLParamElement>(*child))
+ } else if (!child->hasTagName(paramTag))
return true;
}
return false;
@@ -255,24 +254,26 @@ bool HTMLObjectElement::shouldAllowQuickTimeClassIdQuirk()
// 'generator' meta tag is present. Only apply this quirk if there is no
// fallback content, which ensures the quirk will disable itself if Wiki
// Server is updated to generate an alternate embed tag as fallback content.
-
if (!document().page()
|| !document().page()->settings().needsSiteSpecificQuirks()
|| hasFallbackContent()
- || !equalIgnoringCase(fastGetAttribute(classidAttr), "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"))
+ || !equalIgnoringCase(classId(), "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"))
return false;
- for (auto& metaElement : descendantsOfType<HTMLMetaElement>(document())) {
+ RefPtr<NodeList> metaElements = document().getElementsByTagName(HTMLNames::metaTag.localName());
+ unsigned length = metaElements->length();
+ for (unsigned i = 0; i < length; ++i) {
+ HTMLMetaElement& metaElement = toHTMLMetaElement(*metaElements->item(i));
if (equalIgnoringCase(metaElement.name(), "generator") && metaElement.content().startsWith("Mac OS X Server Web Services Server", false))
return true;
}
-
+
return false;
}
bool HTMLObjectElement::hasValidClassId()
{
- if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType()) && fastGetAttribute(classidAttr).startsWith("java:", false))
+ if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType()) && classId().startsWith("java:", false))
return true;
if (shouldAllowQuickTimeClassIdQuirk())
@@ -280,7 +281,7 @@ bool HTMLObjectElement::hasValidClassId()
// HTML5 says that fallback content should be rendered if a non-empty
// classid is specified for which the UA can't find a suitable plug-in.
- return fastGetAttribute(classidAttr).isEmpty();
+ return classId().isEmpty();
}
// FIXME: This should be unified with HTMLEmbedElement::updateWidget and
@@ -337,12 +338,7 @@ Node::InsertionNotificationRequest HTMLObjectElement::insertedInto(ContainerNode
{
HTMLPlugInImageElement::insertedInto(insertionPoint);
FormAssociatedElement::insertedInto(insertionPoint);
- return InsertionShouldCallFinishedInsertingSubtree;
-}
-
-void HTMLObjectElement::finishedInsertingSubtree()
-{
- resetFormOwner();
+ return InsertionDone;
}
void HTMLObjectElement::removedFrom(ContainerNode& insertionPoint)
@@ -368,7 +364,7 @@ bool HTMLObjectElement::isURLAttribute(const Attribute& attribute) const
const AtomicString& HTMLObjectElement::imageSourceURL() const
{
- return fastGetAttribute(dataAttr);
+ return getAttribute(dataAttr);
}
void HTMLObjectElement::renderFallbackContent()
@@ -382,31 +378,29 @@ void HTMLObjectElement::renderFallbackContent()
setNeedsStyleRecalc(ReconstructRenderTree);
// Before we give up and use fallback content, check to see if this is a MIME type issue.
- auto* loader = imageLoader();
- if (loader && loader->image() && loader->image()->status() != CachedResource::LoadError) {
- m_serviceType = loader->image()->response().mimeType();
+ if (m_imageLoader && m_imageLoader->image() && m_imageLoader->image()->status() != CachedResource::LoadError) {
+ m_serviceType = m_imageLoader->image()->response().mimeType();
if (!isImageType()) {
// If we don't think we have an image type anymore, then clear the image from the loader.
- loader->clearImage();
+ m_imageLoader->setImage(0);
return;
}
}
m_useFallbackContent = true;
- // This was added to keep Acid 2 non-flaky. A style recalc is required to make fallback resources load.
- // Without forcing, this may happen after all the other resources have been loaded and the document is already
- // considered complete. FIXME: Would be better to address this with incrementLoadEventDelayCount instead
- // or disentangle loading from style entirely.
+ // This is here mainly to keep acid2 non-flaky. A style recalc is required to make fallback resources to load. Without forcing
+ // this may happen after all the other resources have been loaded and the document is already considered complete.
+ // FIXME: Disentangle fallback content handling from style recalcs.
document().updateStyleIfNeeded();
}
// FIXME: This should be removed, all callers are almost certainly wrong.
static bool isRecognizedTagName(const QualifiedName& tagName)
{
- DEPRECATED_DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
+ DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
if (tagList.isEmpty()) {
- auto* tags = HTMLNames::getHTMLTags();
+ const QualifiedName* const * tags = HTMLNames::getHTMLTags();
for (size_t i = 0; i < HTMLNames::HTMLTagsCount; i++) {
if (*tags[i] == bgsoundTag
|| *tags[i] == commandTag
@@ -435,35 +429,35 @@ void HTMLObjectElement::updateDocNamedItem()
bool isNamedItem = true;
Node* child = firstChild();
while (child && isNamedItem) {
- if (is<Element>(*child)) {
- Element& element = downcast<Element>(*child);
+ if (child->isElementNode()) {
+ Element* element = toElement(child);
// FIXME: Use of isRecognizedTagName is almost certainly wrong here.
- if (isRecognizedTagName(element.tagQName()) && !element.hasTagName(paramTag))
+ if (isRecognizedTagName(element->tagQName()) && !element->hasTagName(paramTag))
isNamedItem = false;
- } else if (is<Text>(*child)) {
- if (!downcast<Text>(*child).containsOnlyWhitespace())
+ } else if (child->isTextNode()) {
+ if (!toText(child)->containsOnlyWhitespace())
isNamedItem = false;
} else
isNamedItem = false;
child = child->nextSibling();
}
- if (isNamedItem != wasNamedItem && inDocument() && is<HTMLDocument>(document())) {
- HTMLDocument& document = downcast<HTMLDocument>(this->document());
+ if (isNamedItem != wasNamedItem && inDocument() && document().isHTMLDocument()) {
+ HTMLDocument* document = toHTMLDocument(&this->document());
const AtomicString& id = getIdAttribute();
if (!id.isEmpty()) {
if (isNamedItem)
- document.addDocumentNamedItem(*id.impl(), *this);
+ document->addDocumentNamedItem(*id.impl(), *this);
else
- document.removeDocumentNamedItem(*id.impl(), *this);
+ document->removeDocumentNamedItem(*id.impl(), *this);
}
const AtomicString& name = getNameAttribute();
if (!name.isEmpty() && id != name) {
if (isNamedItem)
- document.addDocumentNamedItem(*name.impl(), *this);
+ document->addDocumentNamedItem(*name.impl(), *this);
else
- document.removeDocumentNamedItem(*name.impl(), *this);
+ document->removeDocumentNamedItem(*name.impl(), *this);
}
}
m_docNamedItem = isNamedItem;
@@ -478,7 +472,7 @@ bool HTMLObjectElement::containsJavaApplet() const
if (child.hasTagName(paramTag) && equalIgnoringCase(child.getNameAttribute(), "type")
&& MIMETypeRegistry::isJavaAppletMIMEType(child.getAttribute(valueAttr).string()))
return true;
- if (child.hasTagName(objectTag) && downcast<HTMLObjectElement>(child).containsJavaApplet())
+ if (child.hasTagName(objectTag) && toHTMLObjectElement(child).containsJavaApplet())
return true;
if (child.hasTagName(appletTag))
return true;
@@ -491,11 +485,11 @@ void HTMLObjectElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) cons
{
HTMLPlugInImageElement::addSubresourceAttributeURLs(urls);
- addSubresourceURL(urls, document().completeURL(fastGetAttribute(dataAttr)));
+ addSubresourceURL(urls, document().completeURL(getAttribute(dataAttr)));
// FIXME: Passing a string that starts with "#" to the completeURL function does
// not seem like it would work. The image element has similar but not identical code.
- const AtomicString& useMap = fastGetAttribute(usemapAttr);
+ const AtomicString& useMap = getAttribute(usemapAttr);
if (useMap.startsWith('#'))
addSubresourceURL(urls, document().completeURL(useMap));
}
@@ -512,10 +506,10 @@ bool HTMLObjectElement::appendFormData(FormDataList& encoding, bool)
return false;
Widget* widget = pluginWidget();
- if (!is<PluginViewBase>(widget))
+ if (!widget || !widget->isPluginViewBase())
return false;
String value;
- if (!downcast<PluginViewBase>(*widget).getFormValue(value))
+ if (!toPluginViewBase(widget)->getFormValue(value))
return false;
encoding.appendData(name(), value);
return true;
@@ -526,13 +520,4 @@ HTMLFormElement* HTMLObjectElement::virtualForm() const
return FormAssociatedElement::form();
}
-bool HTMLObjectElement::canContainRangeEndPoint() const
-{
- // Call through to HTMLElement because we need to skip HTMLPlugInElement
- // when calling through to the derived class since returns false unconditionally.
- // An object element with fallback content should basically be treated like
- // a generic HTML element.
- return m_useFallbackContent && HTMLElement::canContainRangeEndPoint();
-}
-
}
diff --git a/Source/WebCore/html/HTMLObjectElement.h b/Source/WebCore/html/HTMLObjectElement.h
index e6e7421e4..636f6d627 100644
--- a/Source/WebCore/html/HTMLObjectElement.h
+++ b/Source/WebCore/html/HTMLObjectElement.h
@@ -32,28 +32,38 @@ class HTMLFormElement;
class HTMLObjectElement final : public HTMLPlugInImageElement, public FormAssociatedElement {
public:
- static Ref<HTMLObjectElement> create(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
+ static PassRefPtr<HTMLObjectElement> create(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
virtual ~HTMLObjectElement();
bool isDocNamedItem() const { return m_docNamedItem; }
+
+ const String& classId() const { return m_classId; }
+
bool containsJavaApplet() const;
- bool hasFallbackContent() const;
virtual bool useFallbackContent() const override { return m_useFallbackContent; }
void renderFallbackContent();
- virtual bool willValidate() const override { return false; }
+ // Implementations of FormAssociatedElement
+ HTMLFormElement* form() const { return FormAssociatedElement::form(); }
+
+ virtual bool isFormControlElement() const override { return false; }
+
+ virtual bool isEnumeratable() const override { return true; }
+ virtual bool appendFormData(FormDataList&, bool) override;
- // Implementation of constraint validation API.
+ // Implementations of constraint validation API.
// Note that the object elements are always barred from constraint validation.
- static bool checkValidity() { return true; }
- virtual void setCustomValidity(const String&) override { }
virtual String validationMessage() const override { return String(); }
+ bool checkValidity() { return true; }
+ virtual void setCustomValidity(const String&) override { }
- using HTMLPlugInImageElement::ref;
- using HTMLPlugInImageElement::deref;
+ using Node::ref;
+ using Node::deref;
- using FormAssociatedElement::form;
+ virtual bool canContainRangeEndPoint() const override { return useFallbackContent(); }
+
+ bool hasFallbackContent() const;
private:
HTMLObjectElement(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
@@ -63,7 +73,6 @@ private:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
- void finishedInsertingSubtree() override final;
virtual void removedFrom(ContainerNode&) override;
virtual void didMoveToNewDocument(Document* oldDocument) override;
@@ -73,7 +82,7 @@ private:
virtual bool isURLAttribute(const Attribute&) const override;
virtual const AtomicString& imageSourceURL() const override;
- virtual RenderWidget* renderWidgetLoadingPlugin() const override;
+ virtual RenderWidget* renderWidgetForJSBindings() const override;
virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override;
@@ -86,27 +95,22 @@ private:
bool shouldAllowQuickTimeClassIdQuirk();
bool hasValidClassId();
- void clearUseFallbackContent() { m_useFallbackContent = false; }
virtual void refFormAssociatedElement() override { ref(); }
virtual void derefFormAssociatedElement() override { deref(); }
virtual HTMLFormElement* virtualForm() const override;
- virtual FormNamedItem* asFormNamedItem() override { return this; }
- virtual HTMLObjectElement& asHTMLElement() override { return *this; }
- virtual const HTMLObjectElement& asHTMLElement() const override { return *this; }
-
- virtual bool isFormControlElement() const override { return false; }
-
- virtual bool isEnumeratable() const override { return true; }
- virtual bool appendFormData(FormDataList&, bool) override;
-
- virtual bool canContainRangeEndPoint() const override;
+ virtual FormNamedItem* asFormNamedItem() override final { return this; }
+ virtual HTMLObjectElement& asHTMLElement() override final { return *this; }
+ virtual const HTMLObjectElement& asHTMLElement() const override final { return *this; }
+ String m_classId;
bool m_docNamedItem : 1;
bool m_useFallbackContent : 1;
};
+NODE_TYPE_CASTS(HTMLObjectElement)
+
}
#endif
diff --git a/Source/WebCore/html/HTMLObjectElement.idl b/Source/WebCore/html/HTMLObjectElement.idl
index 7d225ee05..40355c7b2 100644
--- a/Source/WebCore/html/HTMLObjectElement.idl
+++ b/Source/WebCore/html/HTMLObjectElement.idl
@@ -49,9 +49,11 @@
// Introduced in DOM Level 2:
[CheckSecurityForNode] readonly attribute Document contentDocument;
+#if defined(ENABLE_SVG) && ENABLE_SVG
#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
[CheckSecurityForNode, RaisesException] SVGDocument getSVGDocument();
#endif
+#endif
#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
// Objective-C extension:
diff --git a/Source/WebCore/html/HTMLOptGroupElement.cpp b/Source/WebCore/html/HTMLOptGroupElement.cpp
index e0bd8cfc0..2927adac5 100644
--- a/Source/WebCore/html/HTMLOptGroupElement.cpp
+++ b/Source/WebCore/html/HTMLOptGroupElement.cpp
@@ -41,11 +41,12 @@ inline HTMLOptGroupElement::HTMLOptGroupElement(const QualifiedName& tagName, Do
: HTMLElement(tagName, document)
{
ASSERT(hasTagName(optgroupTag));
+ setHasCustomStyleResolveCallbacks();
}
-Ref<HTMLOptGroupElement> HTMLOptGroupElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLOptGroupElement> HTMLOptGroupElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLOptGroupElement(tagName, document));
+ return adoptRef(new HTMLOptGroupElement(tagName, document));
}
bool HTMLOptGroupElement::isDisabledFormControl() const
@@ -55,16 +56,13 @@ bool HTMLOptGroupElement::isDisabledFormControl() const
bool HTMLOptGroupElement::isFocusable() const
{
- if (!supportsFocus())
- return false;
- // Optgroup elements do not have a renderer.
- auto* style = const_cast<HTMLOptGroupElement&>(*this).computedStyle();
- return style && style->display() != NONE;
+ // Optgroup elements do not have a renderer so we check the renderStyle instead.
+ return supportsFocus() && renderStyle() && renderStyle()->display() != NONE;
}
const AtomicString& HTMLOptGroupElement::formControlType() const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, optgroup, ("optgroup", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, optgroup, ("optgroup", AtomicString::ConstructFromLiteral));
return optgroup;
}
@@ -80,21 +78,53 @@ void HTMLOptGroupElement::parseAttribute(const QualifiedName& name, const Atomic
recalcSelectOptions();
if (name == disabledAttr)
- setNeedsStyleRecalc();
+ didAffectSelector(AffectedSelectorDisabled | AffectedSelectorEnabled);
}
void HTMLOptGroupElement::recalcSelectOptions()
{
ContainerNode* select = parentNode();
- while (select && !is<HTMLSelectElement>(*select))
+ while (select && !select->hasTagName(selectTag))
select = select->parentNode();
if (select)
- downcast<HTMLSelectElement>(*select).setRecalcListItems();
+ toHTMLSelectElement(select)->setRecalcListItems();
+}
+
+void HTMLOptGroupElement::didAttachRenderers()
+{
+ // If after attaching nothing called styleForRenderer() on this node we
+ // manually cache the value. This happens if our parent doesn't have a
+ // renderer like <optgroup> or if it doesn't allow children like <select>.
+ if (!m_style && parentNode()->renderStyle())
+ updateNonRenderStyle();
+}
+
+void HTMLOptGroupElement::willDetachRenderers()
+{
+ m_style.clear();
+}
+
+void HTMLOptGroupElement::updateNonRenderStyle()
+{
+ m_style = document().ensureStyleResolver().styleForElement(this);
+}
+
+RenderStyle* HTMLOptGroupElement::nonRendererStyle() const
+{
+ return m_style.get();
+}
+
+PassRefPtr<RenderStyle> HTMLOptGroupElement::customStyleForRenderer()
+{
+ // styleForRenderer is called whenever a new style should be associated
+ // with an Element so now is a good time to update our cached style.
+ updateNonRenderStyle();
+ return m_style;
}
String HTMLOptGroupElement::groupLabelText() const
{
- String itemText = document().displayStringModifiedByEncoding(fastGetAttribute(labelAttr));
+ String itemText = document().displayStringModifiedByEncoding(getAttribute(labelAttr));
// In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior.
itemText = itemText.stripWhiteSpace();
@@ -107,13 +137,13 @@ String HTMLOptGroupElement::groupLabelText() const
HTMLSelectElement* HTMLOptGroupElement::ownerSelectElement() const
{
ContainerNode* select = parentNode();
- while (select && !is<HTMLSelectElement>(*select))
+ while (select && !select->hasTagName(selectTag))
select = select->parentNode();
if (!select)
- return nullptr;
+ return 0;
- return downcast<HTMLSelectElement>(select);
+ return toHTMLSelectElement(select);
}
void HTMLOptGroupElement::accessKeyAction(bool)
diff --git a/Source/WebCore/html/HTMLOptGroupElement.h b/Source/WebCore/html/HTMLOptGroupElement.h
index ea8ce1862..1cb0493c5 100644
--- a/Source/WebCore/html/HTMLOptGroupElement.h
+++ b/Source/WebCore/html/HTMLOptGroupElement.h
@@ -32,28 +32,39 @@ class HTMLSelectElement;
class HTMLOptGroupElement final : public HTMLElement {
public:
- static Ref<HTMLOptGroupElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLOptGroupElement> create(const QualifiedName&, Document&);
virtual bool isDisabledFormControl() const override;
HTMLSelectElement* ownerSelectElement() const;
- WEBCORE_EXPORT String groupLabelText() const;
+ String groupLabelText() const;
private:
HTMLOptGroupElement(const QualifiedName&, Document&);
- const AtomicString& formControlType() const;
+ virtual const AtomicString& formControlType() const;
virtual bool isFocusable() const override;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
virtual bool rendererIsNeeded(const RenderStyle&) override { return false; }
+ virtual void didAttachRenderers() override;
+ virtual void willDetachRenderers() override;
virtual void childrenChanged(const ChildChange&) override;
virtual void accessKeyAction(bool sendMouseEvents) override;
+ // <optgroup> never has a renderer so we manually manage a cached style.
+ void updateNonRenderStyle();
+ virtual RenderStyle* nonRendererStyle() const override;
+ virtual PassRefPtr<RenderStyle> customStyleForRenderer() override;
+
void recalcSelectOptions();
+
+ RefPtr<RenderStyle> m_style;
};
+NODE_TYPE_CASTS(HTMLOptGroupElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLOptionElement.cpp b/Source/WebCore/html/HTMLOptionElement.cpp
index 2dfff2635..f5049b674 100644
--- a/Source/WebCore/html/HTMLOptionElement.cpp
+++ b/Source/WebCore/html/HTMLOptionElement.cpp
@@ -27,6 +27,7 @@
#include "config.h"
#include "HTMLOptionElement.h"
+#include "Attribute.h"
#include "Document.h"
#include "ExceptionCode.h"
#include "HTMLDataListElement.h"
@@ -56,17 +57,17 @@ HTMLOptionElement::HTMLOptionElement(const QualifiedName& tagName, Document& doc
setHasCustomStyleResolveCallbacks();
}
-Ref<HTMLOptionElement> HTMLOptionElement::create(Document& document)
+PassRefPtr<HTMLOptionElement> HTMLOptionElement::create(Document& document)
{
- return adoptRef(*new HTMLOptionElement(optionTag, document));
+ return adoptRef(new HTMLOptionElement(optionTag, document));
}
-Ref<HTMLOptionElement> HTMLOptionElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLOptionElement> HTMLOptionElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLOptionElement(tagName, document));
+ return adoptRef(new HTMLOptionElement(tagName, document));
}
-RefPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document& document, const String& data, const String& value,
+PassRefPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document& document, const String& data, const String& value,
bool defaultSelected, bool selected, ExceptionCode& ec)
{
RefPtr<HTMLOptionElement> element = adoptRef(new HTMLOptionElement(optionTag, document));
@@ -87,13 +88,24 @@ RefPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document& do
return element.release();
}
+void HTMLOptionElement::didAttachRenderers()
+{
+ // If after attaching nothing called styleForRenderer() on this node we
+ // manually cache the value. This happens if our parent doesn't have a
+ // renderer like <optgroup> or if it doesn't allow children like <select>.
+ if (!m_style && parentNode()->renderStyle())
+ updateNonRenderStyle();
+}
+
+void HTMLOptionElement::willDetachRenderers()
+{
+ m_style.clear();
+}
+
bool HTMLOptionElement::isFocusable() const
{
- if (!supportsFocus())
- return false;
- // Option elements do not have a renderer.
- auto* style = const_cast<HTMLOptionElement&>(*this).computedStyle();
- return style && style->display() != NONE;
+ // Option elements do not have a renderer so we check the renderStyle instead.
+ return supportsFocus() && renderStyle() && renderStyle()->display() != NONE;
}
String HTMLOptionElement::text() const
@@ -128,8 +140,8 @@ void HTMLOptionElement::setText(const String &text, ExceptionCode& ec)
// Handle the common special case where there's exactly 1 child node, and it's a text node.
Node* child = firstChild();
- if (is<Text>(child) && !child->nextSibling())
- downcast<Text>(*child).setData(text, ec);
+ if (child && child->isTextNode() && !child->nextSibling())
+ toText(child)->setData(text, ec);
else {
removeChildren();
appendChild(Text::create(document(), text), ec);
@@ -159,7 +171,7 @@ int HTMLOptionElement::index() const
const Vector<HTMLElement*>& items = selectElement->listItems();
size_t length = items.size();
for (size_t i = 0; i < length; ++i) {
- if (!is<HTMLOptionElement>(*items[i]))
+ if (!isHTMLOptionElement(items[i]))
continue;
if (items[i] == this)
return optionIndex;
@@ -181,9 +193,9 @@ void HTMLOptionElement::parseAttribute(const QualifiedName& name, const AtomicSt
bool oldDisabled = m_disabled;
m_disabled = !value.isNull();
if (oldDisabled != m_disabled) {
- setNeedsStyleRecalc();
+ didAffectSelector(AffectedSelectorDisabled | AffectedSelectorEnabled);
if (renderer() && renderer()->style().hasAppearance())
- renderer()->theme().stateChanged(*renderer(), ControlStates::EnabledState);
+ renderer()->theme().stateChanged(renderer(), EnabledState);
}
} else if (name == selectedAttr) {
// FIXME: This doesn't match what the HTML specification says.
@@ -234,7 +246,7 @@ void HTMLOptionElement::setSelectedState(bool selected)
return;
m_isSelected = selected;
- setNeedsStyleRecalc();
+ didAffectSelector(AffectedSelectorChecked);
if (HTMLSelectElement* select = ownerSelectElement())
select->invalidateSelectedItems();
@@ -256,23 +268,23 @@ void HTMLOptionElement::childrenChanged(const ChildChange& change)
HTMLDataListElement* HTMLOptionElement::ownerDataListElement() const
{
for (ContainerNode* parent = parentNode(); parent ; parent = parent->parentNode()) {
- if (is<HTMLDataListElement>(*parent))
- return downcast<HTMLDataListElement>(parent);
+ if (parent->hasTagName(datalistTag))
+ return toHTMLDataListElement(parent);
}
- return nullptr;
+ return 0;
}
#endif
HTMLSelectElement* HTMLOptionElement::ownerSelectElement() const
{
ContainerNode* select = parentNode();
- while (select && !is<HTMLSelectElement>(*select))
+ while (select && !select->hasTagName(selectTag))
select = select->parentNode();
if (!select)
- return nullptr;
+ return 0;
- return downcast<HTMLSelectElement>(select);
+ return toHTMLSelectElement(select);
}
String HTMLOptionElement::label() const
@@ -288,7 +300,25 @@ void HTMLOptionElement::setLabel(const String& label)
setAttribute(labelAttr, label);
}
-void HTMLOptionElement::willResetComputedStyle()
+void HTMLOptionElement::updateNonRenderStyle()
+{
+ m_style = document().ensureStyleResolver().styleForElement(this);
+}
+
+RenderStyle* HTMLOptionElement::nonRendererStyle() const
+{
+ return m_style.get();
+}
+
+PassRefPtr<RenderStyle> HTMLOptionElement::customStyleForRenderer()
+{
+ // styleForRenderer is called whenever a new style should be associated
+ // with an Element so now is a good time to update our cached style.
+ updateNonRenderStyle();
+ return m_style;
+}
+
+void HTMLOptionElement::didRecalcStyle(Style::Change)
{
// FIXME: This is nasty, we ask our owner select to repaint even if the new
// style is exactly the same.
@@ -301,7 +331,7 @@ void HTMLOptionElement::willResetComputedStyle()
String HTMLOptionElement::textIndentedToRespectGroupLabel() const
{
ContainerNode* parent = parentNode();
- if (is<HTMLOptGroupElement>(parent))
+ if (parent && isHTMLOptGroupElement(parent))
return " " + text();
return text();
}
@@ -311,10 +341,11 @@ bool HTMLOptionElement::isDisabledFormControl() const
if (ownElementDisabled())
return true;
- if (!is<HTMLOptGroupElement>(parentNode()))
+ if (!parentNode() || !parentNode()->isHTMLElement())
return false;
- return downcast<HTMLOptGroupElement>(*parentNode()).isDisabledFormControl();
+ HTMLElement& parentElement = toHTMLElement(*parentNode());
+ return isHTMLOptGroupElement(parentElement) && parentElement.isDisabledFormControl();
}
Node::InsertionNotificationRequest HTMLOptionElement::insertedInto(ContainerNode& insertionPoint)
@@ -337,13 +368,13 @@ String HTMLOptionElement::collectOptionInnerText() const
{
StringBuilder text;
for (Node* node = firstChild(); node; ) {
- if (is<Text>(*node))
+ if (node->isTextNode())
text.append(node->nodeValue());
// Text nodes inside script elements are not part of the option text.
- if (is<Element>(*node) && toScriptElementIfPossible(downcast<Element>(node)))
- node = NodeTraversal::nextSkippingChildren(*node, this);
+ if (node->isElementNode() && toScriptElementIfPossible(toElement(node)))
+ node = NodeTraversal::nextSkippingChildren(node, this);
else
- node = NodeTraversal::next(*node, this);
+ node = NodeTraversal::next(node, this);
}
return text.toString();
}
diff --git a/Source/WebCore/html/HTMLOptionElement.h b/Source/WebCore/html/HTMLOptionElement.h
index 1d9601eb4..d64a8bc47 100644
--- a/Source/WebCore/html/HTMLOptionElement.h
+++ b/Source/WebCore/html/HTMLOptionElement.h
@@ -34,12 +34,12 @@ class HTMLSelectElement;
class HTMLOptionElement final : public HTMLElement {
public:
- static Ref<HTMLOptionElement> create(Document&);
- static Ref<HTMLOptionElement> create(const QualifiedName&, Document&);
- static RefPtr<HTMLOptionElement> createForJSConstructor(Document&, const String& data, const String& value,
+ static PassRefPtr<HTMLOptionElement> create(Document&);
+ static PassRefPtr<HTMLOptionElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLOptionElement> createForJSConstructor(Document&, const String& data, const String& value,
bool defaultSelected, bool selected, ExceptionCode&);
- WEBCORE_EXPORT String text() const;
+ virtual String text() const;
void setText(const String&, ExceptionCode&);
int index() const;
@@ -47,7 +47,7 @@ public:
String value() const;
void setValue(const String&);
- WEBCORE_EXPORT bool selected();
+ bool selected();
void setSelected(bool);
#if ENABLE(DATALIST_ELEMENT)
@@ -71,6 +71,8 @@ private:
virtual bool isFocusable() const override;
virtual bool rendererIsNeeded(const RenderStyle&) override { return false; }
+ virtual void didAttachRenderers() override;
+ virtual void willDetachRenderers() override;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
@@ -79,14 +81,22 @@ private:
virtual void childrenChanged(const ChildChange&) override;
- virtual void willResetComputedStyle() override;
+ // <option> never has a renderer so we manually manage a cached style.
+ void updateNonRenderStyle();
+ virtual RenderStyle* nonRendererStyle() const override;
+ virtual PassRefPtr<RenderStyle> customStyleForRenderer() override;
+
+ virtual void didRecalcStyle(Style::Change) override;
String collectOptionInnerText() const;
bool m_disabled;
bool m_isSelected;
+ RefPtr<RenderStyle> m_style;
};
+NODE_TYPE_CASTS(HTMLOptionElement)
+
} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLOptionsCollection.cpp b/Source/WebCore/html/HTMLOptionsCollection.cpp
index 1508b415c..c8f12313d 100644
--- a/Source/WebCore/html/HTMLOptionsCollection.cpp
+++ b/Source/WebCore/html/HTMLOptionsCollection.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2011, 2012 Apple Inc.
+ * Copyright (C) 2006, 2011, 2012 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -31,19 +31,38 @@ HTMLOptionsCollection::HTMLOptionsCollection(HTMLSelectElement& select)
{
}
-Ref<HTMLOptionsCollection> HTMLOptionsCollection::create(HTMLSelectElement& select, CollectionType)
+PassRef<HTMLOptionsCollection> HTMLOptionsCollection::create(HTMLSelectElement& select, CollectionType)
{
return adoptRef(*new HTMLOptionsCollection(select));
}
-void HTMLOptionsCollection::add(HTMLElement* element, HTMLElement* beforeElement, ExceptionCode& ec)
+void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, ExceptionCode& ec)
{
- selectElement().add(element, beforeElement, ec);
+ add(element, length(), ec);
}
-void HTMLOptionsCollection::add(HTMLElement* element, int beforeIndex, ExceptionCode& ec)
+void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, int index, ExceptionCode& ec)
{
- add(element, downcast<HTMLElement>(item(beforeIndex)), ec);
+ HTMLOptionElement* newOption = element.get();
+
+ if (!newOption) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+
+ if (index < -1) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ ec = 0;
+
+ if (index == -1 || unsigned(index) >= length())
+ selectElement().add(newOption, 0, ec);
+ else
+ selectElement().add(newOption, toHTMLOptionElement(item(index)), ec);
+
+ ASSERT(!ec);
}
void HTMLOptionsCollection::remove(int index)
diff --git a/Source/WebCore/html/HTMLOptionsCollection.h b/Source/WebCore/html/HTMLOptionsCollection.h
index 6366865e5..1c5e6889b 100644
--- a/Source/WebCore/html/HTMLOptionsCollection.h
+++ b/Source/WebCore/html/HTMLOptionsCollection.h
@@ -35,13 +35,13 @@ typedef int ExceptionCode;
class HTMLOptionsCollection final : public HTMLCollection {
public:
- static Ref<HTMLOptionsCollection> create(HTMLSelectElement&, CollectionType);
+ static PassRef<HTMLOptionsCollection> create(HTMLSelectElement&, CollectionType);
- HTMLSelectElement& selectElement() { return downcast<HTMLSelectElement>(ownerNode()); }
- const HTMLSelectElement& selectElement() const { return downcast<HTMLSelectElement>(ownerNode()); }
+ HTMLSelectElement& selectElement() { return toHTMLSelectElement(ownerNode()); }
+ const HTMLSelectElement& selectElement() const { return toHTMLSelectElement(ownerNode()); }
- void add(HTMLElement*, HTMLElement* beforeElement, ExceptionCode&);
- void add(HTMLElement*, int beforeIndex, ExceptionCode&);
+ void add(PassRefPtr<HTMLOptionElement>, ExceptionCode&);
+ void add(PassRefPtr<HTMLOptionElement>, int index, ExceptionCode&);
void remove(int index);
void remove(HTMLOptionElement*);
@@ -54,8 +54,6 @@ private:
explicit HTMLOptionsCollection(HTMLSelectElement&);
};
-} // namespace WebCore
+} //namespace
-SPECIALIZE_TYPE_TRAITS_HTMLCOLLECTION(HTMLOptionsCollection, SelectOptions)
-
-#endif // HTMLOptionsCollection_h
+#endif
diff --git a/Source/WebCore/html/HTMLOptionsCollection.idl b/Source/WebCore/html/HTMLOptionsCollection.idl
index 1dba443eb..a33209b91 100644
--- a/Source/WebCore/html/HTMLOptionsCollection.idl
+++ b/Source/WebCore/html/HTMLOptionsCollection.idl
@@ -28,12 +28,8 @@
Node namedItem([Default=Undefined] optional DOMString name);
-#if (!defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C) && (!defined(LANGUAGE_GOBJECT) || !LANGUAGE_GOBJECT)
- [RaisesException] void add(HTMLElement element, [Default=Undefined] optional HTMLElement? before);
- [RaisesException] void add(HTMLElement element, [Default=Undefined] optional long index);
-#else
- [RaisesException] void add(HTMLOptionElement option, unsigned long index);
-#endif
+ [Custom, RaisesException] void add([Default=Undefined] optional HTMLOptionElement option,
+ optional unsigned long index);
[Custom] void remove([Default=Undefined] optional unsigned long index);
#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
diff --git a/Source/WebCore/html/HTMLOutputElement.cpp b/Source/WebCore/html/HTMLOutputElement.cpp
index 67b25e8c4..c8a80bb03 100644
--- a/Source/WebCore/html/HTMLOutputElement.cpp
+++ b/Source/WebCore/html/HTMLOutputElement.cpp
@@ -46,14 +46,14 @@ inline HTMLOutputElement::HTMLOutputElement(const QualifiedName& tagName, Docume
{
}
-Ref<HTMLOutputElement> HTMLOutputElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
+PassRefPtr<HTMLOutputElement> HTMLOutputElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
{
- return adoptRef(*new HTMLOutputElement(tagName, document, form));
+ return adoptRef(new HTMLOutputElement(tagName, document, form));
}
const AtomicString& HTMLOutputElement::formControlType() const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, output, ("output", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, output, ("output", AtomicString::ConstructFromLiteral));
return output;
}
@@ -70,6 +70,11 @@ void HTMLOutputElement::parseAttribute(const QualifiedName& name, const AtomicSt
HTMLFormControlElement::parseAttribute(name, value);
}
+DOMSettableTokenList* HTMLOutputElement::htmlFor() const
+{
+ return m_tokens.get();
+}
+
void HTMLOutputElement::setFor(const String& value)
{
m_tokens->setValue(value);
diff --git a/Source/WebCore/html/HTMLOutputElement.h b/Source/WebCore/html/HTMLOutputElement.h
index 0c0f15ed7..9c4166132 100644
--- a/Source/WebCore/html/HTMLOutputElement.h
+++ b/Source/WebCore/html/HTMLOutputElement.h
@@ -38,21 +38,22 @@ namespace WebCore {
class HTMLOutputElement final : public HTMLFormControlElement {
public:
- static Ref<HTMLOutputElement> create(const QualifiedName&, Document&, HTMLFormElement*);
+ static PassRefPtr<HTMLOutputElement> create(const QualifiedName&, Document&, HTMLFormElement*);
+
+ virtual bool willValidate() const override { return false; }
String value() const;
void setValue(const String&);
String defaultValue() const;
void setDefaultValue(const String&);
void setFor(const String&);
- DOMSettableTokenList& htmlFor() { return m_tokens.get(); }
+ DOMSettableTokenList* htmlFor() const;
virtual bool canContainRangeEndPoint() const override { return false; }
private:
HTMLOutputElement(const QualifiedName&, Document&, HTMLFormElement*);
- virtual bool computeWillValidate() const override { return false; }
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
virtual const AtomicString& formControlType() const override;
virtual bool isEnumeratable() const override { return true; }
@@ -66,7 +67,7 @@ private:
bool m_isDefaultValueMode;
bool m_isSetTextContentInProgress;
String m_defaultValue;
- Ref<DOMSettableTokenList> m_tokens;
+ RefPtr<DOMSettableTokenList> m_tokens;
};
} // namespace
diff --git a/Source/WebCore/html/HTMLParagraphElement.cpp b/Source/WebCore/html/HTMLParagraphElement.cpp
index 5e95cdc0e..a32a3c85a 100644
--- a/Source/WebCore/html/HTMLParagraphElement.cpp
+++ b/Source/WebCore/html/HTMLParagraphElement.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLParagraphElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "Document.h"
@@ -38,14 +39,14 @@ inline HTMLParagraphElement::HTMLParagraphElement(const QualifiedName& tagName,
ASSERT(hasTagName(pTag));
}
-Ref<HTMLParagraphElement> HTMLParagraphElement::create(Document& document)
+PassRefPtr<HTMLParagraphElement> HTMLParagraphElement::create(Document& document)
{
- return adoptRef(*new HTMLParagraphElement(pTag, document));
+ return adoptRef(new HTMLParagraphElement(pTag, document));
}
-Ref<HTMLParagraphElement> HTMLParagraphElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLParagraphElement> HTMLParagraphElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLParagraphElement(tagName, document));
+ return adoptRef(new HTMLParagraphElement(tagName, document));
}
bool HTMLParagraphElement::isPresentationAttribute(const QualifiedName& name) const
diff --git a/Source/WebCore/html/HTMLParagraphElement.h b/Source/WebCore/html/HTMLParagraphElement.h
index 70154f677..14d73812a 100644
--- a/Source/WebCore/html/HTMLParagraphElement.h
+++ b/Source/WebCore/html/HTMLParagraphElement.h
@@ -29,8 +29,8 @@ namespace WebCore {
class HTMLParagraphElement final : public HTMLElement {
public:
- static Ref<HTMLParagraphElement> create(Document&);
- static Ref<HTMLParagraphElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLParagraphElement> create(Document&);
+ static PassRefPtr<HTMLParagraphElement> create(const QualifiedName&, Document&);
private:
HTMLParagraphElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLParamElement.cpp b/Source/WebCore/html/HTMLParamElement.cpp
index bfed47717..d10f462ed 100644
--- a/Source/WebCore/html/HTMLParamElement.cpp
+++ b/Source/WebCore/html/HTMLParamElement.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLParamElement.h"
+#include "Attribute.h"
#include "Document.h"
#include "HTMLNames.h"
@@ -36,9 +37,9 @@ inline HTMLParamElement::HTMLParamElement(const QualifiedName& tagName, Document
ASSERT(hasTagName(paramTag));
}
-Ref<HTMLParamElement> HTMLParamElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLParamElement> HTMLParamElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLParamElement(tagName, document));
+ return adoptRef(new HTMLParamElement(tagName, document));
}
String HTMLParamElement::name() const
diff --git a/Source/WebCore/html/HTMLParamElement.h b/Source/WebCore/html/HTMLParamElement.h
index d381b340e..4e81d2da7 100644
--- a/Source/WebCore/html/HTMLParamElement.h
+++ b/Source/WebCore/html/HTMLParamElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLParamElement final : public HTMLElement {
public:
- static Ref<HTMLParamElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLParamElement> create(const QualifiedName&, Document&);
String name() const;
String value() const;
@@ -43,6 +43,8 @@ private:
virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override;
};
+NODE_TYPE_CASTS(HTMLParamElement)
+
} // namespace WebCore
#endif
diff --git a/Source/WebCore/html/canvas/WebGLSync.idl b/Source/WebCore/html/HTMLParserErrorCodes.cpp
index e1a994758..e1861a781 100644
--- a/Source/WebCore/html/canvas/WebGLSync.idl
+++ b/Source/WebCore/html/HTMLParserErrorCodes.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -23,7 +23,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- Conditional=WEBGL
-] interface WebGLSync {
-};
+#include "config.h"
+
+// FIXME: Delete this file.
diff --git a/Source/WebCore/html/canvas/WebGLQuery.idl b/Source/WebCore/html/HTMLParserErrorCodes.h
index 23d353c46..1d88bc670 100644
--- a/Source/WebCore/html/canvas/WebGLQuery.idl
+++ b/Source/WebCore/html/HTMLParserErrorCodes.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -23,7 +23,4 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- Conditional=WEBGL
-] interface WebGLQuery {
-};
+// FIXME: Delete this file.
diff --git a/Source/WebCore/html/canvas/EXTShaderTextureLOD.idl b/Source/WebCore/html/HTMLParserQuirks.h
index 3baa298a3..4ac6db8ab 100644
--- a/Source/WebCore/html/canvas/EXTShaderTextureLOD.idl
+++ b/Source/WebCore/html/HTMLParserQuirks.h
@@ -1,15 +1,15 @@
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -23,9 +23,4 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- NoInterfaceObject,
- Conditional=WEBGL,
- GenerateIsReachable=ImplWebGLRenderingContext
-] interface EXTShaderTextureLOD {
-};
+// FIXME: Delete this file.
diff --git a/Source/WebCore/html/HTMLPlugInElement.cpp b/Source/WebCore/html/HTMLPlugInElement.cpp
index d786df4fe..93643c7a6 100644
--- a/Source/WebCore/html/HTMLPlugInElement.cpp
+++ b/Source/WebCore/html/HTMLPlugInElement.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Stefan Schimanski (1Stein@gmx.de)
- * Copyright (C) 2004, 2005, 2006, 2014 Apple Inc.
+ * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLPlugInElement.h"
+#include "Attribute.h"
#include "BridgeJSC.h"
#include "Chrome.h"
#include "ChromeClient.h"
@@ -54,9 +55,8 @@
#include "npruntime_impl.h"
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
#include "QuickTimePluginReplacement.h"
-#include "YouTubePluginReplacement.h"
#endif
namespace WebCore {
@@ -66,7 +66,7 @@ using namespace HTMLNames;
HTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document& document)
: HTMLFrameOwnerElement(tagName, document)
, m_inBeforeLoadEventHandler(false)
- , m_swapRendererTimer(*this, &HTMLPlugInElement::swapRendererTimerFired)
+ , m_swapRendererTimer(this, &HTMLPlugInElement::swapRendererTimerFired)
#if ENABLE(NETSCAPE_PLUGIN_API)
, m_NPObject(0)
#endif
@@ -90,7 +90,7 @@ HTMLPlugInElement::~HTMLPlugInElement()
bool HTMLPlugInElement::canProcessDrag() const
{
- const PluginViewBase* plugin = is<PluginViewBase>(pluginWidget()) ? downcast<PluginViewBase>(pluginWidget()) : nullptr;
+ const PluginViewBase* plugin = pluginWidget() && pluginWidget()->isPluginViewBase() ? toPluginViewBase(pluginWidget()) : nullptr;
return plugin ? plugin->canProcessDrag() : false;
}
@@ -104,7 +104,7 @@ bool HTMLPlugInElement::willRespondToMouseClickEvents()
void HTMLPlugInElement::willDetachRenderers()
{
- m_instance = nullptr;
+ m_instance.clear();
if (m_isCapturingMouseEvents) {
if (Frame* frame = document().frame())
@@ -122,7 +122,7 @@ void HTMLPlugInElement::willDetachRenderers()
void HTMLPlugInElement::resetInstance()
{
- m_instance = nullptr;
+ m_instance.clear();
}
PassRefPtr<JSC::Bindings::Instance> HTMLPlugInElement::getInstance()
@@ -157,17 +157,17 @@ bool HTMLPlugInElement::guardedDispatchBeforeLoadEvent(const String& sourceURL)
return beforeLoadAllowedLoad;
}
-Widget* HTMLPlugInElement::pluginWidget(PluginLoadingPolicy loadPolicy) const
+Widget* HTMLPlugInElement::pluginWidget() const
{
if (m_inBeforeLoadEventHandler) {
// The plug-in hasn't loaded yet, and it makes no sense to try to load if beforeload handler happened to touch the plug-in element.
// That would recursively call beforeload for the same element.
- return nullptr;
+ return 0;
}
- RenderWidget* renderWidget = loadPolicy == PluginLoadingPolicy::Load ? renderWidgetLoadingPlugin() : this->renderWidget();
+ RenderWidget* renderWidget = renderWidgetForJSBindings();
if (!renderWidget)
- return nullptr;
+ return 0;
return renderWidget->widget();
}
@@ -206,17 +206,17 @@ void HTMLPlugInElement::defaultEventHandler(Event* event)
// FIXME: Mouse down and scroll events are passed down to plug-in via custom code in EventHandler; these code paths should be united.
auto renderer = this->renderer();
- if (!is<RenderWidget>(renderer))
+ if (!renderer || !renderer->isWidget())
return;
- if (is<RenderEmbeddedObject>(*renderer)) {
- if (downcast<RenderEmbeddedObject>(*renderer).isPluginUnavailable()) {
- downcast<RenderEmbeddedObject>(*renderer).handleUnavailablePluginIndicatorEvent(event);
+ if (renderer->isEmbeddedObject()) {
+ if (toRenderEmbeddedObject(renderer)->isPluginUnavailable()) {
+ toRenderEmbeddedObject(renderer)->handleUnavailablePluginIndicatorEvent(event);
return;
}
- if (is<RenderSnapshottedPlugIn>(*renderer) && displayState() < Restarting) {
- downcast<RenderSnapshottedPlugIn>(*renderer).handleEvent(event);
+ if (toRenderEmbeddedObject(renderer)->isSnapshottedPlugIn() && displayState() < Restarting) {
+ toRenderSnapshottedPlugIn(renderer)->handleEvent(event);
HTMLFrameOwnerElement::defaultEventHandler(event);
return;
}
@@ -225,7 +225,7 @@ void HTMLPlugInElement::defaultEventHandler(Event* event)
return;
}
- RefPtr<Widget> widget = downcast<RenderWidget>(*renderer).widget();
+ RefPtr<Widget> widget = toRenderWidget(renderer)->widget();
if (!widget)
return;
widget->handleEvent(event);
@@ -241,10 +241,10 @@ bool HTMLPlugInElement::isKeyboardFocusable(KeyboardEvent*) const
return false;
Widget* widget = pluginWidget();
- if (!is<PluginViewBase>(widget))
+ if (!widget || !widget->isPluginViewBase())
return false;
- return downcast<PluginViewBase>(*widget).supportsKeyboardFocus();
+ return toPluginViewBase(widget)->supportsKeyboardFocus();
}
bool HTMLPlugInElement::isPluginElement() const
@@ -252,31 +252,14 @@ bool HTMLPlugInElement::isPluginElement() const
return true;
}
-bool HTMLPlugInElement::isUserObservable() const
-{
- // No widget - can't be anything to see or hear here.
- Widget* widget = pluginWidget(PluginLoadingPolicy::DoNotLoad);
- if (!is<PluginViewBase>(widget))
- return false;
-
- PluginViewBase& pluginView = downcast<PluginViewBase>(*widget);
-
- // If audio is playing (or might be) then the plugin is detectable.
- if (pluginView.audioHardwareActivity() != AudioHardwareActivityType::IsInactive)
- return true;
-
- // If the plugin is visible and not vanishingly small in either dimension it is detectable.
- return pluginView.isVisible() && pluginView.width() > 2 && pluginView.height() > 2;
-}
-
bool HTMLPlugInElement::supportsFocus() const
{
if (HTMLFrameOwnerElement::supportsFocus())
return true;
- if (useFallbackContent() || !is<RenderEmbeddedObject>(renderer()))
+ if (useFallbackContent() || !renderer() || !renderer()->isEmbeddedObject())
return false;
- return !downcast<RenderEmbeddedObject>(*renderer()).isPluginUnavailable();
+ return !toRenderEmbeddedObject(renderer())->isPluginUnavailable();
}
#if ENABLE(NETSCAPE_PLUGIN_API)
@@ -291,15 +274,15 @@ NPObject* HTMLPlugInElement::getNPObject()
#endif /* ENABLE(NETSCAPE_PLUGIN_API) */
-RenderPtr<RenderElement> HTMLPlugInElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition& insertionPosition)
+RenderPtr<RenderElement> HTMLPlugInElement::createElementRenderer(PassRef<RenderStyle> style)
{
if (m_pluginReplacement && m_pluginReplacement->willCreateRenderer())
- return m_pluginReplacement->createElementRenderer(*this, WTF::move(style), insertionPosition);
+ return m_pluginReplacement->createElementRenderer(*this, std::move(style));
- return createRenderer<RenderEmbeddedObject>(*this, WTF::move(style));
+ return createRenderer<RenderEmbeddedObject>(*this, std::move(style));
}
-void HTMLPlugInElement::swapRendererTimerFired()
+void HTMLPlugInElement::swapRendererTimerFired(Timer<HTMLPlugInElement>&)
{
ASSERT(displayState() == PreparingPluginReplacement || displayState() == DisplayingSnapshot);
if (userAgentShadowRoot())
@@ -330,28 +313,27 @@ void HTMLPlugInElement::didAddUserAgentShadowRoot(ShadowRoot* root)
}
}
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
static void registrar(const ReplacementPlugin&);
#endif
static Vector<ReplacementPlugin*>& registeredPluginReplacements()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(Vector<ReplacementPlugin*>, registeredReplacements, ());
+ DEFINE_STATIC_LOCAL(Vector<ReplacementPlugin*>, registeredReplacements, ());
static bool enginesQueried = false;
if (enginesQueried)
return registeredReplacements;
enginesQueried = true;
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
QuickTimePluginReplacement::registerPluginReplacement(registrar);
- YouTubePluginReplacement::registerPluginReplacement(registrar);
#endif
return registeredReplacements;
}
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
static void registrar(const ReplacementPlugin& replacement)
{
registeredPluginReplacements().append(new ReplacementPlugin(replacement));
@@ -375,10 +357,9 @@ static ReplacementPlugin* pluginReplacementForType(const URL& url, const String&
type = mimeTypeFromDataURL(url.string());
if (type.isEmpty() && !extension.isEmpty()) {
- for (auto* replacement : replacements) {
- if (replacement->supportsFileExtension(extension) && replacement->supportsURL(url))
- return replacement;
- }
+ for (size_t i = 0; i < replacements.size(); i++)
+ if (replacements[i]->supportsFileExtension(extension))
+ return replacements[i];
}
if (type.isEmpty()) {
@@ -390,10 +371,9 @@ static ReplacementPlugin* pluginReplacementForType(const URL& url, const String&
if (type.isEmpty())
return nullptr;
- for (auto* replacement : replacements) {
- if (replacement->supportsType(type) && replacement->supportsURL(url))
- return replacement;
- }
+ for (unsigned i = 0; i < replacements.size(); i++)
+ if (replacements[i]->supportsType(type))
+ return replacements[i];
return nullptr;
}
diff --git a/Source/WebCore/html/HTMLPlugInElement.h b/Source/WebCore/html/HTMLPlugInElement.h
index 6294d14dd..5866a4bf0 100644
--- a/Source/WebCore/html/HTMLPlugInElement.h
+++ b/Source/WebCore/html/HTMLPlugInElement.h
@@ -51,8 +51,7 @@ public:
PassRefPtr<JSC::Bindings::Instance> getInstance();
- enum class PluginLoadingPolicy { DoNotLoad, Load };
- WEBCORE_EXPORT Widget* pluginWidget(PluginLoadingPolicy = PluginLoadingPolicy::Load) const;
+ Widget* pluginWidget() const;
enum DisplayState {
WaitingForSnapshot,
@@ -72,7 +71,7 @@ public:
JSC::JSObject* scriptObjectForPluginReplacement();
#if ENABLE(NETSCAPE_PLUGIN_API)
- WEBCORE_EXPORT NPObject* getNPObject();
+ NPObject* getNPObject();
#endif
bool isCapturingMouseEvents() const { return m_isCapturingMouseEvents; }
@@ -89,8 +88,6 @@ public:
virtual bool isPlugInImageElement() const { return false; }
- bool isUserObservable() const;
-
protected:
HTMLPlugInElement(const QualifiedName& tagName, Document&);
@@ -103,7 +100,7 @@ protected:
virtual void defaultEventHandler(Event*) override;
virtual bool requestObject(const String& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues);
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual void didAddUserAgentShadowRoot(ShadowRoot*) override;
// Subclasses should use guardedDispatchBeforeLoadEvent instead of calling dispatchBeforeLoadEvent directly.
@@ -112,13 +109,14 @@ protected:
bool m_inBeforeLoadEventHandler;
private:
- void swapRendererTimerFired();
+ void swapRendererTimerFired(Timer<HTMLPlugInElement>&);
bool shouldOverridePlugin(const String& url, const String& mimeType);
bool dispatchBeforeLoadEvent(const String& sourceURL); // Not implemented, generates a compile error if subclasses call this by mistake.
- // This will load the plugin if necessary.
- virtual RenderWidget* renderWidgetLoadingPlugin() const = 0;
+ virtual bool areAuthorShadowsAllowed() const override { return false; }
+
+ virtual RenderWidget* renderWidgetForJSBindings() const = 0;
virtual bool supportsFocus() const override;
@@ -126,7 +124,7 @@ private:
virtual bool isPluginElement() const override final;
RefPtr<JSC::Bindings::Instance> m_instance;
- Timer m_swapRendererTimer;
+ Timer<HTMLPlugInElement> m_swapRendererTimer;
RefPtr<PluginReplacement> m_pluginReplacement;
#if ENABLE(NETSCAPE_PLUGIN_API)
NPObject* m_NPObject;
@@ -136,10 +134,10 @@ private:
DisplayState m_displayState;
};
-} // namespace WebCore
+void isHTMLPlugInElement(const HTMLPlugInElement&); // Catch unnecessary runtime check of type known at compile time.
+inline bool isHTMLPlugInElement(const Node& node) { return node.isPluginElement(); }
+NODE_TYPE_CASTS(HTMLPlugInElement)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLPlugInElement)
- static bool isType(const WebCore::Node& node) { return node.isPluginElement(); }
-SPECIALIZE_TYPE_TRAITS_END()
+} // namespace WebCore
#endif // HTMLPlugInElement_h
diff --git a/Source/WebCore/html/HTMLPlugInImageElement.cpp b/Source/WebCore/html/HTMLPlugInImageElement.cpp
index 3bb79a938..18ef20628 100644
--- a/Source/WebCore/html/HTMLPlugInImageElement.cpp
+++ b/Source/WebCore/html/HTMLPlugInImageElement.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2011, 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2011, 2012 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -55,6 +55,12 @@
#include <wtf/HashMap.h>
#include <wtf/text/StringHash.h>
+#if PLATFORM(IOS)
+#include "HTMLIFrameElement.h"
+#include "RenderBlockFlow.h"
+#include "YouTubeEmbedShadowElement.h"
+#endif
+
namespace WebCore {
using namespace HTMLNames;
@@ -67,12 +73,12 @@ static const float sizingFullPageAreaRatioThreshold = 0.96;
static const float autostartSoonAfterUserGestureThreshold = 5.0;
// This delay should not exceed the snapshot delay in PluginView.cpp
-static const auto simulatedMouseClickTimerDelay = std::chrono::milliseconds { 750 };
-static const auto removeSnapshotTimerDelay = std::chrono::milliseconds { 1500 };
+static const double simulatedMouseClickTimerDelay = .75;
+static const double removeSnapshotTimerDelay = 1.5;
static const String titleText(Page* page, String mimeType)
{
- DEPRECATED_DEFINE_STATIC_LOCAL(MimeTypeToLocalizedStringMap, mimeTypeToLabelTitleMap, ());
+ DEFINE_STATIC_LOCAL(MimeTypeToLocalizedStringMap, mimeTypeToLabelTitleMap, ());
String titleText = mimeTypeToLabelTitleMap.get(mimeType);
if (!titleText.isEmpty())
return titleText;
@@ -86,7 +92,7 @@ static const String titleText(Page* page, String mimeType)
static const String subtitleText(Page* page, String mimeType)
{
- DEPRECATED_DEFINE_STATIC_LOCAL(MimeTypeToLocalizedStringMap, mimeTypeToLabelSubtitleMap, ());
+ DEFINE_STATIC_LOCAL(MimeTypeToLocalizedStringMap, mimeTypeToLabelSubtitleMap, ());
String subtitleText = mimeTypeToLabelSubtitleMap.get(mimeType);
if (!subtitleText.isEmpty())
return subtitleText;
@@ -107,15 +113,14 @@ HTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Doc
, m_needsWidgetUpdate(!createdByParser)
, m_shouldPreferPlugInsForImages(preferPlugInsForImagesOption == ShouldPreferPlugInsForImages)
, m_needsDocumentActivationCallbacks(false)
- , m_simulatedMouseClickTimer(*this, &HTMLPlugInImageElement::simulatedMouseClickTimerFired, simulatedMouseClickTimerDelay)
- , m_removeSnapshotTimer(*this, &HTMLPlugInImageElement::removeSnapshotTimerFired)
+ , m_simulatedMouseClickTimer(this, &HTMLPlugInImageElement::simulatedMouseClickTimerFired, simulatedMouseClickTimerDelay)
+ , m_removeSnapshotTimer(this, &HTMLPlugInImageElement::removeSnapshotTimerFired)
, m_createdDuringUserGesture(ScriptController::processingUserGesture())
, m_isRestartedPlugin(false)
, m_needsCheckForSizeChange(false)
, m_plugInWasCreated(false)
, m_deferredPromotionToPrimaryPlugIn(false)
, m_snapshotDecision(SnapshotNotYetDecided)
- , m_plugInDimensionsSpecified(false)
{
setHasCustomStyleResolveCallbacks();
}
@@ -128,7 +133,7 @@ HTMLPlugInImageElement::~HTMLPlugInImageElement()
void HTMLPlugInImageElement::setDisplayState(DisplayState state)
{
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
if (state == RestartingWithPendingMouseClick || state == Restarting) {
m_isRestartedPlugin = true;
m_snapshotDecision = NeverSnapshot;
@@ -145,7 +150,9 @@ RenderEmbeddedObject* HTMLPlugInImageElement::renderEmbeddedObject() const
{
// HTMLObjectElement and HTMLEmbedElement may return arbitrary renderers
// when using fallback content.
- return is<RenderEmbeddedObject>(renderer()) ? downcast<RenderEmbeddedObject>(renderer()) : nullptr;
+ if (!renderer() || !renderer()->isEmbeddedObject())
+ return 0;
+ return toRenderEmbeddedObject(renderer());
}
bool HTMLPlugInImageElement::isImageType()
@@ -189,12 +196,12 @@ bool HTMLPlugInImageElement::wouldLoadAsNetscapePlugin(const String& url, const
return false;
}
-RenderPtr<RenderElement> HTMLPlugInImageElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition& insertionPosition)
+RenderPtr<RenderElement> HTMLPlugInImageElement::createElementRenderer(PassRef<RenderStyle> style)
{
ASSERT(!document().inPageCache());
if (displayState() >= PreparingPluginReplacement)
- return HTMLPlugInElement::createElementRenderer(WTF::move(style), insertionPosition);
+ return HTMLPlugInElement::createElementRenderer(std::move(style));
// Once a PlugIn Element creates its renderer, it needs to be told when the Document goes
// inactive or reactivates so it can clear the renderer before going into the page cache.
@@ -204,37 +211,32 @@ RenderPtr<RenderElement> HTMLPlugInImageElement::createElementRenderer(Ref<Rende
}
if (displayState() == DisplayingSnapshot) {
- auto renderSnapshottedPlugIn = createRenderer<RenderSnapshottedPlugIn>(*this, WTF::move(style));
+ auto renderSnapshottedPlugIn = createRenderer<RenderSnapshottedPlugIn>(*this, std::move(style));
renderSnapshottedPlugIn->updateSnapshot(m_snapshotImage);
- return WTF::move(renderSnapshottedPlugIn);
+ return std::move(renderSnapshottedPlugIn);
}
// Fallback content breaks the DOM->Renderer class relationship of this
// class and all superclasses because createObject won't necessarily
// return a RenderEmbeddedObject or RenderWidget.
if (useFallbackContent())
- return RenderElement::createFor(*this, WTF::move(style));
+ return RenderElement::createFor(*this, std::move(style));
if (isImageType())
- return createRenderer<RenderImage>(*this, WTF::move(style));
-
- return HTMLPlugInElement::createElementRenderer(WTF::move(style), insertionPosition);
-}
-
-bool HTMLPlugInImageElement::childShouldCreateRenderer(const Node& child) const
-{
- if (is<RenderSnapshottedPlugIn>(renderer()) && !hasShadowRootParent(child))
- return false;
+ return createRenderer<RenderImage>(*this, std::move(style));
- return HTMLPlugInElement::childShouldCreateRenderer(child);
+#if PLATFORM(IOS)
+ if (ShadowRoot* shadowRoot = this->shadowRoot()) {
+ Element* shadowElement = toElement(shadowRoot->firstChild());
+ if (shadowElement && shadowElement->shadowPseudoId() == "-apple-youtube-shadow-iframe")
+ return createRenderer<RenderBlockFlow>(*this, std::move(style));
+ }
+#endif
+ return HTMLPlugInElement::createElementRenderer(std::move(style));
}
-bool HTMLPlugInImageElement::willRecalcStyle(Style::Change change)
+bool HTMLPlugInImageElement::willRecalcStyle(Style::Change)
{
- // Make sure style recalcs scheduled by a child shadow tree don't trigger reconstruction and cause flicker.
- if (change == Style::NoChange && styleChangeType() == NoStyleChange)
- return true;
-
// FIXME: There shoudn't be need to force render tree reconstruction here.
// It is only done because loading and load event dispatching is tied to render tree construction.
if (!useFallbackContent() && needsWidgetUpdate() && renderer() && !isImageType() && (displayState() != DisplayingSnapshot))
@@ -245,32 +247,25 @@ bool HTMLPlugInImageElement::willRecalcStyle(Style::Change change)
void HTMLPlugInImageElement::didAttachRenderers()
{
if (!isImageType()) {
- RefPtr<HTMLPlugInImageElement> element = this;
- Style::queuePostResolutionCallback([element]{
- element->updateWidgetIfNecessary();
- });
+ queuePostAttachCallback(&HTMLPlugInImageElement::updateWidgetCallback, *this);
return;
}
if (!renderer() || useFallbackContent())
return;
- // Image load might complete synchronously and cause us to re-enter.
- RefPtr<HTMLPlugInImageElement> element = this;
- Style::queuePostResolutionCallback([element]{
- element->startLoadingImage();
- });
+ // Image load might complete synchronously and cause us to re-enter attach.
+ queuePostAttachCallback(&HTMLPlugInImageElement::startLoadingImageCallback, *this);
}
void HTMLPlugInImageElement::willDetachRenderers()
{
// FIXME: Because of the insanity that is HTMLPlugInImageElement::willRecalcStyle,
// we can end up detaching during an attach() call, before we even have a
- // renderer. In that case, don't mark the widget for update.
+ // renderer. In that case, don't mark the widget for update.
if (renderer() && !useFallbackContent()) {
// Update the widget the next time we attach (detaching destroys the plugin).
setNeedsWidgetUpdate(true);
}
-
HTMLPlugInElement::willDetachRenderers();
}
@@ -301,13 +296,13 @@ void HTMLPlugInImageElement::finishParsingChildren()
void HTMLPlugInImageElement::didMoveToNewDocument(Document* oldDocument)
{
if (m_needsDocumentActivationCallbacks) {
- oldDocument->unregisterForPageCacheSuspensionCallbacks(this);
+ if (oldDocument)
+ oldDocument->unregisterForPageCacheSuspensionCallbacks(this);
document().registerForPageCacheSuspensionCallbacks(this);
}
if (m_imageLoader)
m_imageLoader->elementDidMoveToNewDocument();
-
HTMLPlugInElement::didMoveToNewDocument(oldDocument);
}
@@ -326,13 +321,23 @@ void HTMLPlugInImageElement::documentDidResumeFromPageCache()
HTMLPlugInElement::documentDidResumeFromPageCache();
}
+void HTMLPlugInImageElement::updateWidgetCallback(Node& node, unsigned)
+{
+ toHTMLPlugInImageElement(node).updateWidgetIfNecessary();
+}
+
void HTMLPlugInImageElement::startLoadingImage()
{
if (!m_imageLoader)
- m_imageLoader = std::make_unique<HTMLImageLoader>(*this);
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
m_imageLoader->updateFromElement();
}
+void HTMLPlugInImageElement::startLoadingImageCallback(Node& node, unsigned)
+{
+ toHTMLPlugInImageElement(node).startLoadingImage();
+}
+
void HTMLPlugInImageElement::updateSnapshot(PassRefPtr<Image> image)
{
if (displayState() > DisplayingSnapshot)
@@ -340,22 +345,30 @@ void HTMLPlugInImageElement::updateSnapshot(PassRefPtr<Image> image)
m_snapshotImage = image;
- if (!renderer())
+ if (renderer()->isSnapshottedPlugIn()) {
+ toRenderSnapshottedPlugIn(renderer())->updateSnapshot(image);
return;
- auto& renderer = *this->renderer();
+ }
- if (is<RenderSnapshottedPlugIn>(renderer)) {
- downcast<RenderSnapshottedPlugIn>(renderer).updateSnapshot(image);
+ if (renderer()->isEmbeddedObject())
+ renderer()->repaint();
+}
+
+void HTMLPlugInImageElement::checkSnapshotStatus()
+{
+ if (!renderer()->isSnapshottedPlugIn()) {
+ if (displayState() == Playing)
+ checkSizeChangeForSnapshotting();
return;
}
- if (is<RenderEmbeddedObject>(renderer))
- renderer.repaint();
+ // Notify the shadow root that the size changed so that we may update the overlay layout.
+ ensureUserAgentShadowRoot().dispatchEvent(Event::create(eventNames().resizeEvent, true, false));
}
static DOMWrapperWorld& plugInImageElementIsolatedWorld()
{
- static DOMWrapperWorld& isolatedWorld = DOMWrapperWorld::create(JSDOMWindow::commonVM()).leakRef();
+ static DOMWrapperWorld& isolatedWorld = *DOMWrapperWorld::create(JSDOMWindow::commonVM()).leakRef();
return isolatedWorld;
}
@@ -379,7 +392,7 @@ void HTMLPlugInImageElement::didAddUserAgentShadowRoot(ShadowRoot* root)
DOMWrapperWorld& isolatedWorld = plugInImageElementIsolatedWorld();
document().ensurePlugInsInjectedScript(isolatedWorld);
- ScriptController& scriptController = document().frame()->script();
+ ScriptController& scriptController = page->mainFrame().script();
JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController.globalObject(isolatedWorld));
JSC::ExecState* exec = globalObject->globalExec();
@@ -395,27 +408,52 @@ void HTMLPlugInImageElement::didAddUserAgentShadowRoot(ShadowRoot* root)
argList.append(JSC::jsBoolean(!m_snapshotImage));
// It is expected the JS file provides a createOverlay(shadowRoot, title, subtitle) function.
- JSC::JSObject* overlay = globalObject->get(exec, JSC::Identifier::fromString(exec, "createOverlay")).toObject(exec);
+ JSC::JSObject* overlay = globalObject->get(exec, JSC::Identifier(exec, "createOverlay")).toObject(exec);
JSC::CallData callData;
JSC::CallType callType = overlay->methodTable()->getCallData(overlay, callData);
if (callType == JSC::CallTypeNone)
return;
JSC::call(exec, overlay, callType, callData, globalObject, argList);
- exec->clearException();
}
-bool HTMLPlugInImageElement::partOfSnapshotOverlay(const Node* node) const
+bool HTMLPlugInImageElement::partOfSnapshotOverlay(Node* node)
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, selector, (".snapshot-overlay", AtomicString::ConstructFromLiteral));
- ShadowRoot* shadow = userAgentShadowRoot();
- if (!shadow)
- return false;
- RefPtr<Element> snapshotLabel = shadow->querySelector(selector, ASSERT_NO_EXCEPTION);
+ DEFINE_STATIC_LOCAL(AtomicString, selector, (".snapshot-overlay", AtomicString::ConstructFromLiteral));
+ RefPtr<Element> snapshotLabel = ensureUserAgentShadowRoot().querySelector(selector, ASSERT_NO_EXCEPTION);
return node && snapshotLabel && (node == snapshotLabel.get() || node->isDescendantOf(snapshotLabel.get()));
}
-void HTMLPlugInImageElement::removeSnapshotTimerFired()
+#if PLATFORM(IOS)
+void HTMLPlugInImageElement::createShadowIFrameSubtree(const String& src)
+{
+ if (this->shadowRoot())
+ return;
+
+ if (src.isEmpty())
+ return;
+
+ RefPtr<YouTubeEmbedShadowElement> shadowElement = YouTubeEmbedShadowElement::create(document());
+ ShadowRoot& root = this->ensureUserAgentShadowRoot();
+ root.appendChild(shadowElement, ASSERT_NO_EXCEPTION);
+
+ RefPtr<HTMLIFrameElement> iframeElement = HTMLIFrameElement::create(HTMLNames::iframeTag, document());
+ if (hasAttribute(HTMLNames::widthAttr))
+ iframeElement->setAttribute(HTMLNames::widthAttr, AtomicString("100%", AtomicString::ConstructFromLiteral));
+ if (hasAttribute(HTMLNames::heightAttr)) {
+ iframeElement->setAttribute(HTMLNames::styleAttr, AtomicString("max-height: 100%", AtomicString::ConstructFromLiteral));
+ iframeElement->setAttribute(HTMLNames::heightAttr, getAttribute(HTMLNames::heightAttr));
+ }
+ iframeElement->setAttribute(HTMLNames::srcAttr, src);
+ iframeElement->setAttribute(HTMLNames::frameborderAttr, AtomicString("0", AtomicString::ConstructFromLiteral));
+
+ // Disable frame flattening for this iframe.
+ iframeElement->setAttribute(HTMLNames::scrollingAttr, AtomicString("no", AtomicString::ConstructFromLiteral));
+ shadowElement->appendChild(iframeElement, ASSERT_NO_EXCEPTION);
+}
+#endif
+
+void HTMLPlugInImageElement::removeSnapshotTimerFired(Timer<HTMLPlugInImageElement>&)
{
m_snapshotImage = nullptr;
m_isRestartedPlugin = false;
@@ -428,12 +466,15 @@ static void addPlugInsFromNodeListMatchingPlugInOrigin(HTMLPlugInImageElementLis
{
for (unsigned i = 0, length = collection->length(); i < length; i++) {
Node* node = collection->item(i);
- if (is<HTMLPlugInImageElement>(*node)) {
- HTMLPlugInImageElement& plugInImageElement = downcast<HTMLPlugInImageElement>(*node);
- const URL& loadedURL = plugInImageElement.loadedUrl();
- String otherMimeType = plugInImageElement.loadedMimeType();
- if (plugInOrigin == loadedURL.host() && mimeType == otherMimeType)
- plugInList.append(&plugInImageElement);
+ if (node->isPluginElement()) {
+ HTMLPlugInElement* plugInElement = toHTMLPlugInElement(node);
+ if (plugInElement->isPlugInImageElement()) {
+ HTMLPlugInImageElement* plugInImageElement = toHTMLPlugInImageElement(node);
+ const URL& loadedURL = plugInImageElement->loadedUrl();
+ String otherMimeType = plugInImageElement->loadedMimeType();
+ if (plugInOrigin == loadedURL.host() && mimeType == otherMimeType)
+ plugInList.append(plugInImageElement);
+ }
}
}
}
@@ -483,7 +524,7 @@ void HTMLPlugInImageElement::userDidClickSnapshot(PassRefPtr<MouseEvent> event,
String plugInOrigin = m_loadedUrl.host();
if (document().page() && !SchemeRegistry::shouldTreatURLSchemeAsLocal(document().page()->mainFrame().document()->baseURL().protocol()) && document().page()->settings().autostartOriginPlugInSnapshottingEnabled())
- document().page()->plugInClient()->didStartFromOrigin(document().page()->mainFrame().document()->baseURL().host(), plugInOrigin, loadedMimeType(), document().page()->sessionID());
+ document().page()->plugInClient()->didStartFromOrigin(document().page()->mainFrame().document()->baseURL().host(), plugInOrigin, loadedMimeType());
LOG(Plugins, "%p User clicked on snapshotted plug-in. Restart.", this);
restartSnapshottedPlugIn();
@@ -524,7 +565,7 @@ void HTMLPlugInImageElement::dispatchPendingMouseClick()
m_simulatedMouseClickTimer.restart();
}
-void HTMLPlugInImageElement::simulatedMouseClickTimerFired()
+void HTMLPlugInImageElement::simulatedMouseClickTimerFired(DeferrableOneShotTimer<HTMLPlugInImageElement>&)
{
ASSERT(displayState() == RestartingWithPendingMouseClick);
ASSERT(m_pendingClickEventFromSnapshot);
@@ -554,7 +595,7 @@ void HTMLPlugInImageElement::checkSizeChangeForSnapshotting()
return;
m_needsCheckForSizeChange = false;
- LayoutRect contentBoxRect = downcast<RenderBox>(*renderer()).contentBoxRect();
+ LayoutRect contentBoxRect = toRenderBox(renderer())->contentBoxRect();
int contentWidth = contentBoxRect.width();
int contentHeight = contentBoxRect.height();
@@ -565,64 +606,10 @@ void HTMLPlugInImageElement::checkSizeChangeForSnapshotting()
setDisplayState(WaitingForSnapshot);
m_snapshotDecision = Snapshotted;
Widget* widget = pluginWidget();
- if (is<PluginViewBase>(widget))
- downcast<PluginViewBase>(*widget).beginSnapshottingRunningPlugin();
+ if (widget && widget->isPluginViewBase())
+ toPluginViewBase(widget)->beginSnapshottingRunningPlugin();
}
-static inline bool is100Percent(Length length)
-{
- return length.isPercent() && length.percent() == 100;
-}
-
-static inline bool isSmallerThanTinySizingThreshold(const RenderEmbeddedObject& renderer)
-{
- LayoutRect contentRect = renderer.contentBoxRect();
- return contentRect.width() <= sizingTinyDimensionThreshold || contentRect.height() <= sizingTinyDimensionThreshold;
-}
-
-bool HTMLPlugInImageElement::isTopLevelFullPagePlugin(const RenderEmbeddedObject& renderer) const
-{
- Frame& frame = *document().frame();
- if (!frame.isMainFrame())
- return false;
-
- auto& style = renderer.style();
- IntSize visibleSize = frame.view()->visibleSize();
- LayoutRect contentRect = renderer.contentBoxRect();
- int contentWidth = contentRect.width();
- int contentHeight = contentRect.height();
- return is100Percent(style.width()) && is100Percent(style.height()) && contentWidth * contentHeight > visibleSize.area() * sizingFullPageAreaRatioThreshold;
-}
-
-void HTMLPlugInImageElement::checkSnapshotStatus()
-{
- if (!is<RenderSnapshottedPlugIn>(*renderer())) {
- if (displayState() == Playing)
- checkSizeChangeForSnapshotting();
- return;
- }
-
- // If width and height styles were previously not set and we've snapshotted the plugin we may need to restart the plugin so that its state can be updated appropriately.
- if (!document().page()->settings().snapshotAllPlugIns() && displayState() <= DisplayingSnapshot && !m_plugInDimensionsSpecified) {
- RenderSnapshottedPlugIn& renderer = downcast<RenderSnapshottedPlugIn>(*this->renderer());
- if (!renderer.style().logicalWidth().isSpecified() && !renderer.style().logicalHeight().isSpecified())
- return;
-
- m_plugInDimensionsSpecified = true;
- if (isTopLevelFullPagePlugin(renderer)) {
- m_snapshotDecision = NeverSnapshot;
- restartSnapshottedPlugIn();
- } else if (isSmallerThanTinySizingThreshold(renderer)) {
- m_snapshotDecision = MaySnapshotWhenResized;
- restartSnapshottedPlugIn();
- }
- return;
- }
-
- // Notify the shadow root that the size changed so that we may update the overlay layout.
- ensureUserAgentShadowRoot().dispatchEvent(Event::create(eventNames().resizeEvent, true, false));
-}
-
void HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn(const URL& url)
{
LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data());
@@ -706,23 +693,28 @@ void HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn(const URL& url)
m_snapshotDecision = NeverSnapshot;
return;
}
-
- auto& renderer = downcast<RenderEmbeddedObject>(*this->renderer());
- LayoutRect contentRect = renderer.contentBoxRect();
- int contentWidth = contentRect.width();
- int contentHeight = contentRect.height();
-
- m_plugInDimensionsSpecified = renderer.style().logicalWidth().isSpecified() || renderer.style().logicalHeight().isSpecified();
-
- if (isTopLevelFullPagePlugin(renderer)) {
+
+ RenderBox* renderEmbeddedObject = toRenderBox(renderer());
+ Length styleWidth = renderEmbeddedObject->style().width();
+ Length styleHeight = renderEmbeddedObject->style().height();
+ LayoutRect contentBoxRect = renderEmbeddedObject->contentBoxRect();
+ int contentWidth = contentBoxRect.width();
+ int contentHeight = contentBoxRect.height();
+ int contentArea = contentWidth * contentHeight;
+ IntSize visibleViewSize = document().frame()->view()->visibleSize();
+ int visibleArea = visibleViewSize.width() * visibleViewSize.height();
+
+ if (inMainFrame && styleWidth.isPercent() && (styleWidth.percent() == 100)
+ && styleHeight.isPercent() && (styleHeight.percent() == 100)
+ && (static_cast<float>(contentArea) / visibleArea > sizingFullPageAreaRatioThreshold)) {
LOG(Plugins, "%p Plug-in is top level full page, set to play", this);
m_snapshotDecision = NeverSnapshot;
return;
}
- if (isSmallerThanTinySizingThreshold(renderer)) {
+ if (contentWidth <= sizingTinyDimensionThreshold || contentHeight <= sizingTinyDimensionThreshold) {
LOG(Plugins, "%p Plug-in is very small %dx%d, set to play", this, contentWidth, contentHeight);
- m_sizeWhenSnapshotted = IntSize(contentWidth, contentHeight);
+ m_sizeWhenSnapshotted = IntSize(contentBoxRect.width().toInt(), contentBoxRect.height().toInt());
m_snapshotDecision = MaySnapshotWhenResized;
return;
}
@@ -734,16 +726,16 @@ void HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn(const URL& url)
return;
}
- LOG(Plugins, "%p Plug-in from (%s, %s) is not auto-start, sized at %dx%d, set to wait for snapshot", this, document().topDocument().baseURL().host().utf8().data(), url.host().utf8().data(), contentWidth, contentHeight);
+ LOG(Plugins, "%p Plug-in from (%s, %s) is not auto-start, sized at %dx%d, set to wait for snapshot", this, document().page()->mainFrame().document()->baseURL().host().utf8().data(), url.host().utf8().data(), contentWidth, contentHeight);
m_snapshotDecision = Snapshotted;
setDisplayState(WaitingForSnapshot);
}
-void HTMLPlugInImageElement::subframeLoaderDidCreatePlugIn(const Widget& widget)
+void HTMLPlugInImageElement::subframeLoaderDidCreatePlugIn(const Widget* widget)
{
m_plugInWasCreated = true;
- if (is<PluginViewBase>(widget) && downcast<PluginViewBase>(widget).shouldAlwaysAutoStart()) {
+ if (widget->isPluginViewBase() && toPluginViewBase(widget)->shouldAlwaysAutoStart()) {
LOG(Plugins, "%p Plug-in should auto-start, set to play", this);
m_snapshotDecision = NeverSnapshot;
setDisplayState(Playing);
@@ -761,11 +753,11 @@ void HTMLPlugInImageElement::defaultEventHandler(Event* event)
{
RenderElement* r = renderer();
if (r && r->isEmbeddedObject()) {
- if (displayState() == WaitingForSnapshot && is<MouseEvent>(*event) && event->type() == eventNames().clickEvent) {
- MouseEvent& mouseEvent = downcast<MouseEvent>(*event);
- if (mouseEvent.button() == LeftButton) {
- userDidClickSnapshot(&mouseEvent, true);
- mouseEvent.setDefaultHandled();
+ if (isPlugInImageElement() && displayState() == WaitingForSnapshot && event->isMouseEvent() && event->type() == eventNames().clickEvent) {
+ MouseEvent* mouseEvent = toMouseEvent(event);
+ if (mouseEvent->button() == LeftButton) {
+ userDidClickSnapshot(mouseEvent, true);
+ event->setDefaultHandled();
return;
}
}
diff --git a/Source/WebCore/html/HTMLPlugInImageElement.h b/Source/WebCore/html/HTMLPlugInImageElement.h
index e0495b74d..7e9e68677 100644
--- a/Source/WebCore/html/HTMLPlugInImageElement.h
+++ b/Source/WebCore/html/HTMLPlugInImageElement.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2011, 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,13 +23,16 @@
#include "HTMLPlugInElement.h"
+#include "RenderStyle.h"
+#include <wtf/OwnPtr.h>
+
namespace WebCore {
class HTMLImageLoader;
+class HTMLVideoElement;
class FrameLoader;
class Image;
class MouseEvent;
-class RenderStyle;
class Widget;
enum PluginCreationOption {
@@ -37,8 +40,12 @@ enum PluginCreationOption {
CreateOnlyNonNetscapePlugins,
};
-// Base class for HTMLAppletElement, HTMLEmbedElement, and HTMLObjectElement.
-// FIXME: Should HTMLAppletElement inherit from HTMLPlugInElement directly instead?
+enum PreferPlugInsForImagesOption {
+ ShouldPreferPlugInsForImages,
+ ShouldNotPreferPlugInsForImages
+};
+
+// Base class for HTMLObjectElement and HTMLEmbedElement
class HTMLPlugInImageElement : public HTMLPlugInElement {
public:
virtual ~HTMLPlugInImageElement();
@@ -67,17 +74,21 @@ public:
bool needsWidgetUpdate() const { return m_needsWidgetUpdate; }
void setNeedsWidgetUpdate(bool needsWidgetUpdate) { m_needsWidgetUpdate = needsWidgetUpdate; }
+#if PLATFORM(IOS)
+ void createShadowIFrameSubtree(const String& src);
+#endif
+
void userDidClickSnapshot(PassRefPtr<MouseEvent>, bool forwardEvent);
void checkSnapshotStatus();
Image* snapshotImage() const { return m_snapshotImage.get(); }
- WEBCORE_EXPORT void restartSnapshottedPlugIn();
+ void restartSnapshottedPlugIn();
// Plug-in URL might not be the same as url() with overriding parameters.
void subframeLoaderWillCreatePlugIn(const URL& plugInURL);
- void subframeLoaderDidCreatePlugIn(const Widget&);
+ void subframeLoaderDidCreatePlugIn(const Widget*);
- WEBCORE_EXPORT void setIsPrimarySnapshottedPlugIn(bool);
- bool partOfSnapshotOverlay(const Node*) const;
+ void setIsPrimarySnapshottedPlugIn(bool);
+ bool partOfSnapshotOverlay(Node*);
bool needsCheckForSizeChange() const { return m_needsCheckForSizeChange; }
void setNeedsCheckForSizeChange() { m_needsCheckForSizeChange = true; }
@@ -93,60 +104,61 @@ public:
SnapshotDecision snapshotDecision() const { return m_snapshotDecision; }
protected:
- enum PreferPlugInsForImagesOption { ShouldPreferPlugInsForImages, ShouldNotPreferPlugInsForImages };
HTMLPlugInImageElement(const QualifiedName& tagName, Document&, bool createdByParser, PreferPlugInsForImagesOption);
- virtual void didMoveToNewDocument(Document* oldDocument) override;
- virtual bool requestObject(const String& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues) override final;
-
bool isImageType();
- HTMLImageLoader* imageLoader() { return m_imageLoader.get(); }
-
- bool allowedToLoadFrameURL(const String& url);
- bool wouldLoadAsNetscapePlugin(const String& url, const String& serviceType);
+ OwnPtr<HTMLImageLoader> m_imageLoader;
String m_serviceType;
String m_url;
+ URL m_loadedUrl;
- std::unique_ptr<HTMLImageLoader> m_imageLoader;
+ static void updateWidgetCallback(Node&, unsigned);
+ static void startLoadingImageCallback(Node&, unsigned);
-private:
- virtual bool isPlugInImageElement() const override final { return true; }
- virtual bool isRestartedPlugin() const override final { return m_isRestartedPlugin; }
+ virtual void didAttachRenderers() override;
+ virtual void willDetachRenderers() override;
- virtual void finishParsingChildren() override final;
- virtual void didAddUserAgentShadowRoot(ShadowRoot*) override final;
+ bool allowedToLoadFrameURL(const String& url);
+ bool wouldLoadAsNetscapePlugin(const String& url, const String& serviceType);
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
- virtual bool childShouldCreateRenderer(const Node&) const override;
- virtual bool willRecalcStyle(Style::Change) override final;
- virtual void didAttachRenderers() override final;
- virtual void willDetachRenderers() override final;
+ virtual void didMoveToNewDocument(Document* oldDocument) override;
- virtual void documentWillSuspendForPageCache() override final;
- virtual void documentDidResumeFromPageCache() override final;
+ virtual void documentWillSuspendForPageCache() override;
+ virtual void documentDidResumeFromPageCache() override;
- virtual void defaultEventHandler(Event*) override final;
- virtual void dispatchPendingMouseClick() override final;
+ virtual bool isRestartedPlugin() const override { return m_isRestartedPlugin; }
+ virtual bool requestObject(const String& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues) override;
- virtual void updateSnapshot(PassRefPtr<Image>) override final;
+private:
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
+ virtual bool willRecalcStyle(Style::Change) override;
+
+ virtual void didAddUserAgentShadowRoot(ShadowRoot*) override;
+
+ virtual void finishParsingChildren() override;
- void startLoadingImage();
void updateWidgetIfNecessary();
+ void startLoadingImage();
- void simulatedMouseClickTimerFired();
+ virtual void updateSnapshot(PassRefPtr<Image>) override;
+ virtual void dispatchPendingMouseClick() override;
+ void simulatedMouseClickTimerFired(DeferrableOneShotTimer<HTMLPlugInImageElement>&);
void restartSimilarPlugIns();
- void removeSnapshotTimerFired();
- bool isTopLevelFullPagePlugin(const RenderEmbeddedObject&) const;
- URL m_loadedUrl;
+ virtual bool isPlugInImageElement() const override { return true; }
+
+ void removeSnapshotTimerFired(Timer<HTMLPlugInImageElement>&);
+
+ virtual void defaultEventHandler(Event*) override;
+
bool m_needsWidgetUpdate;
bool m_shouldPreferPlugInsForImages;
bool m_needsDocumentActivationCallbacks;
RefPtr<MouseEvent> m_pendingClickEventFromSnapshot;
- DeferrableOneShotTimer m_simulatedMouseClickTimer;
- Timer m_removeSnapshotTimer;
+ DeferrableOneShotTimer<HTMLPlugInImageElement> m_simulatedMouseClickTimer;
+ Timer<HTMLPlugInImageElement> m_removeSnapshotTimer;
RefPtr<Image> m_snapshotImage;
bool m_createdDuringUserGesture;
bool m_isRestartedPlugin;
@@ -155,14 +167,13 @@ private:
bool m_deferredPromotionToPrimaryPlugIn;
IntSize m_sizeWhenSnapshotted;
SnapshotDecision m_snapshotDecision;
- bool m_plugInDimensionsSpecified;
};
-} // namespace WebCore
+void isHTMLPlugInImageElement(const HTMLPlugInImageElement&); // Catch unnecessary runtime check of type known at compile time.
+inline bool isHTMLPlugInImageElement(const HTMLPlugInElement& element) { return element.isPlugInImageElement(); }
+inline bool isHTMLPlugInImageElement(const Node& node) { return node.isPluginElement() && toHTMLPlugInElement(node).isPlugInImageElement(); }
+NODE_TYPE_CASTS(HTMLPlugInImageElement)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLPlugInImageElement)
- static bool isType(const WebCore::HTMLPlugInElement& element) { return element.isPlugInImageElement(); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::HTMLPlugInElement>(node) && isType(downcast<WebCore::HTMLPlugInElement>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+} // namespace WebCore
#endif // HTMLPlugInImageElement_h
diff --git a/Source/WebCore/html/HTMLPreElement.cpp b/Source/WebCore/html/HTMLPreElement.cpp
index 60af0de91..f994ae15a 100644
--- a/Source/WebCore/html/HTMLPreElement.cpp
+++ b/Source/WebCore/html/HTMLPreElement.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLPreElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
@@ -37,9 +38,9 @@ inline HTMLPreElement::HTMLPreElement(const QualifiedName& tagName, Document& do
{
}
-Ref<HTMLPreElement> HTMLPreElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLPreElement> HTMLPreElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLPreElement(tagName, document));
+ return adoptRef(new HTMLPreElement(tagName, document));
}
bool HTMLPreElement::isPresentationAttribute(const QualifiedName& name) const
diff --git a/Source/WebCore/html/HTMLPreElement.h b/Source/WebCore/html/HTMLPreElement.h
index 45880f599..688601e60 100644
--- a/Source/WebCore/html/HTMLPreElement.h
+++ b/Source/WebCore/html/HTMLPreElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLPreElement final : public HTMLElement {
public:
- static Ref<HTMLPreElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLPreElement> create(const QualifiedName&, Document&);
private:
HTMLPreElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLProgressElement.cpp b/Source/WebCore/html/HTMLProgressElement.cpp
index 87f0e370c..c877fbe05 100644
--- a/Source/WebCore/html/HTMLProgressElement.cpp
+++ b/Source/WebCore/html/HTMLProgressElement.cpp
@@ -19,8 +19,10 @@
*/
#include "config.h"
+#if ENABLE(PROGRESS_ELEMENT)
#include "HTMLProgressElement.h"
+#include "Attribute.h"
#include "ElementIterator.h"
#include "EventNames.h"
#include "ExceptionCode.h"
@@ -49,19 +51,19 @@ HTMLProgressElement::~HTMLProgressElement()
{
}
-Ref<HTMLProgressElement> HTMLProgressElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLProgressElement> HTMLProgressElement::create(const QualifiedName& tagName, Document& document)
{
- Ref<HTMLProgressElement> progress = adoptRef(*new HTMLProgressElement(tagName, document));
+ RefPtr<HTMLProgressElement> progress = adoptRef(new HTMLProgressElement(tagName, document));
progress->ensureUserAgentShadowRoot();
- return progress;
+ return progress.release();
}
-RenderPtr<RenderElement> HTMLProgressElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLProgressElement::createElementRenderer(PassRef<RenderStyle> style)
{
- if (!style.get().hasAppearance())
- return RenderElement::createFor(*this, WTF::move(style));
+ if (!style.get().hasAppearance() || hasAuthorShadowRoot())
+ return RenderElement::createFor(*this, std::move(style));
- return createRenderer<RenderProgress>(*this, WTF::move(style));
+ return createRenderer<RenderProgress>(*this, std::move(style));
}
bool HTMLProgressElement::childShouldCreateRenderer(const Node& child) const
@@ -71,9 +73,9 @@ bool HTMLProgressElement::childShouldCreateRenderer(const Node& child) const
RenderProgress* HTMLProgressElement::renderProgress() const
{
- if (is<RenderProgress>(renderer()))
- return downcast<RenderProgress>(renderer());
- return downcast<RenderProgress>(descendantsOfType<Element>(*userAgentShadowRoot()).first()->renderer());
+ if (renderer() && renderer()->isProgress())
+ return toRenderProgress(renderer());
+ return toRenderProgress(descendantsOfType<Element>(*userAgentShadowRoot()).first()->renderer());
}
void HTMLProgressElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -109,7 +111,7 @@ void HTMLProgressElement::setValue(double value, ExceptionCode& ec)
double HTMLProgressElement::max() const
{
- double max = parseToDoubleForNumberType(fastGetAttribute(maxAttr));
+ double max = parseToDoubleForNumberType(getAttribute(maxAttr));
return !std::isfinite(max) || max <= 0 ? 1 : max;
}
@@ -141,7 +143,7 @@ void HTMLProgressElement::didElementStateChange()
bool wasDeterminate = render->isDeterminate();
render->updateFromElement();
if (wasDeterminate != isDeterminate())
- setNeedsStyleRecalc();
+ didAffectSelector(AffectedSelectorIndeterminate);
}
}
@@ -167,3 +169,4 @@ bool HTMLProgressElement::shouldAppearIndeterminate() const
}
} // namespace
+#endif
diff --git a/Source/WebCore/html/HTMLProgressElement.h b/Source/WebCore/html/HTMLProgressElement.h
index b7b45a59a..255563d22 100644
--- a/Source/WebCore/html/HTMLProgressElement.h
+++ b/Source/WebCore/html/HTMLProgressElement.h
@@ -21,6 +21,7 @@
#ifndef HTMLProgressElement_h
#define HTMLProgressElement_h
+#if ENABLE(PROGRESS_ELEMENT)
#include "LabelableElement.h"
namespace WebCore {
@@ -33,7 +34,7 @@ public:
static const double IndeterminatePosition;
static const double InvalidPosition;
- static Ref<HTMLProgressElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLProgressElement> create(const QualifiedName&, Document&);
double value() const;
void setValue(double, ExceptionCode&);
@@ -49,10 +50,11 @@ private:
HTMLProgressElement(const QualifiedName&, Document&);
virtual ~HTMLProgressElement();
+ virtual bool areAuthorShadowsAllowed() const override { return false; }
virtual bool shouldAppearIndeterminate() const override;
virtual bool supportLabels() const override { return true; }
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual bool childShouldCreateRenderer(const Node&) const override;
RenderProgress* renderProgress() const;
@@ -67,6 +69,9 @@ private:
ProgressValueElement* m_value;
};
+NODE_TYPE_CASTS(HTMLProgressElement)
+
} // namespace
#endif
+#endif
diff --git a/Source/WebCore/html/HTMLProgressElement.idl b/Source/WebCore/html/HTMLProgressElement.idl
index eff99788c..fcc657b1a 100644
--- a/Source/WebCore/html/HTMLProgressElement.idl
+++ b/Source/WebCore/html/HTMLProgressElement.idl
@@ -17,10 +17,12 @@
* Boston, MA 02110-1301, USA.
*/
-interface HTMLProgressElement : HTMLElement {
- [SetterRaisesException] attribute unrestricted double value;
- [SetterRaisesException] attribute unrestricted double max;
- readonly attribute unrestricted double position;
+[
+ Conditional=PROGRESS_ELEMENT
+] interface HTMLProgressElement : HTMLElement {
+ [SetterRaisesException] attribute double value;
+ [SetterRaisesException] attribute double max;
+ readonly attribute double position;
readonly attribute NodeList labels;
};
diff --git a/Source/WebCore/html/HTMLQuoteElement.cpp b/Source/WebCore/html/HTMLQuoteElement.cpp
index 8126b8602..96d2d9110 100644
--- a/Source/WebCore/html/HTMLQuoteElement.cpp
+++ b/Source/WebCore/html/HTMLQuoteElement.cpp
@@ -37,9 +37,17 @@ inline HTMLQuoteElement::HTMLQuoteElement(const QualifiedName& tagName, Document
ASSERT(hasTagName(qTag) || hasTagName(blockquoteTag));
}
-Ref<HTMLQuoteElement> HTMLQuoteElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLQuoteElement> HTMLQuoteElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLQuoteElement(tagName, document));
+ return adoptRef(new HTMLQuoteElement(tagName, document));
+}
+
+Node::InsertionNotificationRequest HTMLQuoteElement::insertedInto(ContainerNode& insertionPoint)
+{
+ if (hasTagName(qTag))
+ document().styleSheetCollection().setUsesBeforeAfterRulesOverride(true);
+
+ return HTMLElement::insertedInto(insertionPoint);
}
bool HTMLQuoteElement::isURLAttribute(const Attribute& attribute) const
diff --git a/Source/WebCore/html/HTMLQuoteElement.h b/Source/WebCore/html/HTMLQuoteElement.h
index 67e0295a8..13ff919b4 100644
--- a/Source/WebCore/html/HTMLQuoteElement.h
+++ b/Source/WebCore/html/HTMLQuoteElement.h
@@ -31,11 +31,12 @@ namespace WebCore {
class HTMLQuoteElement final : public HTMLElement {
public:
- static Ref<HTMLQuoteElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLQuoteElement> create(const QualifiedName&, Document&);
private:
HTMLQuoteElement(const QualifiedName&, Document&);
+ virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
virtual bool isURLAttribute(const Attribute&) const override;
};
diff --git a/Source/WebCore/html/HTMLScriptElement.cpp b/Source/WebCore/html/HTMLScriptElement.cpp
index 695114668..b0bdc951c 100644
--- a/Source/WebCore/html/HTMLScriptElement.cpp
+++ b/Source/WebCore/html/HTMLScriptElement.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLScriptElement.h"
+#include "Attribute.h"
#include "Document.h"
#include "Event.h"
#include "EventNames.h"
@@ -36,14 +37,14 @@ using namespace HTMLNames;
inline HTMLScriptElement::HTMLScriptElement(const QualifiedName& tagName, Document& document, bool wasInsertedByParser, bool alreadyStarted)
: HTMLElement(tagName, document)
- , ScriptElement(*this, wasInsertedByParser, alreadyStarted)
+ , ScriptElement(this, wasInsertedByParser, alreadyStarted)
{
ASSERT(hasTagName(scriptTag));
}
-Ref<HTMLScriptElement> HTMLScriptElement::create(const QualifiedName& tagName, Document& document, bool wasInsertedByParser, bool alreadyStarted)
+PassRefPtr<HTMLScriptElement> HTMLScriptElement::create(const QualifiedName& tagName, Document& document, bool wasInsertedByParser, bool alreadyStarted)
{
- return adoptRef(*new HTMLScriptElement(tagName, document, wasInsertedByParser, alreadyStarted));
+ return adoptRef(new HTMLScriptElement(tagName, document, wasInsertedByParser, alreadyStarted));
}
bool HTMLScriptElement::isURLAttribute(const Attribute& attribute) const
@@ -63,6 +64,8 @@ void HTMLScriptElement::parseAttribute(const QualifiedName& name, const AtomicSt
handleSourceAttribute(value);
else if (name == asyncAttr)
handleAsyncAttribute();
+ else if (name == onbeforeloadAttr)
+ setAttributeEventListener(eventNames().beforeloadEvent, name, value);
else
HTMLElement::parseAttribute(name, value);
}
@@ -70,24 +73,22 @@ void HTMLScriptElement::parseAttribute(const QualifiedName& name, const AtomicSt
Node::InsertionNotificationRequest HTMLScriptElement::insertedInto(ContainerNode& insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
- return shouldCallFinishedInsertingSubtree(insertionPoint) ? InsertionShouldCallFinishedInsertingSubtree : InsertionDone;
-}
-
-void HTMLScriptElement::finishedInsertingSubtree()
-{
- ScriptElement::finishedInsertingSubtree();
+ ScriptElement::insertedInto(insertionPoint);
+ return InsertionDone;
}
void HTMLScriptElement::setText(const String &value)
{
Ref<HTMLScriptElement> protectFromMutationEvents(*this);
- if (hasOneChild() && is<Text>(*firstChild())) {
- downcast<Text>(*firstChild()).setData(value, IGNORE_EXCEPTION);
+ int numChildren = childNodeCount();
+
+ if (numChildren == 1 && firstChild()->isTextNode()) {
+ toText(firstChild())->setData(value, IGNORE_EXCEPTION);
return;
}
- if (hasChildNodes())
+ if (numChildren > 0)
removeChildren();
appendChild(document().createTextNode(value.impl()), IGNORE_EXCEPTION);
@@ -118,12 +119,12 @@ void HTMLScriptElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) cons
String HTMLScriptElement::sourceAttributeValue() const
{
- return fastGetAttribute(srcAttr).string();
+ return getAttribute(srcAttr).string();
}
String HTMLScriptElement::charsetAttributeValue() const
{
- return fastGetAttribute(charsetAttr).string();
+ return getAttribute(charsetAttr).string();
}
String HTMLScriptElement::typeAttributeValue() const
@@ -133,17 +134,17 @@ String HTMLScriptElement::typeAttributeValue() const
String HTMLScriptElement::languageAttributeValue() const
{
- return fastGetAttribute(languageAttr).string();
+ return getAttribute(languageAttr).string();
}
String HTMLScriptElement::forAttributeValue() const
{
- return fastGetAttribute(forAttr).string();
+ return getAttribute(forAttr).string();
}
String HTMLScriptElement::eventAttributeValue() const
{
- return fastGetAttribute(eventAttr).string();
+ return getAttribute(eventAttr).string();
}
bool HTMLScriptElement::asyncAttributeValue() const
@@ -169,9 +170,9 @@ void HTMLScriptElement::dispatchLoadEvent()
dispatchEvent(Event::create(eventNames().loadEvent, false, false));
}
-RefPtr<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren(Document& targetDocument)
+PassRefPtr<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren()
{
- return adoptRef(new HTMLScriptElement(tagQName(), targetDocument, false, alreadyStarted()));
+ return adoptRef(new HTMLScriptElement(tagQName(), document(), false, alreadyStarted()));
}
}
diff --git a/Source/WebCore/html/HTMLScriptElement.h b/Source/WebCore/html/HTMLScriptElement.h
index e39c10ca5..b8501b473 100644
--- a/Source/WebCore/html/HTMLScriptElement.h
+++ b/Source/WebCore/html/HTMLScriptElement.h
@@ -31,7 +31,7 @@ namespace WebCore {
class HTMLScriptElement final : public HTMLElement, public ScriptElement {
public:
- static Ref<HTMLScriptElement> create(const QualifiedName&, Document&, bool wasInsertedByParser, bool alreadyStarted = false);
+ static PassRefPtr<HTMLScriptElement> create(const QualifiedName&, Document&, bool wasInsertedByParser, bool alreadyStarted = false);
String text() const { return scriptContent(); }
void setText(const String&);
@@ -46,7 +46,6 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
- virtual void finishedInsertingSubtree() override;
virtual void childrenChanged(const ChildChange&) override;
virtual bool isURLAttribute(const Attribute&) const override;
@@ -65,9 +64,11 @@ private:
virtual void dispatchLoadEvent() override;
- virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren(Document&) override;
+ virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() override;
};
+NODE_TYPE_CASTS(HTMLScriptElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLSelectElement.cpp b/Source/WebCore/html/HTMLSelectElement.cpp
index 10f613f16..2c2eb89a8 100644
--- a/Source/WebCore/html/HTMLSelectElement.cpp
+++ b/Source/WebCore/html/HTMLSelectElement.cpp
@@ -29,6 +29,7 @@
#include "HTMLSelectElement.h"
#include "AXObjectCache.h"
+#include "Attribute.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "ElementTraversal.h"
@@ -79,10 +80,10 @@ HTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document& doc
ASSERT(hasTagName(selectTag));
}
-Ref<HTMLSelectElement> HTMLSelectElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
+PassRefPtr<HTMLSelectElement> HTMLSelectElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
{
ASSERT(tagName.matches(selectTag));
- return adoptRef(*new HTMLSelectElement(tagName, document, form));
+ return adoptRef(new HTMLSelectElement(tagName, document, form));
}
void HTMLSelectElement::didRecalcStyle(Style::Change styleChange)
@@ -95,15 +96,15 @@ void HTMLSelectElement::didRecalcStyle(Style::Change styleChange)
const AtomicString& HTMLSelectElement::formControlType() const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, selectMultiple, ("select-multiple", AtomicString::ConstructFromLiteral));
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, selectOne, ("select-one", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, selectMultiple, ("select-multiple", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, selectOne, ("select-one", AtomicString::ConstructFromLiteral));
return m_multiple ? selectMultiple : selectOne;
}
void HTMLSelectElement::deselectItems(HTMLOptionElement* excludeElement)
{
deselectItemsWithoutValidation(excludeElement);
- updateValidity();
+ setNeedsValidityCheck();
}
void HTMLSelectElement::optionSelectedByUser(int optionIndex, bool fireOnChangeNow, bool allowMultipleSelection)
@@ -112,7 +113,7 @@ void HTMLSelectElement::optionSelectedByUser(int optionIndex, bool fireOnChangeN
// This produces that same behavior for changes triggered by other code running on behalf of the user.
if (!usesMenuList()) {
updateSelectedState(optionToListIndex(optionIndex), allowMultipleSelection, false);
- updateValidity();
+ setNeedsValidityCheck();
if (fireOnChangeNow)
listBoxOnChange();
return;
@@ -148,8 +149,8 @@ bool HTMLSelectElement::hasPlaceholderLabelOption() const
ASSERT(listIndex >= 0);
if (listIndex < 0)
return false;
- HTMLOptionElement& option = downcast<HTMLOptionElement>(*listItems()[listIndex]);
- return !listIndex && option.value().isEmpty();
+ HTMLOptionElement* option = toHTMLOptionElement(listItems()[listIndex]);
+ return !listIndex && option->value().isEmpty();
}
String HTMLSelectElement::validationMessage() const
@@ -183,7 +184,7 @@ void HTMLSelectElement::listBoxSelectItem(int listIndex, bool allowMultiplySelec
optionSelectedByUser(listToOptionIndex(listIndex), fireOnChangeNow, false);
else {
updateSelectedState(listIndex, allowMultiplySelections, shift);
- updateValidity();
+ setNeedsValidityCheck();
if (fireOnChangeNow)
listBoxOnChange();
}
@@ -217,21 +218,16 @@ int HTMLSelectElement::activeSelectionEndListIndex() const
return lastSelectedListIndex();
}
-void HTMLSelectElement::add(HTMLElement* element, HTMLElement* beforeElement, ExceptionCode& ec)
+void HTMLSelectElement::add(HTMLElement* element, HTMLElement* before, ExceptionCode& ec)
{
- if (!element || !(is<HTMLOptionElement>(*element) || element->hasTagName(hrTag) || is<HTMLOptGroupElement>(*element)))
+ if (!element || !(element->hasLocalName(optionTag) || element->hasLocalName(hrTag)))
return;
// Make sure the element is ref'd and deref'd so we don't leak it.
Ref<HTMLElement> protectNewChild(*element);
- insertBefore(element, beforeElement, ec);
- updateValidity();
-}
-
-void HTMLSelectElement::add(HTMLElement* element, int beforeIndex, ExceptionCode& ec)
-{
- add(element, item(beforeIndex), ec);
+ insertBefore(element, before, ec);
+ setNeedsValidityCheck();
}
void HTMLSelectElement::removeByIndex(int optionIndex)
@@ -253,14 +249,15 @@ void HTMLSelectElement::remove(HTMLOptionElement* option)
String HTMLSelectElement::value() const
{
- for (auto* item : listItems()) {
- if (is<HTMLOptionElement>(*item)) {
- HTMLOptionElement& option = downcast<HTMLOptionElement>(*item);
- if (option.selected())
- return option.value();
+ const Vector<HTMLElement*>& items = listItems();
+ for (unsigned i = 0; i < items.size(); i++) {
+ if (items[i]->hasLocalName(optionTag)) {
+ HTMLOptionElement* option = toHTMLOptionElement(items[i]);
+ if (option->selected())
+ return option->value();
}
}
- return emptyString();
+ return "";
}
void HTMLSelectElement::setValue(const String &value)
@@ -272,14 +269,15 @@ void HTMLSelectElement::setValue(const String &value)
}
// Find the option with value() matching the given parameter and make it the current selection.
+ const Vector<HTMLElement*>& items = listItems();
unsigned optionIndex = 0;
- for (auto* item : listItems()) {
- if (is<HTMLOptionElement>(*item)) {
- if (downcast<HTMLOptionElement>(*item).value() == value) {
+ for (unsigned i = 0; i < items.size(); i++) {
+ if (items[i]->hasLocalName(optionTag)) {
+ if (toHTMLOptionElement(items[i])->value() == value) {
setSelectedIndex(optionIndex);
return;
}
- ++optionIndex;
+ optionIndex++;
}
}
@@ -310,14 +308,14 @@ void HTMLSelectElement::parseAttribute(const QualifiedName& name, const AtomicSt
if (Attribute* sizeAttribute = ensureUniqueElementData().findAttributeByName(sizeAttr))
sizeAttribute->setValue(attrSize);
}
- size = std::max(size, 0);
+ size = std::max(size, 1);
// Ensure that we've determined selectedness of the items at least once prior to changing the size.
if (oldSize != size)
updateListItemSelectedStates();
m_size = size;
- updateValidity();
+ setNeedsValidityCheck();
if (m_size != oldSize) {
setNeedsStyleRecalc(ReconstructRenderTree);
setRecalcListItems();
@@ -350,14 +348,14 @@ bool HTMLSelectElement::canSelectAll() const
return !usesMenuList();
}
-RenderPtr<RenderElement> HTMLSelectElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLSelectElement::createElementRenderer(PassRef<RenderStyle> style)
{
#if !PLATFORM(IOS)
if (usesMenuList())
- return createRenderer<RenderMenuList>(*this, WTF::move(style));
- return createRenderer<RenderListBox>(*this, WTF::move(style));
+ return createRenderer<RenderMenuList>(*this, std::move(style));
+ return createRenderer<RenderListBox>(*this, std::move(style));
#else
- return createRenderer<RenderMenuList>(*this, WTF::move(style));
+ return createRenderer<RenderMenuList>(*this, std::move(style));
#endif
}
@@ -367,19 +365,19 @@ bool HTMLSelectElement::childShouldCreateRenderer(const Node& child) const
return false;
#if !PLATFORM(IOS)
if (!usesMenuList())
- return is<HTMLOptionElement>(child) || is<HTMLOptGroupElement>(child) || validationMessageShadowTreeContains(child);
+ return isHTMLOptionElement(child) || isHTMLOptGroupElement(child) || validationMessageShadowTreeContains(child);
#endif
return validationMessageShadowTreeContains(child);
}
-Ref<HTMLCollection> HTMLSelectElement::selectedOptions()
+PassRefPtr<HTMLCollection> HTMLSelectElement::selectedOptions()
{
return ensureCachedHTMLCollection(SelectedOptions);
}
-Ref<HTMLOptionsCollection> HTMLSelectElement::options()
+PassRefPtr<HTMLOptionsCollection> HTMLSelectElement::options()
{
- return downcast<HTMLOptionsCollection>(ensureCachedHTMLCollection(SelectOptions).get());
+ return static_cast<HTMLOptionsCollection*>(ensureCachedHTMLCollection(SelectOptions).get());
}
void HTMLSelectElement::updateListItemSelectedStates()
@@ -391,7 +389,7 @@ void HTMLSelectElement::updateListItemSelectedStates()
void HTMLSelectElement::childrenChanged(const ChildChange& change)
{
setRecalcListItems();
- updateValidity();
+ setNeedsValidityCheck();
m_lastOnChangeSelection.clear();
HTMLFormControlElementWithState::childrenChanged(change);
@@ -400,7 +398,7 @@ void HTMLSelectElement::childrenChanged(const ChildChange& change)
void HTMLSelectElement::optionElementChildrenChanged()
{
setRecalcListItems();
- updateValidity();
+ setNeedsValidityCheck();
if (renderer()) {
if (AXObjectCache* cache = renderer()->document().existingAXObjectCache())
@@ -431,14 +429,14 @@ void HTMLSelectElement::setSize(int size)
setIntegralAttribute(sizeAttr, size);
}
-HTMLOptionElement* HTMLSelectElement::namedItem(const AtomicString& name)
+Node* HTMLSelectElement::namedItem(const AtomicString& name)
{
- return downcast<HTMLOptionElement>(options()->namedItem(name));
+ return options()->namedItem(name);
}
-HTMLOptionElement* HTMLSelectElement::item(unsigned index)
+Node* HTMLSelectElement::item(unsigned index)
{
- return downcast<HTMLOptionElement>(options()->item(index));
+ return options()->item(index);
}
void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, ExceptionCode& ec)
@@ -453,7 +451,7 @@ void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, Exc
setLength(index, ec);
// Replace an existing entry?
} else if (diff < 0) {
- before = downcast<HTMLElement>(options()->item(index + 1));
+ before = toHTMLElement(options()->item(index+1));
removeByIndex(index);
}
// Finally add the new element.
@@ -475,7 +473,7 @@ void HTMLSelectElement::setLength(unsigned newLen, ExceptionCode& ec)
do {
RefPtr<Element> option = document().createElement(optionTag, false);
ASSERT(option);
- add(downcast<HTMLElement>(option.get()), nullptr, ec);
+ add(toHTMLElement(option.get()), 0, ec);
if (ec)
break;
} while (++diff);
@@ -486,19 +484,21 @@ void HTMLSelectElement::setLength(unsigned newLen, ExceptionCode& ec)
// of elements that we intend to remove then attempt to remove them one at a time.
Vector<RefPtr<Element>> itemsToRemove;
size_t optionIndex = 0;
- for (auto& item : items) {
- if (is<HTMLOptionElement>(*item) && optionIndex++ >= newLen) {
+ for (size_t i = 0; i < items.size(); ++i) {
+ Element* item = items[i];
+ if (item->hasLocalName(optionTag) && optionIndex++ >= newLen) {
ASSERT(item->parentNode());
itemsToRemove.append(item);
}
}
- for (auto& item : itemsToRemove) {
+ for (size_t i = 0; i < itemsToRemove.size(); ++i) {
+ Element* item = itemsToRemove[i].get();
if (item->parentNode())
- item->parentNode()->removeChild(item.get(), ec);
+ item->parentNode()->removeChild(item, ec);
}
}
- updateValidity();
+ setNeedsValidityCheck();
}
bool HTMLSelectElement::isRequiredFormControl() const
@@ -525,7 +525,7 @@ int HTMLSelectElement::nextValidIndex(int listIndex, SkipDirection direction, in
int size = listItems.size();
for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex += direction) {
--skip;
- if (!listItems[listIndex]->isDisabledFormControl() && is<HTMLOptionElement>(*listItems[listIndex])) {
+ if (!listItems[listIndex]->isDisabledFormControl() && isHTMLOptionElement(listItems[listIndex])) {
lastGoodIndex = listIndex;
if (skip <= 0)
break;
@@ -566,14 +566,14 @@ int HTMLSelectElement::nextSelectableListIndexPageAway(int startIndex, SkipDirec
const Vector<HTMLElement*>& items = listItems();
// Can't use m_size because renderer forces a minimum size.
int pageSize = 0;
- if (is<RenderListBox>(*renderer()))
- pageSize = downcast<RenderListBox>(*renderer()).size() - 1; // -1 so we still show context.
+ if (renderer()->isListBox())
+ pageSize = toRenderListBox(renderer())->size() - 1; // -1 so we still show context.
// One page away, but not outside valid bounds.
// If there is a valid option item one page away, the index is chosen.
// If there is no exact one page away valid option, returns startIndex or the most far index.
- int edgeIndex = direction == SkipForwards ? 0 : items.size() - 1;
- int skipAmount = pageSize + (direction == SkipForwards ? startIndex : edgeIndex - startIndex);
+ int edgeIndex = (direction == SkipForwards) ? 0 : (items.size() - 1);
+ int skipAmount = pageSize + ((direction == SkipForwards) ? startIndex : (edgeIndex - startIndex));
return nextValidIndex(edgeIndex, direction, skipAmount);
}
@@ -595,7 +595,7 @@ void HTMLSelectElement::selectAll()
updateListBoxSelection(false);
listBoxOnChange();
- updateValidity();
+ setNeedsValidityCheck();
}
void HTMLSelectElement::saveLastSelection()
@@ -609,7 +609,7 @@ void HTMLSelectElement::saveLastSelection()
const Vector<HTMLElement*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- m_lastOnChangeSelection.append(is<HTMLOptionElement>(*element) && downcast<HTMLOptionElement>(*element).selected());
+ m_lastOnChangeSelection.append(isHTMLOptionElement(element) && toHTMLOptionElement(element)->selected());
}
}
@@ -624,7 +624,7 @@ void HTMLSelectElement::setActiveSelectionAnchorIndex(int index)
const Vector<HTMLElement*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- m_cachedStateForActiveSelection.append(is<HTMLOptionElement>(*element) && downcast<HTMLOptionElement>(*element).selected());
+ m_cachedStateForActiveSelection.append(isHTMLOptionElement(element) && toHTMLOptionElement(element)->selected());
}
}
@@ -648,19 +648,20 @@ void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions)
const Vector<HTMLElement*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (!is<HTMLOptionElement>(*element) || downcast<HTMLOptionElement>(*element).isDisabledFormControl())
+ if (!isHTMLOptionElement(element) || toHTMLOptionElement(element)->isDisabledFormControl())
continue;
if (i >= start && i <= end)
- downcast<HTMLOptionElement>(*element).setSelectedState(m_activeSelectionState);
+ toHTMLOptionElement(element)->setSelectedState(m_activeSelectionState);
else if (deselectOtherOptions || i >= m_cachedStateForActiveSelection.size())
- downcast<HTMLOptionElement>(*element).setSelectedState(false);
+ toHTMLOptionElement(element)->setSelectedState(false);
else
- downcast<HTMLOptionElement>(*element).setSelectedState(m_cachedStateForActiveSelection[i]);
+ toHTMLOptionElement(element)->setSelectedState(m_cachedStateForActiveSelection[i]);
}
scrollToSelection();
- updateValidity();
+ setNeedsValidityCheck();
+ notifyFormStateChanged();
}
void HTMLSelectElement::listBoxOnChange()
@@ -680,16 +681,14 @@ void HTMLSelectElement::listBoxOnChange()
bool fireOnChange = false;
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- bool selected = is<HTMLOptionElement>(*element) && downcast<HTMLOptionElement>(*element).selected();
+ bool selected = isHTMLOptionElement(element) && toHTMLOptionElement(element)->selected();
if (selected != m_lastOnChangeSelection[i])
fireOnChange = true;
m_lastOnChangeSelection[i] = selected;
}
- if (fireOnChange) {
- dispatchInputEvent();
+ if (fireOnChange)
dispatchFormControlChangeEvent();
- }
}
void HTMLSelectElement::dispatchChangeEventForMenuList()
@@ -700,7 +699,6 @@ void HTMLSelectElement::dispatchChangeEventForMenuList()
if (m_lastOnChangeIndex != selected && m_isProcessingUserDrivenChange) {
m_lastOnChangeIndex = selected;
m_isProcessingUserDrivenChange = false;
- dispatchInputEvent();
dispatchFormControlChangeEvent();
}
}
@@ -711,26 +709,26 @@ void HTMLSelectElement::scrollToSelection()
if (usesMenuList())
return;
- auto* renderer = this->renderer();
- if (!is<RenderListBox>(renderer))
+ auto renderer = this->renderer();
+ if (!renderer || !renderer->isListBox())
return;
- downcast<RenderListBox>(*renderer).selectionChanged();
+ toRenderListBox(renderer)->selectionChanged();
#else
- if (auto* renderer = this->renderer())
+ if (auto renderer = this->renderer())
renderer->repaint();
#endif
}
void HTMLSelectElement::setOptionsChangedOnRenderer()
{
- if (auto* renderer = this->renderer()) {
+ if (auto renderer = this->renderer()) {
#if !PLATFORM(IOS)
- if (is<RenderMenuList>(*renderer))
- downcast<RenderMenuList>(*renderer).setOptionsChanged(true);
+ if (renderer->isMenuList())
+ toRenderMenuList(renderer)->setOptionsChanged(true);
else
- downcast<RenderListBox>(*renderer).setOptionsChanged(true);
+ toRenderListBox(renderer)->setOptionsChanged(true);
#else
- downcast<RenderMenuList>(*renderer).setOptionsChanged(true);
+ toRenderMenuList(renderer)->setOptionsChanged(true);
#endif
}
}
@@ -753,7 +751,7 @@ const Vector<HTMLElement*>& HTMLSelectElement::listItems() const
void HTMLSelectElement::invalidateSelectedItems()
{
if (HTMLCollection* collection = cachedHTMLCollection(SelectedOptions))
- collection->invalidateCache(document());
+ collection->invalidateCache();
}
void HTMLSelectElement::setRecalcListItems()
@@ -765,7 +763,7 @@ void HTMLSelectElement::setRecalcListItems()
setNeedsStyleRecalc();
if (!inDocument()) {
if (HTMLCollection* collection = cachedHTMLCollection(SelectOptions))
- collection->invalidateCache(document());
+ collection->invalidateCache();
}
if (!inDocument())
invalidateSelectedItems();
@@ -784,44 +782,44 @@ void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
HTMLOptionElement* foundSelected = 0;
HTMLOptionElement* firstOption = 0;
- for (Element* currentElement = ElementTraversal::firstWithin(*this); currentElement; ) {
- if (!is<HTMLElement>(*currentElement)) {
- currentElement = ElementTraversal::nextSkippingChildren(*currentElement, this);
+ for (Element* currentElement = ElementTraversal::firstWithin(this); currentElement; ) {
+ if (!currentElement->isHTMLElement()) {
+ currentElement = ElementTraversal::nextSkippingChildren(currentElement, this);
continue;
}
- HTMLElement& current = downcast<HTMLElement>(*currentElement);
+ HTMLElement* current = toHTMLElement(currentElement);
// optgroup tags may not nest. However, both FireFox and IE will
// flatten the tree automatically, so we follow suit.
// (http://www.w3.org/TR/html401/interact/forms.html#h-17.6)
- if (is<HTMLOptGroupElement>(current)) {
- m_listItems.append(&current);
+ if (isHTMLOptGroupElement(current)) {
+ m_listItems.append(current);
if (Element* nextElement = ElementTraversal::firstWithin(current)) {
currentElement = nextElement;
continue;
}
}
- if (is<HTMLOptionElement>(current)) {
- m_listItems.append(&current);
+ if (isHTMLOptionElement(current)) {
+ m_listItems.append(current);
if (updateSelectedStates && !m_multiple) {
- HTMLOptionElement& option = downcast<HTMLOptionElement>(current);
+ HTMLOptionElement* option = toHTMLOptionElement(current);
if (!firstOption)
- firstOption = &option;
- if (option.selected()) {
+ firstOption = option;
+ if (option->selected()) {
if (foundSelected)
foundSelected->setSelectedState(false);
- foundSelected = &option;
- } else if (m_size <= 1 && !foundSelected && !option.isDisabledFormControl()) {
- foundSelected = &option;
+ foundSelected = option;
+ } else if (m_size <= 1 && !foundSelected && !option->isDisabledFormControl()) {
+ foundSelected = option;
foundSelected->setSelectedState(true);
}
}
}
- if (current.hasTagName(hrTag))
- m_listItems.append(&current);
+ if (current->hasTagName(hrTag))
+ m_listItems.append(current);
// In conforming HTML code, only <optgroup> and <option> will be found
// within a <select>. We call NodeTraversal::nextSkippingChildren so that we only step
@@ -829,7 +827,7 @@ void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
// with the case where odd tags like a <div> have been added but we
// handle this because such tags have already been removed from the
// <select>'s subtree at this point.
- currentElement = ElementTraversal::nextSkippingChildren(*currentElement, this);
+ currentElement = ElementTraversal::nextSkippingChildren(currentElement, this);
}
if (!foundSelected && m_size <= 1 && firstOption && !firstOption->selected())
@@ -844,8 +842,8 @@ int HTMLSelectElement::selectedIndex() const
const Vector<HTMLElement*>& items = listItems();
for (size_t i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (is<HTMLOptionElement>(*element)) {
- if (downcast<HTMLOptionElement>(*element).selected())
+ if (isHTMLOptionElement(element)) {
+ if (toHTMLOptionElement(element)->selected())
return index;
++index;
}
@@ -877,40 +875,41 @@ void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags)
const Vector<HTMLElement*>& items = listItems();
int listIndex = optionToListIndex(optionIndex);
- HTMLElement* element = nullptr;
+ HTMLElement* element = 0;
if (listIndex >= 0) {
element = items[listIndex];
+ if (isHTMLOptionElement(element)) {
+ if (m_activeSelectionAnchorIndex < 0 || shouldDeselect)
+ setActiveSelectionAnchorIndex(listIndex);
+ if (m_activeSelectionEndIndex < 0 || shouldDeselect)
+ setActiveSelectionEndIndex(listIndex);
+ toHTMLOptionElement(element)->setSelectedState(true);
+ }
}
if (shouldDeselect)
deselectItemsWithoutValidation(element);
- if (is<HTMLOptionElement>(element)) {
- if (m_activeSelectionAnchorIndex < 0 || shouldDeselect)
- setActiveSelectionAnchorIndex(listIndex);
- if (m_activeSelectionEndIndex < 0 || shouldDeselect)
- setActiveSelectionEndIndex(listIndex);
- downcast<HTMLOptionElement>(*element).setSelectedState(true);
- }
-
// For the menu list case, this is what makes the selected element appear.
- if (auto* renderer = this->renderer())
+ if (auto renderer = this->renderer())
renderer->updateFromElement();
scrollToSelection();
- updateValidity();
if (usesMenuList()) {
m_isProcessingUserDrivenChange = flags & UserDriven;
if (flags & DispatchChangeEvent)
dispatchChangeEventForMenuList();
- if (auto* renderer = this->renderer()) {
- if (is<RenderMenuList>(*renderer))
- downcast<RenderMenuList>(*renderer).didSetSelectedIndex(listIndex);
+ if (auto renderer = this->renderer()) {
+ if (renderer->isMenuList())
+ toRenderMenuList(renderer)->didSetSelectedIndex(listIndex);
else
- downcast<RenderListBox>(*renderer).selectionChanged();
+ toRenderListBox(renderer)->selectionChanged();
}
}
+
+ setNeedsValidityCheck();
+ notifyFormStateChanged();
}
int HTMLSelectElement::optionToListIndex(int optionIndex) const
@@ -922,7 +921,7 @@ int HTMLSelectElement::optionToListIndex(int optionIndex) const
int optionIndex2 = -1;
for (int listIndex = 0; listIndex < listSize; ++listIndex) {
- if (is<HTMLOptionElement>(*items[listIndex])) {
+ if (isHTMLOptionElement(items[listIndex])) {
++optionIndex2;
if (optionIndex2 == optionIndex)
return listIndex;
@@ -935,36 +934,36 @@ int HTMLSelectElement::optionToListIndex(int optionIndex) const
int HTMLSelectElement::listToOptionIndex(int listIndex) const
{
const Vector<HTMLElement*>& items = listItems();
- if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !is<HTMLOptionElement>(*items[listIndex]))
+ if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !isHTMLOptionElement(items[listIndex]))
return -1;
// Actual index of option not counting OPTGROUP entries that may be in list.
int optionIndex = 0;
for (int i = 0; i < listIndex; ++i) {
- if (is<HTMLOptionElement>(*items[i]))
+ if (isHTMLOptionElement(items[i]))
++optionIndex;
}
return optionIndex;
}
-void HTMLSelectElement::dispatchFocusEvent(RefPtr<Element>&& oldFocusedElement, FocusDirection direction)
+void HTMLSelectElement::dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection direction)
{
// Save the selection so it can be compared to the new selection when
// dispatching change events during blur event dispatch.
if (usesMenuList())
saveLastSelection();
- HTMLFormControlElementWithState::dispatchFocusEvent(WTF::move(oldFocusedElement), direction);
+ HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, direction);
}
-void HTMLSelectElement::dispatchBlurEvent(RefPtr<Element>&& newFocusedElement)
+void HTMLSelectElement::dispatchBlurEvent(PassRefPtr<Element> newFocusedElement)
{
// We only need to fire change events here for menu lists, because we fire
// change events for list boxes whenever the selection change is actually made.
// This matches other browsers' behavior.
if (usesMenuList())
dispatchChangeEventForMenuList();
- HTMLFormControlElementWithState::dispatchBlurEvent(WTF::move(newFocusedElement));
+ HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement);
}
void HTMLSelectElement::deselectItemsWithoutValidation(HTMLElement* excludeElement)
@@ -972,8 +971,8 @@ void HTMLSelectElement::deselectItemsWithoutValidation(HTMLElement* excludeEleme
const Vector<HTMLElement*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (element != excludeElement && is<HTMLOptionElement>(*element))
- downcast<HTMLOptionElement>(*element).setSelectedState(false);
+ if (element != excludeElement && isHTMLOptionElement(element))
+ toHTMLOptionElement(element)->setSelectedState(false);
}
}
@@ -983,12 +982,12 @@ FormControlState HTMLSelectElement::saveFormControlState() const
size_t length = items.size();
FormControlState state;
for (unsigned i = 0; i < length; ++i) {
- if (!is<HTMLOptionElement>(*items[i]))
+ if (!isHTMLOptionElement(items[i]))
continue;
- HTMLOptionElement& option = downcast<HTMLOptionElement>(*items[i]);
- if (!option.selected())
+ HTMLOptionElement* option = toHTMLOptionElement(items[i]);
+ if (!option->selected())
continue;
- state.append(option.value());
+ state.append(option->value());
if (!multiple())
break;
}
@@ -1000,9 +999,9 @@ size_t HTMLSelectElement::searchOptionsForValue(const String& value, size_t list
const Vector<HTMLElement*>& items = listItems();
size_t loopEndIndex = std::min(items.size(), listIndexEnd);
for (size_t i = listIndexStart; i < loopEndIndex; ++i) {
- if (!is<HTMLOptionElement>(*items[i]))
+ if (!items[i]->hasLocalName(optionTag))
continue;
- if (downcast<HTMLOptionElement>(*items[i]).value() == value)
+ if (toHTMLOptionElement(items[i])->value() == value)
return i;
}
return notFound;
@@ -1018,15 +1017,15 @@ void HTMLSelectElement::restoreFormControlState(const FormControlState& state)
return;
for (size_t i = 0; i < itemsSize; ++i) {
- if (!is<HTMLOptionElement>(*items[i]))
+ if (!items[i]->hasLocalName(optionTag))
continue;
- downcast<HTMLOptionElement>(*items[i]).setSelectedState(false);
+ toHTMLOptionElement(items[i])->setSelectedState(false);
}
if (!multiple()) {
size_t foundIndex = searchOptionsForValue(state[0], 0, itemsSize);
if (foundIndex != notFound)
- downcast<HTMLOptionElement>(*items[foundIndex]).setSelectedState(true);
+ toHTMLOptionElement(items[foundIndex])->setSelectedState(true);
} else {
size_t startIndex = 0;
for (size_t i = 0; i < state.valueSize(); ++i) {
@@ -1036,20 +1035,20 @@ void HTMLSelectElement::restoreFormControlState(const FormControlState& state)
foundIndex = searchOptionsForValue(value, 0, startIndex);
if (foundIndex == notFound)
continue;
- downcast<HTMLOptionElement>(*items[foundIndex]).setSelectedState(true);
+ toHTMLOptionElement(items[foundIndex])->setSelectedState(true);
startIndex = foundIndex + 1;
}
}
setOptionsChangedOnRenderer();
- updateValidity();
+ setNeedsValidityCheck();
}
void HTMLSelectElement::parseMultipleAttribute(const AtomicString& value)
{
bool oldUsesMenuList = usesMenuList();
m_multiple = !value.isNull();
- updateValidity();
+ setNeedsValidityCheck();
if (oldUsesMenuList != usesMenuList())
setNeedsStyleRecalc(ReconstructRenderTree);
}
@@ -1065,8 +1064,8 @@ bool HTMLSelectElement::appendFormData(FormDataList& list, bool)
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (is<HTMLOptionElement>(*element) && downcast<HTMLOptionElement>(*element).selected() && !downcast<HTMLOptionElement>(*element).isDisabledFormControl()) {
- list.appendData(name, downcast<HTMLOptionElement>(*element).value());
+ if (isHTMLOptionElement(element) && toHTMLOptionElement(element)->selected() && !toHTMLOptionElement(element)->isDisabledFormControl()) {
+ list.appendData(name, toHTMLOptionElement(element)->value());
successful = true;
}
}
@@ -1079,26 +1078,25 @@ bool HTMLSelectElement::appendFormData(FormDataList& list, bool)
void HTMLSelectElement::reset()
{
- HTMLOptionElement* firstOption = nullptr;
- HTMLOptionElement* selectedOption = nullptr;
+ HTMLOptionElement* firstOption = 0;
+ HTMLOptionElement* selectedOption = 0;
const Vector<HTMLElement*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (!is<HTMLOptionElement>(*element))
+ if (!isHTMLOptionElement(element))
continue;
- HTMLOptionElement& option = downcast<HTMLOptionElement>(*element);
- if (option.fastHasAttribute(selectedAttr)) {
+ if (items[i]->fastHasAttribute(selectedAttr)) {
if (selectedOption && !m_multiple)
selectedOption->setSelectedState(false);
- option.setSelectedState(true);
- selectedOption = &option;
+ toHTMLOptionElement(element)->setSelectedState(true);
+ selectedOption = toHTMLOptionElement(element);
} else
- option.setSelectedState(false);
+ toHTMLOptionElement(element)->setSelectedState(false);
if (!firstOption)
- firstOption = &option;
+ firstOption = toHTMLOptionElement(element);
}
if (!selectedOption && firstOption && !m_multiple && m_size <= 1)
@@ -1106,7 +1104,7 @@ void HTMLSelectElement::reset()
setOptionsChangedOnRenderer();
setNeedsStyleRecalc();
- updateValidity();
+ setNeedsValidityCheck();
}
#if !PLATFORM(WIN)
@@ -1124,7 +1122,7 @@ bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event)
// Calling focus() may cause us to lose our renderer. Return true so
// that our caller doesn't process the event further, but don't set
// the event as handled.
- if (!is<RenderMenuList>(renderer()))
+ if (!renderer() || !renderer()->isMenuList())
return true;
// Save the selection so it can be compared to the new selection
@@ -1132,7 +1130,7 @@ bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event)
// gets called from RenderMenuList::valueChanged, which gets called
// after the user makes a selection from the menu.
saveLastSelection();
- downcast<RenderMenuList>(*renderer()).showPopup();
+ toRenderMenuList(renderer())->showPopup();
event->setDefaultHandled();
}
return true;
@@ -1150,11 +1148,10 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
RefPtr<RenderTheme> renderTheme = page ? &page->theme() : RenderTheme::defaultTheme();
if (event->type() == eventNames().keydownEvent) {
- if (!is<KeyboardEvent>(*event))
+ if (!event->isKeyboardEvent())
return;
- KeyboardEvent& keyboardEvent = downcast<KeyboardEvent>(*event);
- if (platformHandleKeydownEvent(&keyboardEvent))
+ if (platformHandleKeydownEvent(static_cast<KeyboardEvent*>(event)))
return;
// When using spatial navigation, we want to be able to navigate away
@@ -1165,7 +1162,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
return;
}
- const String& keyIdentifier = keyboardEvent.keyIdentifier();
+ const String& keyIdentifier = static_cast<KeyboardEvent*>(event)->keyIdentifier();
bool handled = true;
const Vector<HTMLElement*>& listItems = this->listItems();
int listIndex = optionToListIndex(selectedIndex());
@@ -1197,23 +1194,22 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | DispatchChangeEvent | UserDriven);
if (handled)
- keyboardEvent.setDefaultHandled();
+ event->setDefaultHandled();
}
// Use key press event here since sending simulated mouse events
// on key down blocks the proper sending of the key press event.
if (event->type() == eventNames().keypressEvent) {
- if (!is<KeyboardEvent>(*event))
+ if (!event->isKeyboardEvent())
return;
- KeyboardEvent& keyboardEvent = downcast<KeyboardEvent>(*event);
- int keyCode = keyboardEvent.keyCode();
+ int keyCode = static_cast<KeyboardEvent*>(event)->keyCode();
bool handled = false;
if (keyCode == ' ' && isSpatialNavigationEnabled(document().frame())) {
// Use space to toggle arrow key handling for selection change or spatial navigation.
m_activeSelectionState = !m_activeSelectionState;
- keyboardEvent.setDefaultHandled();
+ event->setDefaultHandled();
return;
}
@@ -1223,7 +1219,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
// Calling focus() may remove the renderer or change the
// renderer type.
- if (!is<RenderMenuList>(renderer()))
+ if (!renderer() || !renderer()->isMenuList())
return;
// Save the selection so it can be compared to the new selection
@@ -1231,7 +1227,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
// gets called from RenderMenuList::valueChanged, which gets called
// after the user makes a selection from the menu.
saveLastSelection();
- downcast<RenderMenuList>(*renderer()).showPopup();
+ toRenderMenuList(renderer())->showPopup();
handled = true;
}
} else if (renderTheme->popsMenuByArrowKeys()) {
@@ -1240,7 +1236,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
// Calling focus() may remove the renderer or change the
// renderer type.
- if (!is<RenderMenuList>(renderer()))
+ if (!renderer() || !renderer()->isMenuList())
return;
// Save the selection so it can be compared to the new selection
@@ -1248,33 +1244,36 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
// gets called from RenderMenuList::valueChanged, which gets called
// after the user makes a selection from the menu.
saveLastSelection();
- downcast<RenderMenuList>(*renderer()).showPopup();
+ toRenderMenuList(renderer())->showPopup();
handled = true;
} else if (keyCode == '\r') {
if (form())
- form()->submitImplicitly(&keyboardEvent, false);
+ form()->submitImplicitly(event, false);
dispatchChangeEventForMenuList();
handled = true;
}
}
if (handled)
- keyboardEvent.setDefaultHandled();
+ event->setDefaultHandled();
}
- if (event->type() == eventNames().mousedownEvent && is<MouseEvent>(*event) && downcast<MouseEvent>(*event).button() == LeftButton) {
+ if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
focus();
#if !PLATFORM(IOS)
- if (is<RenderMenuList>(renderer())) {
- auto& menuList = downcast<RenderMenuList>(*renderer());
- ASSERT(!menuList.popupIsVisible());
- // Save the selection so it can be compared to the new
- // selection when we call onChange during selectOption,
- // which gets called from RenderMenuList::valueChanged,
- // which gets called after the user makes a selection from
- // the menu.
- saveLastSelection();
- menuList.showPopup();
+ if (renderer() && renderer()->isMenuList()) {
+ auto& menuList = toRenderMenuList(*renderer());
+ if (menuList.popupIsVisible())
+ menuList.hidePopup();
+ else {
+ // Save the selection so it can be compared to the new
+ // selection when we call onChange during selectOption,
+ // which gets called from RenderMenuList::valueChanged,
+ // which gets called after the user makes a selection from
+ // the menu.
+ saveLastSelection();
+ menuList.showPopup();
+ }
}
#endif
event->setDefaultHandled();
@@ -1282,7 +1281,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
#if !PLATFORM(IOS)
if (event->type() == eventNames().blurEvent && !focused()) {
- auto& menuList = downcast<RenderMenuList>(*renderer());
+ auto& menuList = toRenderMenuList(*renderer());
if (menuList.popupIsVisible())
menuList.hidePopup();
}
@@ -1303,13 +1302,13 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
bool multiSelect = m_multiple && multi && !shift;
HTMLElement* clickedElement = listItems()[listIndex];
- if (is<HTMLOptionElement>(*clickedElement)) {
+ if (isHTMLOptionElement(clickedElement)) {
// Keep track of whether an active selection (like during drag
// selection), should select or deselect.
- if (downcast<HTMLOptionElement>(*clickedElement).selected() && multiSelect)
+ if (toHTMLOptionElement(clickedElement)->selected() && multiSelect)
m_activeSelectionState = false;
if (!m_activeSelectionState)
- downcast<HTMLOptionElement>(*clickedElement).setSelectedState(false);
+ toHTMLOptionElement(clickedElement)->setSelectedState(false);
}
// If we're not in any special multiple selection mode, then deselect all
@@ -1324,8 +1323,8 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
setActiveSelectionAnchorIndex(selectedIndex());
// Set the selection state of the clicked option.
- if (is<HTMLOptionElement>(*clickedElement) && !downcast<HTMLOptionElement>(*clickedElement).isDisabledFormControl())
- downcast<HTMLOptionElement>(*clickedElement).setSelectedState(true);
+ if (isHTMLOptionElement(clickedElement) && !toHTMLOptionElement(clickedElement)->isDisabledFormControl())
+ toHTMLOptionElement(clickedElement)->setSelectedState(true);
// If there was no selectedIndex() for the previous initialization, or If
// we're doing a single selection, or a multiple selection (using cmd or
@@ -1342,36 +1341,36 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
{
const Vector<HTMLElement*>& listItems = this->listItems();
- if (event->type() == eventNames().mousedownEvent && is<MouseEvent>(*event) && downcast<MouseEvent>(*event).button() == LeftButton) {
+ if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
focus();
// Calling focus() may remove or change our renderer, in which case we don't want to handle the event further.
- if (!is<RenderListBox>(renderer()))
+ if (!renderer() || !renderer()->isListBox())
return;
// Convert to coords relative to the list box if needed.
- MouseEvent& mouseEvent = downcast<MouseEvent>(*event);
- IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouseEvent.absoluteLocation(), UseTransforms));
- int listIndex = downcast<RenderListBox>(*renderer()).listIndexAtOffset(toIntSize(localOffset));
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouseEvent->absoluteLocation(), UseTransforms));
+ int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize(localOffset));
if (listIndex >= 0) {
if (!isDisabledFormControl()) {
-#if PLATFORM(COCOA)
- updateSelectedState(listIndex, mouseEvent.metaKey(), mouseEvent.shiftKey());
+#if PLATFORM(MAC)
+ updateSelectedState(listIndex, mouseEvent->metaKey(), mouseEvent->shiftKey());
#else
- updateSelectedState(listIndex, mouseEvent.ctrlKey(), mouseEvent.shiftKey());
+ updateSelectedState(listIndex, mouseEvent->ctrlKey(), mouseEvent->shiftKey());
#endif
}
if (Frame* frame = document().frame())
frame->eventHandler().setMouseDownMayStartAutoscroll();
- mouseEvent.setDefaultHandled();
+ event->setDefaultHandled();
}
- } else if (event->type() == eventNames().mousemoveEvent && is<MouseEvent>(*event) && !downcast<RenderBox>(*renderer()).canBeScrolledAndHasScrollableArea()) {
- MouseEvent& mouseEvent = downcast<MouseEvent>(*event);
- if (mouseEvent.button() != LeftButton || !mouseEvent.buttonDown())
+ } else if (event->type() == eventNames().mousemoveEvent && event->isMouseEvent() && !toRenderBox(renderer())->canBeScrolledAndHasScrollableArea()) {
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ if (mouseEvent->button() != LeftButton || !mouseEvent->buttonDown())
return;
- IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouseEvent.absoluteLocation(), UseTransforms));
- int listIndex = downcast<RenderListBox>(*renderer()).listIndexAtOffset(toIntSize(localOffset));
+ IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouseEvent->absoluteLocation(), UseTransforms));
+ int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize(localOffset));
if (listIndex >= 0) {
if (!isDisabledFormControl()) {
if (m_multiple) {
@@ -1387,9 +1386,9 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
updateListBoxSelection(true);
}
}
- mouseEvent.setDefaultHandled();
+ event->setDefaultHandled();
}
- } else if (event->type() == eventNames().mouseupEvent && is<MouseEvent>(*event) && downcast<MouseEvent>(*event).button() == LeftButton && document().frame()->eventHandler().autoscrollRenderer() != renderer()) {
+ } else if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton && document().frame()->eventHandler().autoscrollRenderer() != renderer()) {
// This click or drag event was not over any of the options.
if (m_lastOnChangeSelection.isEmpty())
return;
@@ -1398,11 +1397,9 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
// timer stops.
listBoxOnChange();
} else if (event->type() == eventNames().keydownEvent) {
- if (!is<KeyboardEvent>(*event))
+ if (!event->isKeyboardEvent())
return;
-
- KeyboardEvent& keyboardEvent = downcast<KeyboardEvent>(*event);
- const String& keyIdentifier = keyboardEvent.keyIdentifier();
+ const String& keyIdentifier = static_cast<KeyboardEvent*>(event)->keyIdentifier();
bool handled = false;
int endIndex = 0;
@@ -1461,52 +1458,51 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
ASSERT_UNUSED(listItems, !listItems.size() || static_cast<size_t>(endIndex) < listItems.size());
setActiveSelectionEndIndex(endIndex);
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
m_allowsNonContiguousSelection = m_multiple && isSpatialNavigationEnabled(document().frame());
#else
- m_allowsNonContiguousSelection = m_multiple && (isSpatialNavigationEnabled(document().frame()) || keyboardEvent.ctrlKey());
+ m_allowsNonContiguousSelection = m_multiple && (isSpatialNavigationEnabled(document().frame()) || static_cast<KeyboardEvent*>(event)->ctrlKey());
#endif
- bool selectNewItem = keyboardEvent.shiftKey() || !m_allowsNonContiguousSelection;
+ bool selectNewItem = static_cast<KeyboardEvent*>(event)->shiftKey() || !m_allowsNonContiguousSelection;
if (selectNewItem)
m_activeSelectionState = true;
// If the anchor is unitialized, or if we're going to deselect all
// other options, then set the anchor index equal to the end index.
- bool deselectOthers = !m_multiple || (!keyboardEvent.shiftKey() && selectNewItem);
+ bool deselectOthers = !m_multiple || (!static_cast<KeyboardEvent*>(event)->shiftKey() && selectNewItem);
if (m_activeSelectionAnchorIndex < 0 || deselectOthers) {
if (deselectOthers)
deselectItemsWithoutValidation();
setActiveSelectionAnchorIndex(m_activeSelectionEndIndex);
}
- downcast<RenderListBox>(*renderer()).scrollToRevealElementAtListIndex(endIndex);
+ toRenderListBox(renderer())->scrollToRevealElementAtListIndex(endIndex);
if (selectNewItem) {
updateListBoxSelection(deselectOthers);
listBoxOnChange();
} else
scrollToSelection();
- keyboardEvent.setDefaultHandled();
+ event->setDefaultHandled();
}
} else if (event->type() == eventNames().keypressEvent) {
- if (!is<KeyboardEvent>(*event))
+ if (!event->isKeyboardEvent())
return;
- KeyboardEvent& keyboardEvent = downcast<KeyboardEvent>(*event);
- int keyCode = keyboardEvent.keyCode();
+ int keyCode = static_cast<KeyboardEvent*>(event)->keyCode();
if (keyCode == '\r') {
if (form())
- form()->submitImplicitly(&keyboardEvent, false);
- keyboardEvent.setDefaultHandled();
+ form()->submitImplicitly(event, false);
+ event->setDefaultHandled();
} else if (m_multiple && keyCode == ' ' && m_allowsNonContiguousSelection) {
// Use space to toggle selection change.
m_activeSelectionState = !m_activeSelectionState;
- ASSERT(m_activeSelectionEndIndex >= 0);
- ASSERT(m_activeSelectionEndIndex < static_cast<int>(listItems.size()));
- ASSERT(is<HTMLOptionElement>(*listItems[m_activeSelectionEndIndex]));
+ ASSERT(m_activeSelectionEndIndex >= 0
+ && m_activeSelectionEndIndex < static_cast<int>(listItems.size())
+ && listItems[m_activeSelectionEndIndex]->hasTagName(optionTag));
updateSelectedState(m_activeSelectionEndIndex, true /*multi*/, false /*shift*/);
listBoxOnChange();
- keyboardEvent.setDefaultHandled();
+ event->setDefaultHandled();
}
}
}
@@ -1532,9 +1528,9 @@ void HTMLSelectElement::defaultEventHandler(Event* event)
if (event->defaultHandled())
return;
- if (event->type() == eventNames().keypressEvent && is<KeyboardEvent>(*event)) {
- KeyboardEvent& keyboardEvent = downcast<KeyboardEvent>(*event);
- if (!keyboardEvent.ctrlKey() && !keyboardEvent.altKey() && !keyboardEvent.metaKey() && u_isprint(keyboardEvent.charCode())) {
+ if (event->type() == eventNames().keypressEvent && event->isKeyboardEvent()) {
+ KeyboardEvent* keyboardEvent = static_cast<KeyboardEvent*>(event);
+ if (!keyboardEvent->ctrlKey() && !keyboardEvent->altKey() && !keyboardEvent->metaKey() && u_isprint(keyboardEvent->charCode())) {
typeAheadFind(keyboardEvent);
event->setDefaultHandled();
return;
@@ -1548,7 +1544,7 @@ int HTMLSelectElement::lastSelectedListIndex() const
const Vector<HTMLElement*>& items = listItems();
for (size_t i = items.size(); i;) {
HTMLElement* element = items[--i];
- if (is<HTMLOptionElement>(*element) && downcast<HTMLOptionElement>(*element).selected())
+ if (isHTMLOptionElement(element) && toHTMLOptionElement(element)->selected())
return i;
}
return -1;
@@ -1569,14 +1565,14 @@ String HTMLSelectElement::optionAtIndex(int index) const
const Vector<HTMLElement*>& items = listItems();
HTMLElement* element = items[index];
- if (!is<HTMLOptionElement>(*element) || downcast<HTMLOptionElement>(*element).isDisabledFormControl())
+ if (!isHTMLOptionElement(element) || toHTMLOptionElement(element)->isDisabledFormControl())
return String();
- return downcast<HTMLOptionElement>(*element).textIndentedToRespectGroupLabel();
+ return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
}
-void HTMLSelectElement::typeAheadFind(KeyboardEvent& event)
+void HTMLSelectElement::typeAheadFind(KeyboardEvent* event)
{
- int index = m_typeAhead.handleEvent(&event, TypeAhead::MatchPrefix | TypeAhead::CycleFirstChar);
+ int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhead::CycleFirstChar);
if (index < 0)
return;
selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchChangeEvent | UserDriven);
@@ -1590,7 +1586,8 @@ Node::InsertionNotificationRequest HTMLSelectElement::insertedInto(ContainerNode
// items yet - but for innerHTML and related methods, this method is called
// after the whole subtree is constructed.
recalcListItems();
- return HTMLFormControlElementWithState::insertedInto(insertionPoint);
+ HTMLFormControlElementWithState::insertedInto(insertionPoint);
+ return InsertionDone;
}
void HTMLSelectElement::accessKeySetSelectedIndex(int index)
@@ -1604,9 +1601,9 @@ void HTMLSelectElement::accessKeySetSelectedIndex(int index)
int listIndex = optionToListIndex(index);
if (listIndex >= 0) {
HTMLElement* element = items[listIndex];
- if (is<HTMLOptionElement>(*element)) {
- if (downcast<HTMLOptionElement>(*element).selected())
- downcast<HTMLOptionElement>(*element).setSelectedState(false);
+ if (isHTMLOptionElement(element)) {
+ if (toHTMLOptionElement(element)->selected())
+ toHTMLOptionElement(element)->setSelectedState(false);
else
selectOption(index, DispatchChangeEvent | UserDriven);
}
@@ -1626,7 +1623,7 @@ unsigned HTMLSelectElement::length() const
const Vector<HTMLElement*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
- if (is<HTMLOptionElement>(*items[i]))
+ if (isHTMLOptionElement(items[i]))
++options;
}
diff --git a/Source/WebCore/html/HTMLSelectElement.h b/Source/WebCore/html/HTMLSelectElement.h
index a155df0ab..d39610274 100644
--- a/Source/WebCore/html/HTMLSelectElement.h
+++ b/Source/WebCore/html/HTMLSelectElement.h
@@ -28,22 +28,22 @@
#include "Event.h"
#include "HTMLFormControlElementWithState.h"
-#include "HTMLOptionElement.h"
#include "TypeAhead.h"
#include <wtf/Vector.h>
namespace WebCore {
+class HTMLOptionElement;
class HTMLOptionsCollection;
class HTMLSelectElement : public HTMLFormControlElementWithState, public TypeAheadDataSource {
public:
- static Ref<HTMLSelectElement> create(const QualifiedName&, Document&, HTMLFormElement*);
+ static PassRefPtr<HTMLSelectElement> create(const QualifiedName&, Document&, HTMLFormElement*);
- WEBCORE_EXPORT int selectedIndex() const;
+ int selectedIndex() const;
void setSelectedIndex(int);
- WEBCORE_EXPORT void optionSelectedByUser(int index, bool dispatchChangeEvent, bool allowMultipleSelection = false);
+ void optionSelectedByUser(int index, bool dispatchChangeEvent, bool allowMultipleSelection = false);
// For ValidityState
virtual String validationMessage() const override;
@@ -57,18 +57,17 @@ public:
bool usesMenuList() const;
void add(HTMLElement*, HTMLElement* beforeElement, ExceptionCode&);
- void add(HTMLElement*, int beforeIndex, ExceptionCode&);
using Node::remove;
// Should be remove(int) but it conflicts with Node::remove(ExceptionCode&).
void removeByIndex(int);
void remove(HTMLOptionElement*);
- WEBCORE_EXPORT String value() const;
+ String value() const;
void setValue(const String&);
- Ref<HTMLOptionsCollection> options();
- Ref<HTMLCollection> selectedOptions();
+ PassRefPtr<HTMLOptionsCollection> options();
+ PassRefPtr<HTMLCollection> selectedOptions();
void optionElementChildrenChanged();
@@ -76,7 +75,7 @@ public:
void invalidateSelectedItems();
void updateListItemSelectedStates();
- WEBCORE_EXPORT const Vector<HTMLElement*>& listItems() const;
+ const Vector<HTMLElement*>& listItems() const;
virtual void accessKeyAction(bool sendMouseEvents) override;
void accessKeySetSelectedIndex(int);
@@ -88,8 +87,8 @@ public:
void setOption(unsigned index, HTMLOptionElement*, ExceptionCode&);
void setLength(unsigned, ExceptionCode&);
- HTMLOptionElement* namedItem(const AtomicString& name);
- HTMLOptionElement* item(unsigned index);
+ Node* namedItem(const AtomicString& name);
+ Node* item(unsigned index);
void scrollToSelection();
@@ -123,8 +122,8 @@ private:
virtual bool isKeyboardFocusable(KeyboardEvent*) const override;
virtual bool isMouseFocusable() const override;
- virtual void dispatchFocusEvent(RefPtr<Element>&& oldFocusedElement, FocusDirection) override final;
- virtual void dispatchBlurEvent(RefPtr<Element>&& newFocusedElement) override final;
+ virtual void dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection) override final;
+ virtual void dispatchBlurEvent(PassRefPtr<Element> newFocusedElement) override final;
virtual bool canStartSelection() const override { return false; }
@@ -138,7 +137,7 @@ private:
virtual bool isPresentationAttribute(const QualifiedName&) const override;
virtual bool childShouldCreateRenderer(const Node&) const override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual bool appendFormData(FormDataList&, bool) override;
virtual void reset() override;
@@ -152,7 +151,7 @@ private:
void recalcListItems(bool updateSelectedStates = true) const;
void deselectItems(HTMLOptionElement* excludeElement = 0);
- void typeAheadFind(KeyboardEvent&);
+ void typeAheadFind(KeyboardEvent*);
void saveLastSelection();
virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
@@ -191,6 +190,7 @@ private:
int nextSelectableListIndexPageAway(int startIndex, SkipDirection) const;
virtual void childrenChanged(const ChildChange&) override;
+ virtual bool areAuthorShadowsAllowed() const override { return false; }
// TypeAheadDataSource functions.
virtual int indexOfSelectedOption() const override;
@@ -213,6 +213,8 @@ private:
mutable bool m_shouldRecalcListItems;
};
+NODE_TYPE_CASTS(HTMLSelectElement)
+
} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLSelectElement.idl b/Source/WebCore/html/HTMLSelectElement.idl
index bacc656ca..92a96a3a2 100644
--- a/Source/WebCore/html/HTMLSelectElement.idl
+++ b/Source/WebCore/html/HTMLSelectElement.idl
@@ -41,9 +41,9 @@
#endif
getter Node item(unsigned long index);
Node namedItem([Default=Undefined] optional DOMString name);
- [ObjCLegacyUnnamedParameters, RaisesException] void add(HTMLElement element, [Default=Undefined] optional HTMLElement? before);
+ [ObjCLegacyUnnamedParameters, RaisesException] void add([Default=Undefined] optional HTMLElement element,
+ [Default=Undefined] optional HTMLElement before);
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
- [RaisesException] void add(HTMLElement element, [Default=Undefined] optional long index);
// In JavaScript, we support both option index and option object parameters.
// As of this writing this cannot be auto-generated.
[Custom] void remove(/* indexOrOption */);
diff --git a/Source/WebCore/html/HTMLSelectElementWin.cpp b/Source/WebCore/html/HTMLSelectElementWin.cpp
deleted file mode 100644
index 90f6ef70f..000000000
--- a/Source/WebCore/html/HTMLSelectElementWin.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "HTMLSelectElement.h"
-
-#if OS(WINDOWS)
-
-#include "Element.h"
-#include "KeyboardEvent.h"
-#include "RenderMenuList.h"
-
-namespace WebCore {
-
-bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event)
-{
- // Allow (Shift) F4 and (Ctrl/Shift) Alt/AltGr + Up/Down arrow to pop the menu, matching Firefox.
- bool eventShowsMenu = (!event->altKey() && !event->ctrlKey() && event->keyIdentifier() == "F4")
- || ((event->altGraphKey() || event->altKey()) && (event->keyIdentifier() == "Down" || event->keyIdentifier() == "Up"));
- if (!eventShowsMenu)
- return false;
-
- // Save the selection so it can be compared to the new selection when dispatching change events during setSelectedIndex,
- // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
- saveLastSelection();
- if (auto* menuList = downcast<RenderMenuList>(renderer()))
- menuList->showPopup();
-
- int index = selectedIndex();
- ASSERT(index >= 0);
- ASSERT_WITH_SECURITY_IMPLICATION(index < static_cast<int>(listItems().size()));
- setSelectedIndex(index);
- event->setDefaultHandled();
- return true;
-}
-
-}
-
-#endif
diff --git a/Source/WebCore/html/HTMLSourceElement.cpp b/Source/WebCore/html/HTMLSourceElement.cpp
index 2931ce0d3..4e0b4dae6 100644
--- a/Source/WebCore/html/HTMLSourceElement.cpp
+++ b/Source/WebCore/html/HTMLSourceElement.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -40,36 +40,33 @@ using namespace HTMLNames;
inline HTMLSourceElement::HTMLSourceElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
- , ActiveDOMObject(&document)
- , m_errorEventTimer(*this, &HTMLSourceElement::errorEventTimerFired)
+ , m_errorEventTimer(this, &HTMLSourceElement::errorEventTimerFired)
{
LOG(Media, "HTMLSourceElement::HTMLSourceElement - %p", this);
ASSERT(hasTagName(sourceTag));
}
-Ref<HTMLSourceElement> HTMLSourceElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLSourceElement> HTMLSourceElement::create(const QualifiedName& tagName, Document& document)
{
- Ref<HTMLSourceElement> sourceElement = adoptRef(*new HTMLSourceElement(tagName, document));
- sourceElement->suspendIfNeeded();
- return sourceElement;
+ return adoptRef(new HTMLSourceElement(tagName, document));
}
Node::InsertionNotificationRequest HTMLSourceElement::insertedInto(ContainerNode& insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
Element* parent = parentElement();
- if (is<HTMLMediaElement>(parent))
- downcast<HTMLMediaElement>(*parent).sourceWasAdded(this);
+ if (parent && parent->isMediaElement())
+ toHTMLMediaElement(parentNode())->sourceWasAdded(this);
return InsertionDone;
}
void HTMLSourceElement::removedFrom(ContainerNode& removalRoot)
{
Element* parent = parentElement();
- if (!parent && is<Element>(removalRoot))
- parent = &downcast<Element>(removalRoot);
- if (is<HTMLMediaElement>(parent))
- downcast<HTMLMediaElement>(*parent).sourceWasRemoved(this);
+ if (!parent && removalRoot.isElementNode())
+ parent = &toElement(removalRoot);
+ if (parent && parent->isMediaElement())
+ toHTMLMediaElement(parent)->sourceWasRemoved(this);
HTMLElement::removedFrom(removalRoot);
}
@@ -113,7 +110,7 @@ void HTMLSourceElement::cancelPendingErrorEvent()
m_errorEventTimer.stop();
}
-void HTMLSourceElement::errorEventTimerFired()
+void HTMLSourceElement::errorEventTimerFired(Timer<HTMLSourceElement>&)
{
LOG(Media, "HTMLSourceElement::errorEventTimerFired - %p", this);
dispatchEvent(Event::create(eventNames().errorEvent, false, true));
@@ -124,37 +121,6 @@ bool HTMLSourceElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == srcAttr || HTMLElement::isURLAttribute(attribute);
}
-const char* HTMLSourceElement::activeDOMObjectName() const
-{
- return "HTMLSourceElement";
-}
-
-bool HTMLSourceElement::canSuspendForPageCache() const
-{
- return true;
-}
-
-void HTMLSourceElement::suspend(ReasonForSuspension why)
-{
- if (why == PageCache) {
- m_shouldRescheduleErrorEventOnResume = m_errorEventTimer.isActive();
- m_errorEventTimer.stop();
- }
-}
-
-void HTMLSourceElement::resume()
-{
- if (m_shouldRescheduleErrorEventOnResume) {
- m_errorEventTimer.startOneShot(0);
- m_shouldRescheduleErrorEventOnResume = false;
- }
-}
-
-void HTMLSourceElement::stop()
-{
- cancelPendingErrorEvent();
-}
-
}
#endif
diff --git a/Source/WebCore/html/HTMLSourceElement.h b/Source/WebCore/html/HTMLSourceElement.h
index f373fb998..492d1c2df 100644
--- a/Source/WebCore/html/HTMLSourceElement.h
+++ b/Source/WebCore/html/HTMLSourceElement.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -32,9 +32,9 @@
namespace WebCore {
-class HTMLSourceElement final : public HTMLElement, public ActiveDOMObject {
+class HTMLSourceElement final : public HTMLElement {
public:
- static Ref<HTMLSourceElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLSourceElement> create(const QualifiedName&, Document&);
String media() const;
String type() const;
@@ -52,19 +52,13 @@ private:
virtual void removedFrom(ContainerNode&) override;
virtual bool isURLAttribute(const Attribute&) const override;
- // ActiveDOMObject.
- const char* activeDOMObjectName() const override;
- bool canSuspendForPageCache() const override;
- void suspend(ReasonForSuspension) override;
- void resume() override;
- void stop() override;
+ void errorEventTimerFired(Timer<HTMLSourceElement>&);
- void errorEventTimerFired();
-
- Timer m_errorEventTimer;
- bool m_shouldRescheduleErrorEventOnResume { false };
+ Timer<HTMLSourceElement> m_errorEventTimer;
};
+NODE_TYPE_CASTS(HTMLSourceElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLSourceElement.idl b/Source/WebCore/html/HTMLSourceElement.idl
index ceed35ef6..4d23c79ca 100644
--- a/Source/WebCore/html/HTMLSourceElement.idl
+++ b/Source/WebCore/html/HTMLSourceElement.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/HTMLSpanElement.cpp b/Source/WebCore/html/HTMLSpanElement.cpp
index b8205814a..9ecc231c0 100644
--- a/Source/WebCore/html/HTMLSpanElement.cpp
+++ b/Source/WebCore/html/HTMLSpanElement.cpp
@@ -38,9 +38,9 @@ HTMLSpanElement::HTMLSpanElement(const QualifiedName& tagName, Document& documen
ASSERT(hasTagName(spanTag));
}
-Ref<HTMLSpanElement> HTMLSpanElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLSpanElement> HTMLSpanElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLSpanElement(tagName, document));
+ return adoptRef(new HTMLSpanElement(tagName, document));
}
}
diff --git a/Source/WebCore/html/HTMLSpanElement.h b/Source/WebCore/html/HTMLSpanElement.h
index c28bc696c..2e70bf9af 100644
--- a/Source/WebCore/html/HTMLSpanElement.h
+++ b/Source/WebCore/html/HTMLSpanElement.h
@@ -30,9 +30,9 @@
namespace WebCore {
-class HTMLSpanElement final : public HTMLElement {
+class HTMLSpanElement : public HTMLElement {
public:
- static Ref<HTMLSpanElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLSpanElement> create(const QualifiedName&, Document&);
private:
HTMLSpanElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLStyleElement.cpp b/Source/WebCore/html/HTMLStyleElement.cpp
index aceded4e6..b0b667286 100644
--- a/Source/WebCore/html/HTMLStyleElement.cpp
+++ b/Source/WebCore/html/HTMLStyleElement.cpp
@@ -24,6 +24,7 @@
#include "config.h"
#include "HTMLStyleElement.h"
+#include "Attribute.h"
#include "Document.h"
#include "Event.h"
#include "EventSender.h"
@@ -40,7 +41,7 @@ using namespace HTMLNames;
static StyleEventSender& styleLoadEventSender()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(StyleEventSender, sharedLoadEventSender, (eventNames().loadEvent));
+ DEFINE_STATIC_LOCAL(StyleEventSender, sharedLoadEventSender, (eventNames().loadEvent));
return sharedLoadEventSender;
}
@@ -59,12 +60,12 @@ HTMLStyleElement::~HTMLStyleElement()
// Therefore we can't ASSERT(m_scopedStyleRegistrationState == NotRegistered).
m_styleSheetOwner.clearDocumentData(document(), *this);
- styleLoadEventSender().cancelEvent(*this);
+ styleLoadEventSender().cancelEvent(this);
}
-Ref<HTMLStyleElement> HTMLStyleElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
+PassRefPtr<HTMLStyleElement> HTMLStyleElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
{
- return adoptRef(*new HTMLStyleElement(tagName, document, createdByParser));
+ return adoptRef(new HTMLStyleElement(tagName, document, createdByParser));
}
void HTMLStyleElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -132,7 +133,7 @@ void HTMLStyleElement::notifyLoadedSheetAndAllCriticalSubresources(bool errorOcc
if (m_firedLoad)
return;
m_loadedSheet = !errorOccurred;
- styleLoadEventSender().dispatchEventSoon(*this);
+ styleLoadEventSender().dispatchEventSoon(this);
m_firedLoad = true;
}
diff --git a/Source/WebCore/html/HTMLStyleElement.h b/Source/WebCore/html/HTMLStyleElement.h
index 7776d1ee0..9957ba507 100644
--- a/Source/WebCore/html/HTMLStyleElement.h
+++ b/Source/WebCore/html/HTMLStyleElement.h
@@ -36,7 +36,7 @@ typedef EventSender<HTMLStyleElement> StyleEventSender;
class HTMLStyleElement final : public HTMLElement {
public:
- static Ref<HTMLStyleElement> create(const QualifiedName&, Document&, bool createdByParser);
+ static PassRefPtr<HTMLStyleElement> create(const QualifiedName&, Document&, bool createdByParser);
virtual ~HTMLStyleElement();
CSSStyleSheet* sheet() const { return m_styleSheetOwner.sheet(); }
@@ -58,7 +58,7 @@ private:
virtual void finishParsingChildren() override;
- bool isLoading() const { return m_styleSheetOwner.isLoading(); }
+ virtual bool isLoading() const { return m_styleSheetOwner.isLoading(); }
virtual bool sheetLoaded() override { return m_styleSheetOwner.sheetLoaded(document()); }
virtual void notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred) override;
virtual void startLoadingDynamicSheet() override { m_styleSheetOwner.startLoadingDynamicSheet(document()); }
@@ -70,6 +70,8 @@ private:
bool m_loadedSheet;
};
+NODE_TYPE_CASTS(HTMLStyleElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLSummaryElement.cpp b/Source/WebCore/html/HTMLSummaryElement.cpp
index 8b5c18710..7c41386e6 100644
--- a/Source/WebCore/html/HTMLSummaryElement.cpp
+++ b/Source/WebCore/html/HTMLSummaryElement.cpp
@@ -24,7 +24,6 @@
#if ENABLE(DETAILS_ELEMENT)
#include "DetailsMarkerControl.h"
#include "HTMLDetailsElement.h"
-#include "HTMLFormControlElement.h"
#include "InsertionPoint.h"
#include "KeyboardEvent.h"
#include "MouseEvent.h"
@@ -36,9 +35,9 @@ namespace WebCore {
using namespace HTMLNames;
-class SummaryContentElement final : public InsertionPoint {
+class SummaryContentElement : public InsertionPoint {
public:
- static Ref<SummaryContentElement> create(Document&);
+ static PassRefPtr<SummaryContentElement> create(Document&);
private:
SummaryContentElement(Document& document)
@@ -47,16 +46,16 @@ private:
}
};
-Ref<SummaryContentElement> SummaryContentElement::create(Document& document)
+PassRefPtr<SummaryContentElement> SummaryContentElement::create(Document& document)
{
- return adoptRef(*new SummaryContentElement(document));
+ return adoptRef(new SummaryContentElement(document));
}
-Ref<HTMLSummaryElement> HTMLSummaryElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLSummaryElement> HTMLSummaryElement::create(const QualifiedName& tagName, Document& document)
{
- Ref<HTMLSummaryElement> summary = adoptRef(*new HTMLSummaryElement(tagName, document));
+ RefPtr<HTMLSummaryElement> summary = adoptRef(new HTMLSummaryElement(tagName, document));
summary->ensureUserAgentShadowRoot();
- return summary;
+ return summary.release();
}
HTMLSummaryElement::HTMLSummaryElement(const QualifiedName& tagName, Document& document)
@@ -65,9 +64,9 @@ HTMLSummaryElement::HTMLSummaryElement(const QualifiedName& tagName, Document& d
ASSERT(hasTagName(summaryTag));
}
-RenderPtr<RenderElement> HTMLSummaryElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLSummaryElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderBlockFlow>(*this, WTF::move(style));
+ return createRenderer<RenderBlockFlow>(*this, std::move(style));
}
bool HTMLSummaryElement::childShouldCreateRenderer(const Node& child) const
@@ -88,8 +87,8 @@ HTMLDetailsElement* HTMLSummaryElement::detailsElement() const
{
Node* mayDetails = NodeRenderingTraversal::parent(this);
if (!mayDetails || !mayDetails->hasTagName(detailsTag))
- return nullptr;
- return downcast<HTMLDetailsElement>(mayDetails);
+ return 0;
+ return toHTMLDetailsElement(mayDetails);
}
bool HTMLSummaryElement::isMainSummary() const
@@ -102,14 +101,13 @@ bool HTMLSummaryElement::isMainSummary() const
static bool isClickableControl(Node* node)
{
- ASSERT(node);
- if (!is<Element>(*node))
+ if (!node->isElementNode())
return false;
- Element& element = downcast<Element>(*node);
- if (is<HTMLFormControlElement>(element))
+ Element* element = toElement(node);
+ if (element->isFormControlElement())
return true;
- Element* host = element.shadowHost();
- return host && is<HTMLFormControlElement>(host);
+ Element* host = element->shadowHost();
+ return host && host->isFormControlElement();
}
bool HTMLSummaryElement::supportsFocus() const
@@ -127,29 +125,28 @@ void HTMLSummaryElement::defaultEventHandler(Event* event)
return;
}
- if (is<KeyboardEvent>(*event)) {
- KeyboardEvent& keyboardEvent = downcast<KeyboardEvent>(*event);
- if (keyboardEvent.type() == eventNames().keydownEvent && keyboardEvent.keyIdentifier() == "U+0020") {
+ if (event->isKeyboardEvent()) {
+ if (event->type() == eventNames().keydownEvent && static_cast<KeyboardEvent*>(event)->keyIdentifier() == "U+0020") {
setActive(true, true);
// No setDefaultHandled() - IE dispatches a keypress in this case.
return;
}
- if (keyboardEvent.type() == eventNames().keypressEvent) {
- switch (keyboardEvent.charCode()) {
+ if (event->type() == eventNames().keypressEvent) {
+ switch (static_cast<KeyboardEvent*>(event)->charCode()) {
case '\r':
dispatchSimulatedClick(event);
- keyboardEvent.setDefaultHandled();
+ event->setDefaultHandled();
return;
case ' ':
// Prevent scrolling down the page.
- keyboardEvent.setDefaultHandled();
+ event->setDefaultHandled();
return;
}
}
- if (keyboardEvent.type() == eventNames().keyupEvent && keyboardEvent.keyIdentifier() == "U+0020") {
+ if (event->type() == eventNames().keyupEvent && static_cast<KeyboardEvent*>(event)->keyIdentifier() == "U+0020") {
if (active())
dispatchSimulatedClick(event);
- keyboardEvent.setDefaultHandled();
+ event->setDefaultHandled();
return;
}
}
diff --git a/Source/WebCore/html/HTMLSummaryElement.h b/Source/WebCore/html/HTMLSummaryElement.h
index 4809ce445..fbabcde52 100644
--- a/Source/WebCore/html/HTMLSummaryElement.h
+++ b/Source/WebCore/html/HTMLSummaryElement.h
@@ -29,24 +29,25 @@ class HTMLDetailsElement;
class HTMLSummaryElement final : public HTMLElement {
public:
- static Ref<HTMLSummaryElement> create(const QualifiedName&, Document&);
-
+ static PassRefPtr<HTMLSummaryElement> create(const QualifiedName&, Document&);
bool isMainSummary() const;
virtual bool willRespondToMouseClickEvents() override;
private:
HTMLSummaryElement(const QualifiedName&, Document&);
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual bool childShouldCreateRenderer(const Node&) const override;
virtual void defaultEventHandler(Event*) override;
virtual void didAddUserAgentShadowRoot(ShadowRoot*) override;
HTMLDetailsElement* detailsElement() const;
- virtual bool supportsFocus() const override;
+ bool supportsFocus() const override;
};
+NODE_TYPE_CASTS(HTMLSummaryElement)
+
}
#endif // HTMLSummaryElement_h
diff --git a/Source/WebCore/html/HTMLTableCaptionElement.cpp b/Source/WebCore/html/HTMLTableCaptionElement.cpp
index 261ad1774..0ddf41766 100644
--- a/Source/WebCore/html/HTMLTableCaptionElement.cpp
+++ b/Source/WebCore/html/HTMLTableCaptionElement.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "HTMLTableCaptionElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "HTMLNames.h"
@@ -38,9 +39,9 @@ inline HTMLTableCaptionElement::HTMLTableCaptionElement(const QualifiedName& tag
ASSERT(hasTagName(captionTag));
}
-Ref<HTMLTableCaptionElement> HTMLTableCaptionElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLTableCaptionElement> HTMLTableCaptionElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLTableCaptionElement(tagName, document));
+ return adoptRef(new HTMLTableCaptionElement(tagName, document));
}
bool HTMLTableCaptionElement::isPresentationAttribute(const QualifiedName& name) const
diff --git a/Source/WebCore/html/HTMLTableCaptionElement.h b/Source/WebCore/html/HTMLTableCaptionElement.h
index 2d18c6c36..f064e28a9 100644
--- a/Source/WebCore/html/HTMLTableCaptionElement.h
+++ b/Source/WebCore/html/HTMLTableCaptionElement.h
@@ -32,7 +32,7 @@ namespace WebCore {
class HTMLTableCaptionElement final : public HTMLElement {
public:
- static Ref<HTMLTableCaptionElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLTableCaptionElement> create(const QualifiedName&, Document&);
private:
HTMLTableCaptionElement(const QualifiedName&, Document&);
@@ -41,6 +41,8 @@ private:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
};
+NODE_TYPE_CASTS(HTMLTableCaptionElement)
+
} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLTableCellElement.cpp b/Source/WebCore/html/HTMLTableCellElement.cpp
index 61ab9e698..ccfbf27bc 100644
--- a/Source/WebCore/html/HTMLTableCellElement.cpp
+++ b/Source/WebCore/html/HTMLTableCellElement.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "HTMLTableCellElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
@@ -43,9 +44,9 @@ inline HTMLTableCellElement::HTMLTableCellElement(const QualifiedName& tagName,
{
}
-Ref<HTMLTableCellElement> HTMLTableCellElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLTableCellElement> HTMLTableCellElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLTableCellElement(tagName, document));
+ return adoptRef(new HTMLTableCellElement(tagName, document));
}
int HTMLTableCellElement::colSpan() const
@@ -104,11 +105,11 @@ void HTMLTableCellElement::collectStyleForPresentationAttribute(const QualifiedN
void HTMLTableCellElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == rowspanAttr) {
- if (is<RenderTableCell>(renderer()))
- downcast<RenderTableCell>(*renderer()).colSpanOrRowSpanChanged();
+ if (renderer() && renderer()->isTableCell())
+ toRenderTableCell(renderer())->colSpanOrRowSpanChanged();
} else if (name == colspanAttr) {
- if (is<RenderTableCell>(renderer()))
- downcast<RenderTableCell>(*renderer()).colSpanOrRowSpanChanged();
+ if (renderer() && renderer()->isTableCell())
+ toRenderTableCell(renderer())->colSpanOrRowSpanChanged();
} else
HTMLTablePartElement::parseAttribute(name, value);
}
@@ -159,21 +160,21 @@ void HTMLTableCellElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) c
{
HTMLTablePartElement::addSubresourceAttributeURLs(urls);
- addSubresourceURL(urls, document().completeURL(fastGetAttribute(backgroundAttr)));
+ addSubresourceURL(urls, document().completeURL(getAttribute(backgroundAttr)));
}
HTMLTableCellElement* HTMLTableCellElement::cellAbove() const
{
- auto* cellRenderer = renderer();
- if (!is<RenderTableCell>(cellRenderer))
+ auto cellRenderer = renderer();
+ if (!cellRenderer || !cellRenderer->isTableCell())
return nullptr;
- auto& tableCellRenderer = downcast<RenderTableCell>(*cellRenderer);
- auto* cellAboveRenderer = tableCellRenderer.table()->cellAbove(&tableCellRenderer);
+ auto tableCellRenderer = toRenderTableCell(cellRenderer);
+ auto cellAboveRenderer = tableCellRenderer->table()->cellAbove(tableCellRenderer);
if (!cellAboveRenderer)
return nullptr;
- return downcast<HTMLTableCellElement>(cellAboveRenderer->element());
+ return toHTMLTableCellElement(cellAboveRenderer->element());
}
} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLTableCellElement.h b/Source/WebCore/html/HTMLTableCellElement.h
index d9d9b748b..125eba56f 100644
--- a/Source/WebCore/html/HTMLTableCellElement.h
+++ b/Source/WebCore/html/HTMLTableCellElement.h
@@ -32,7 +32,7 @@ namespace WebCore {
class HTMLTableCellElement final : public HTMLTablePartElement {
public:
- static Ref<HTMLTableCellElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLTableCellElement> create(const QualifiedName&, Document&);
int cellIndex() const;
int colSpan() const;
@@ -47,7 +47,7 @@ public:
String headers() const;
String scope() const;
- WEBCORE_EXPORT HTMLTableCellElement* cellAbove() const;
+ HTMLTableCellElement* cellAbove() const;
private:
HTMLTableCellElement(const QualifiedName&, Document&);
@@ -62,11 +62,10 @@ private:
virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override;
};
-} // namespace WebCore
+void isHTMLTableCellElement(const HTMLTableCellElement&); // Catch unnecessary runtime check of type known at compile time.
+inline bool isHTMLTableCellElement(const Node& node) { return node.hasTagName(HTMLNames::tdTag) || node.hasTagName(HTMLNames::thTag); }
+NODE_TYPE_CASTS(HTMLTableCellElement)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLTableCellElement)
- static bool isType(const WebCore::HTMLElement& element) { return element.hasTagName(WebCore::HTMLNames::tdTag) || element.hasTagName(WebCore::HTMLNames::thTag); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::HTMLElement>(node) && isType(downcast<WebCore::HTMLElement>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLTableColElement.cpp b/Source/WebCore/html/HTMLTableColElement.cpp
index 991652296..995b892f9 100644
--- a/Source/WebCore/html/HTMLTableColElement.cpp
+++ b/Source/WebCore/html/HTMLTableColElement.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "HTMLTableColElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "HTMLNames.h"
#include "HTMLTableElement.h"
@@ -41,9 +42,9 @@ inline HTMLTableColElement::HTMLTableColElement(const QualifiedName& tagName, Do
{
}
-Ref<HTMLTableColElement> HTMLTableColElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLTableColElement> HTMLTableColElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLTableColElement(tagName, document));
+ return adoptRef(new HTMLTableColElement(tagName, document));
}
bool HTMLTableColElement::isPresentationAttribute(const QualifiedName& name) const
@@ -64,17 +65,16 @@ void HTMLTableColElement::collectStyleForPresentationAttribute(const QualifiedNa
void HTMLTableColElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == spanAttr) {
- int newSpan = value.toInt();
- m_span = newSpan ? newSpan : 1;
- if (is<RenderTableCol>(renderer()))
- downcast<RenderTableCol>(*renderer()).updateFromElement();
+ m_span = !value.isNull() ? value.toInt() : 1;
+ if (renderer() && renderer()->isRenderTableCol())
+ renderer()->updateFromElement();
} else if (name == widthAttr) {
if (!value.isEmpty()) {
- if (is<RenderTableCol>(renderer())) {
- RenderTableCol& col = downcast<RenderTableCol>(*renderer());
+ if (renderer() && renderer()->isRenderTableCol()) {
+ RenderTableCol* col = toRenderTableCol(renderer());
int newWidth = width().toInt();
- if (newWidth != col.width())
- col.setNeedsLayoutAndPrefWidthsRecalc();
+ if (newWidth != col->width())
+ col->setNeedsLayoutAndPrefWidthsRecalc();
}
}
} else
@@ -83,11 +83,11 @@ void HTMLTableColElement::parseAttribute(const QualifiedName& name, const Atomic
const StyleProperties* HTMLTableColElement::additionalPresentationAttributeStyle()
{
- if (!hasTagName(colgroupTag))
- return nullptr;
+ if (!hasLocalName(colgroupTag))
+ return 0;
if (HTMLTableElement* table = findParentTable())
return table->additionalGroupStyle(false);
- return nullptr;
+ return 0;
}
void HTMLTableColElement::setSpan(int n)
diff --git a/Source/WebCore/html/HTMLTableColElement.h b/Source/WebCore/html/HTMLTableColElement.h
index b9618a9f6..2c96085be 100644
--- a/Source/WebCore/html/HTMLTableColElement.h
+++ b/Source/WebCore/html/HTMLTableColElement.h
@@ -32,7 +32,7 @@ namespace WebCore {
class HTMLTableColElement final : public HTMLTablePartElement {
public:
- static Ref<HTMLTableColElement> create(const QualifiedName& tagName, Document&);
+ static PassRefPtr<HTMLTableColElement> create(const QualifiedName& tagName, Document&);
int span() const { return m_span; }
void setSpan(int);
diff --git a/Source/WebCore/html/HTMLTableElement.cpp b/Source/WebCore/html/HTMLTableElement.cpp
index 7457361b6..bf22d0087 100644
--- a/Source/WebCore/html/HTMLTableElement.cpp
+++ b/Source/WebCore/html/HTMLTableElement.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "HTMLTableElement.h"
+#include "Attribute.h"
#include "CSSImageValue.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
@@ -56,23 +57,23 @@ HTMLTableElement::HTMLTableElement(const QualifiedName& tagName, Document& docum
ASSERT(hasTagName(tableTag));
}
-Ref<HTMLTableElement> HTMLTableElement::create(Document& document)
+PassRefPtr<HTMLTableElement> HTMLTableElement::create(Document& document)
{
- return adoptRef(*new HTMLTableElement(tableTag, document));
+ return adoptRef(new HTMLTableElement(tableTag, document));
}
-Ref<HTMLTableElement> HTMLTableElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLTableElement> HTMLTableElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLTableElement(tagName, document));
+ return adoptRef(new HTMLTableElement(tagName, document));
}
HTMLTableCaptionElement* HTMLTableElement::caption() const
{
for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (is<HTMLTableCaptionElement>(*child))
- return downcast<HTMLTableCaptionElement>(child);
+ if (child->hasTagName(captionTag))
+ return toHTMLTableCaptionElement(child);
}
- return nullptr;
+ return 0;
}
void HTMLTableElement::setCaption(PassRefPtr<HTMLTableCaptionElement> newCaption, ExceptionCode& ec)
@@ -85,9 +86,9 @@ HTMLTableSectionElement* HTMLTableElement::tHead() const
{
for (Node* child = firstChild(); child; child = child->nextSibling()) {
if (child->hasTagName(theadTag))
- return downcast<HTMLTableSectionElement>(child);
+ return toHTMLTableSectionElement(child);
}
- return nullptr;
+ return 0;
}
void HTMLTableElement::setTHead(PassRefPtr<HTMLTableSectionElement> newHead, ExceptionCode& ec)
@@ -106,9 +107,9 @@ HTMLTableSectionElement* HTMLTableElement::tFoot() const
{
for (Node* child = firstChild(); child; child = child->nextSibling()) {
if (child->hasTagName(tfootTag))
- return downcast<HTMLTableSectionElement>(child);
+ return toHTMLTableSectionElement(child);
}
- return nullptr;
+ return 0;
}
void HTMLTableElement::setTFoot(PassRefPtr<HTMLTableSectionElement> newFoot, ExceptionCode& ec)
@@ -123,13 +124,13 @@ void HTMLTableElement::setTFoot(PassRefPtr<HTMLTableSectionElement> newFoot, Exc
insertBefore(newFoot, child, ec);
}
-RefPtr<HTMLElement> HTMLTableElement::createTHead()
+PassRefPtr<HTMLElement> HTMLTableElement::createTHead()
{
if (HTMLTableSectionElement* existingHead = tHead())
return existingHead;
RefPtr<HTMLTableSectionElement> head = HTMLTableSectionElement::create(theadTag, document());
setTHead(head, IGNORE_EXCEPTION);
- return head;
+ return head.release();
}
void HTMLTableElement::deleteTHead()
@@ -137,13 +138,13 @@ void HTMLTableElement::deleteTHead()
removeChild(tHead(), IGNORE_EXCEPTION);
}
-RefPtr<HTMLElement> HTMLTableElement::createTFoot()
+PassRefPtr<HTMLElement> HTMLTableElement::createTFoot()
{
if (HTMLTableSectionElement* existingFoot = tFoot())
return existingFoot;
RefPtr<HTMLTableSectionElement> foot = HTMLTableSectionElement::create(tfootTag, document());
setTFoot(foot, IGNORE_EXCEPTION);
- return foot;
+ return foot.release();
}
void HTMLTableElement::deleteTFoot()
@@ -151,21 +152,21 @@ void HTMLTableElement::deleteTFoot()
removeChild(tFoot(), IGNORE_EXCEPTION);
}
-RefPtr<HTMLElement> HTMLTableElement::createTBody()
+PassRefPtr<HTMLElement> HTMLTableElement::createTBody()
{
RefPtr<HTMLTableSectionElement> body = HTMLTableSectionElement::create(tbodyTag, document());
Node* referenceElement = lastBody() ? lastBody()->nextSibling() : 0;
insertBefore(body, referenceElement, ASSERT_NO_EXCEPTION);
- return body;
+ return body.release();
}
-RefPtr<HTMLElement> HTMLTableElement::createCaption()
+PassRefPtr<HTMLElement> HTMLTableElement::createCaption()
{
if (HTMLTableCaptionElement* existingCaption = caption())
return existingCaption;
RefPtr<HTMLTableCaptionElement> caption = HTMLTableCaptionElement::create(captionTag, document());
setCaption(caption, IGNORE_EXCEPTION);
- return caption;
+ return caption.release();
}
void HTMLTableElement::deleteCaption()
@@ -177,12 +178,12 @@ HTMLTableSectionElement* HTMLTableElement::lastBody() const
{
for (Node* child = lastChild(); child; child = child->previousSibling()) {
if (child->hasTagName(tbodyTag))
- return downcast<HTMLTableSectionElement>(child);
+ return toHTMLTableSectionElement(child);
}
- return nullptr;
+ return 0;
}
-RefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionCode& ec)
+PassRefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionCode& ec)
{
if (index < -1) {
ec = INDEX_SIZE_ERR;
@@ -194,10 +195,10 @@ RefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionCode& ec)
RefPtr<HTMLTableRowElement> lastRow = 0;
RefPtr<HTMLTableRowElement> row = 0;
if (index == -1)
- lastRow = HTMLTableRowsCollection::lastRow(*this);
+ lastRow = HTMLTableRowsCollection::lastRow(this);
else {
for (int i = 0; i <= index; ++i) {
- row = HTMLTableRowsCollection::rowAfter(*this, lastRow.get());
+ row = HTMLTableRowsCollection::rowAfter(this, lastRow.get());
if (!row) {
if (i != index) {
ec = INDEX_SIZE_ERR;
@@ -219,23 +220,23 @@ RefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionCode& ec)
RefPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
newBody->appendChild(newRow, ec);
appendChild(newBody.release(), ec);
- return newRow;
+ return newRow.release();
}
}
RefPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
parent->insertBefore(newRow, row.get(), ec);
- return newRow;
+ return newRow.release();
}
void HTMLTableElement::deleteRow(int index, ExceptionCode& ec)
{
HTMLTableRowElement* row = 0;
if (index == -1)
- row = HTMLTableRowsCollection::lastRow(*this);
+ row = HTMLTableRowsCollection::lastRow(this);
else {
for (int i = 0; i <= index; ++i) {
- row = HTMLTableRowsCollection::rowAfter(*this, row);
+ row = HTMLTableRowsCollection::rowAfter(this, row);
if (!row)
break;
}
@@ -402,7 +403,7 @@ void HTMLTableElement::parseAttribute(const QualifiedName& name, const AtomicStr
HTMLElement::parseAttribute(name, value);
if (bordersBefore != cellBorders() || oldPadding != m_padding) {
- m_sharedCellStyle = nullptr;
+ m_sharedCellStyle = 0;
bool cellChanged = false;
for (Node* child = firstChild(); child; child = child->nextSibling())
cellChanged |= setTableCellsChanged(child);
@@ -467,7 +468,7 @@ HTMLTableElement::CellBorders HTMLTableElement::cellBorders() const
return NoBorders;
}
-RefPtr<StyleProperties> HTMLTableElement::createSharedCellStyle()
+PassRefPtr<StyleProperties> HTMLTableElement::createSharedCellStyle()
{
RefPtr<MutableStyleProperties> style = MutableStyleProperties::create();
@@ -504,7 +505,7 @@ RefPtr<StyleProperties> HTMLTableElement::createSharedCellStyle()
if (m_padding)
style->setProperty(CSSPropertyPadding, cssValuePool().createValue(m_padding, CSSPrimitiveValue::CSS_PX));
- return style;
+ return style.release();
}
const StyleProperties* HTMLTableElement::additionalCellStyle()
@@ -549,31 +550,31 @@ bool HTMLTableElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == backgroundAttr || HTMLElement::isURLAttribute(attribute);
}
-Ref<HTMLCollection> HTMLTableElement::rows()
+PassRefPtr<HTMLCollection> HTMLTableElement::rows()
{
return ensureCachedHTMLCollection(TableRows);
}
-Ref<HTMLCollection> HTMLTableElement::tBodies()
+PassRefPtr<HTMLCollection> HTMLTableElement::tBodies()
{
return ensureCachedHTMLCollection(TableTBodies);
}
-const AtomicString& HTMLTableElement::rules() const
+String HTMLTableElement::rules() const
{
- return fastGetAttribute(rulesAttr);
+ return getAttribute(rulesAttr);
}
-const AtomicString& HTMLTableElement::summary() const
+String HTMLTableElement::summary() const
{
- return fastGetAttribute(summaryAttr);
+ return getAttribute(summaryAttr);
}
void HTMLTableElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
{
HTMLElement::addSubresourceAttributeURLs(urls);
- addSubresourceURL(urls, document().completeURL(fastGetAttribute(backgroundAttr)));
+ addSubresourceURL(urls, document().completeURL(getAttribute(backgroundAttr)));
}
}
diff --git a/Source/WebCore/html/HTMLTableElement.h b/Source/WebCore/html/HTMLTableElement.h
index cf5f4a0cd..6a0165073 100644
--- a/Source/WebCore/html/HTMLTableElement.h
+++ b/Source/WebCore/html/HTMLTableElement.h
@@ -37,8 +37,8 @@ class HTMLTableSectionElement;
class HTMLTableElement final : public HTMLElement {
public:
- static Ref<HTMLTableElement> create(Document&);
- static Ref<HTMLTableElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLTableElement> create(Document&);
+ static PassRefPtr<HTMLTableElement> create(const QualifiedName&, Document&);
HTMLTableCaptionElement* caption() const;
void setCaption(PassRefPtr<HTMLTableCaptionElement>, ExceptionCode&);
@@ -49,22 +49,21 @@ public:
HTMLTableSectionElement* tFoot() const;
void setTFoot(PassRefPtr<HTMLTableSectionElement>, ExceptionCode&);
- RefPtr<HTMLElement> createTHead();
+ PassRefPtr<HTMLElement> createTHead();
void deleteTHead();
- RefPtr<HTMLElement> createTFoot();
+ PassRefPtr<HTMLElement> createTFoot();
void deleteTFoot();
- RefPtr<HTMLElement> createTBody();
- RefPtr<HTMLElement> createCaption();
+ PassRefPtr<HTMLElement> createTBody();
+ PassRefPtr<HTMLElement> createCaption();
void deleteCaption();
- RefPtr<HTMLElement> insertRow(ExceptionCode& ec) { return insertRow(-1, ec); }
- RefPtr<HTMLElement> insertRow(int index, ExceptionCode&);
+ PassRefPtr<HTMLElement> insertRow(int index, ExceptionCode&);
void deleteRow(int index, ExceptionCode&);
- Ref<HTMLCollection> rows();
- Ref<HTMLCollection> tBodies();
+ PassRefPtr<HTMLCollection> rows();
+ PassRefPtr<HTMLCollection> tBodies();
- const AtomicString& rules() const;
- const AtomicString& summary() const;
+ String rules() const;
+ String summary() const;
const StyleProperties* additionalCellStyle();
const StyleProperties* additionalGroupStyle(bool rows);
@@ -87,7 +86,7 @@ private:
CellBorders cellBorders() const;
- RefPtr<StyleProperties> createSharedCellStyle();
+ PassRefPtr<StyleProperties> createSharedCellStyle();
HTMLTableSectionElement* lastBody() const;
@@ -101,6 +100,8 @@ private:
RefPtr<StyleProperties> m_sharedCellStyle;
};
+NODE_TYPE_CASTS(HTMLTableElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLTableElement.idl b/Source/WebCore/html/HTMLTableElement.idl
index a0a1c6b03..1881de3ea 100644
--- a/Source/WebCore/html/HTMLTableElement.idl
+++ b/Source/WebCore/html/HTMLTableElement.idl
@@ -45,7 +45,7 @@ interface HTMLTableElement : HTMLElement {
HTMLElement createCaption();
void deleteCaption();
- [RaisesException] HTMLElement insertRow(optional long index);
+ [RaisesException] HTMLElement insertRow([Default=Undefined] optional long index);
[RaisesException] void deleteRow([Default=Undefined] optional long index);
};
diff --git a/Source/WebCore/html/HTMLTablePartElement.cpp b/Source/WebCore/html/HTMLTablePartElement.cpp
index 835af4649..e64071bac 100644
--- a/Source/WebCore/html/HTMLTablePartElement.cpp
+++ b/Source/WebCore/html/HTMLTablePartElement.cpp
@@ -4,7 +4,7 @@
* (C) 1998 Waldo Bastian (bastian@kde.org)
* (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006 Apple Inc.
+ * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,6 +25,7 @@
#include "config.h"
#include "HTMLTablePartElement.h"
+#include "Attribute.h"
#include "CSSImageValue.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
@@ -85,9 +86,9 @@ void HTMLTablePartElement::collectStyleForPresentationAttribute(const QualifiedN
HTMLTableElement* HTMLTablePartElement::findParentTable() const
{
ContainerNode* parent = parentNode();
- while (parent && !is<HTMLTableElement>(*parent))
+ while (parent && !isHTMLTableElement(parent))
parent = parent->parentNode();
- return downcast<HTMLTableElement>(parent);
+ return toHTMLTableElement(parent);
}
}
diff --git a/Source/WebCore/html/HTMLTableRowElement.cpp b/Source/WebCore/html/HTMLTableRowElement.cpp
index d4351eafc..4c4d9792c 100644
--- a/Source/WebCore/html/HTMLTableRowElement.cpp
+++ b/Source/WebCore/html/HTMLTableRowElement.cpp
@@ -44,14 +44,14 @@ HTMLTableRowElement::HTMLTableRowElement(const QualifiedName& tagName, Document&
ASSERT(hasTagName(trTag));
}
-Ref<HTMLTableRowElement> HTMLTableRowElement::create(Document& document)
+PassRefPtr<HTMLTableRowElement> HTMLTableRowElement::create(Document& document)
{
- return adoptRef(*new HTMLTableRowElement(trTag, document));
+ return adoptRef(new HTMLTableRowElement(trTag, document));
}
-Ref<HTMLTableRowElement> HTMLTableRowElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLTableRowElement> HTMLTableRowElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLTableRowElement(tagName, document));
+ return adoptRef(new HTMLTableRowElement(tagName, document));
}
int HTMLTableRowElement::rowIndex() const
@@ -60,7 +60,7 @@ int HTMLTableRowElement::rowIndex() const
if (!table)
return -1;
table = table->parentNode();
- if (!is<HTMLTableElement>(table))
+ if (!table || !isHTMLTableElement(table))
return -1;
// To match Firefox, the row indices work like this:
@@ -70,7 +70,7 @@ int HTMLTableRowElement::rowIndex() const
int rIndex = 0;
- if (HTMLTableSectionElement* head = downcast<HTMLTableElement>(*table).tHead()) {
+ if (HTMLTableSectionElement* head = toHTMLTableElement(table)->tHead()) {
for (Node *row = head->firstChild(); row; row = row->nextSibling()) {
if (row == this)
return rIndex;
@@ -81,8 +81,8 @@ int HTMLTableRowElement::rowIndex() const
for (Node *node = table->firstChild(); node; node = node->nextSibling()) {
if (node->hasTagName(tbodyTag)) {
- HTMLTableSectionElement& section = downcast<HTMLTableSectionElement>(*node);
- for (Node* row = section.firstChild(); row; row = row->nextSibling()) {
+ HTMLTableSectionElement* section = toHTMLTableSectionElement(node);
+ for (Node* row = section->firstChild(); row; row = row->nextSibling()) {
if (row == this)
return rIndex;
if (row->hasTagName(trTag))
@@ -91,7 +91,7 @@ int HTMLTableRowElement::rowIndex() const
}
}
- if (HTMLTableSectionElement* foot = downcast<HTMLTableElement>(*table).tFoot()) {
+ if (HTMLTableSectionElement* foot = toHTMLTableElement(table)->tFoot()) {
for (Node *row = foot->firstChild(); row; row = row->nextSibling()) {
if (row == this)
return rIndex;
@@ -118,10 +118,10 @@ int HTMLTableRowElement::sectionRowIndex() const
return rIndex;
}
-RefPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionCode& ec)
+PassRefPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionCode& ec)
{
- Ref<HTMLCollection> children = cells();
- int numCells = children->length();
+ RefPtr<HTMLCollection> children = cells();
+ int numCells = children ? children->length() : 0;
if (index < -1 || index > numCells) {
ec = INDEX_SIZE_ERR;
return 0;
@@ -138,13 +138,13 @@ RefPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionCode& ec
n = children->item(index);
insertBefore(cell, n, ec);
}
- return cell;
+ return cell.release();
}
void HTMLTableRowElement::deleteCell(int index, ExceptionCode& ec)
{
- Ref<HTMLCollection> children = cells();
- int numCells = children->length();
+ RefPtr<HTMLCollection> children = cells();
+ int numCells = children ? children->length() : 0;
if (index == -1)
index = numCells-1;
if (index >= 0 && index < numCells) {
@@ -154,7 +154,7 @@ void HTMLTableRowElement::deleteCell(int index, ExceptionCode& ec)
ec = INDEX_SIZE_ERR;
}
-Ref<HTMLCollection> HTMLTableRowElement::cells()
+PassRefPtr<HTMLCollection> HTMLTableRowElement::cells()
{
return ensureCachedHTMLCollection(TRCells);
}
diff --git a/Source/WebCore/html/HTMLTableRowElement.h b/Source/WebCore/html/HTMLTableRowElement.h
index c997aec91..58de7678f 100644
--- a/Source/WebCore/html/HTMLTableRowElement.h
+++ b/Source/WebCore/html/HTMLTableRowElement.h
@@ -32,8 +32,8 @@ namespace WebCore {
class HTMLTableRowElement final : public HTMLTablePartElement {
public:
- static Ref<HTMLTableRowElement> create(Document&);
- static Ref<HTMLTableRowElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLTableRowElement> create(Document&);
+ static PassRefPtr<HTMLTableRowElement> create(const QualifiedName&, Document&);
int rowIndex() const;
void setRowIndex(int);
@@ -41,17 +41,18 @@ public:
int sectionRowIndex() const;
void setSectionRowIndex(int);
- RefPtr<HTMLElement> insertCell(ExceptionCode& ec) { return insertCell(-1, ec); }
- RefPtr<HTMLElement> insertCell(int index, ExceptionCode&);
+ PassRefPtr<HTMLElement> insertCell(int index, ExceptionCode&);
void deleteCell(int index, ExceptionCode&);
- Ref<HTMLCollection> cells();
+ PassRefPtr<HTMLCollection> cells();
void setCells(HTMLCollection *, ExceptionCode&);
private:
HTMLTableRowElement(const QualifiedName&, Document&);
};
+NODE_TYPE_CASTS(HTMLTableRowElement)
+
} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLTableRowElement.idl b/Source/WebCore/html/HTMLTableRowElement.idl
index b6b68f3f4..a56f70a46 100644
--- a/Source/WebCore/html/HTMLTableRowElement.idl
+++ b/Source/WebCore/html/HTMLTableRowElement.idl
@@ -27,7 +27,7 @@ interface HTMLTableRowElement : HTMLElement {
[Reflect=char] attribute DOMString ch;
[Reflect=charoff] attribute DOMString chOff;
[Reflect] attribute DOMString vAlign;
- [RaisesException] HTMLElement insertCell(optional long index);
+ [RaisesException] HTMLElement insertCell([Default=Undefined] optional long index);
[RaisesException] void deleteCell([Default=Undefined] optional long index);
};
diff --git a/Source/WebCore/html/HTMLTableRowsCollection.cpp b/Source/WebCore/html/HTMLTableRowsCollection.cpp
index bfa5f6d78..0e4ac0830 100644
--- a/Source/WebCore/html/HTMLTableRowsCollection.cpp
+++ b/Source/WebCore/html/HTMLTableRowsCollection.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -38,7 +38,7 @@ namespace WebCore {
using namespace HTMLNames;
-static inline void assertRowIsInTable(HTMLTableElement& table, HTMLTableRowElement* row)
+static inline void assertRowIsInTable(HTMLTableElement* table, HTMLTableRowElement* row)
{
#if !ASSERT_DISABLED
UNUSED_PARAM(table);
@@ -46,29 +46,30 @@ static inline void assertRowIsInTable(HTMLTableElement& table, HTMLTableRowEleme
#else
if (!row)
return;
- if (row->parentNode() == &table)
+ if (row->parentNode() == table)
return;
ASSERT(row->parentNode());
ASSERT(row->parentNode()->hasTagName(theadTag) || row->parentNode()->hasTagName(tbodyTag) || row->parentNode()->hasTagName(tfootTag));
- ASSERT(row->parentNode()->parentNode() == &table);
+ ASSERT(row->parentNode()->parentNode() == table);
#endif
}
-static inline bool isInSection(HTMLTableRowElement& row, const HTMLQualifiedName& sectionTag)
+static inline bool isInSection(HTMLTableRowElement* row, const QualifiedName& sectionTag)
{
- // Because we know that the parent is a table or a section, it's safe to cast it to an HTMLElement
- // giving us access to the faster hasTagName overload from that class.
- return downcast<HTMLElement>(*row.parentNode()).hasTagName(sectionTag);
+ // Because we know that the parent is a table or a section, all of which are in the HTML
+ // namespace, it's OK to do the faster hasLocalName here instead of the more typical hasTagName,
+ // since we don't need the check for the HTML namespace.
+ return toElement(row->parentNode())->hasLocalName(sectionTag);
}
-HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement& table, HTMLTableRowElement* previous)
+HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement* table, HTMLTableRowElement* previous)
{
// The HTMLCollection caching mechanism, along with the code in this class, will guarantee that the previous row
// is an immediate child of either the table, or a table section that is itself an immediate child of the table.
assertRowIsInTable(table, previous);
// Start by looking for the next row in this section. Continue only if there is none.
- if (previous && previous->parentNode() != &table) {
+ if (previous && previous->parentNode() != table) {
auto childRows = childrenOfType<HTMLTableRowElement>(*previous->parentNode());
auto row = childRows.beginAt(*previous);
if (++row != childRows.end())
@@ -80,9 +81,9 @@ HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement& table,
// If still looking at head sections, find the first row in the next head section.
if (!previous)
child = ElementTraversal::firstChild(table);
- else if (isInSection(*previous, theadTag))
- child = ElementTraversal::nextSibling(*previous->parentNode());
- for (; child; child = ElementTraversal::nextSibling(*child)) {
+ else if (isInSection(previous, theadTag))
+ child = ElementTraversal::nextSibling(previous->parentNode());
+ for (; child; child = ElementTraversal::nextSibling(child)) {
if (child->hasTagName(theadTag)) {
if (auto row = childrenOfType<HTMLTableRowElement>(*child).first())
return row;
@@ -90,15 +91,15 @@ HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement& table,
}
// If still looking at top level and bodies, find the next row in top level or the first in the next body section.
- if (!previous || isInSection(*previous, theadTag))
+ if (!previous || isInSection(previous, theadTag))
child = ElementTraversal::firstChild(table);
- else if (previous->parentNode() == &table)
- child = ElementTraversal::nextSibling(*previous);
- else if (isInSection(*previous, tbodyTag))
- child = ElementTraversal::nextSibling(*previous->parentNode());
- for (; child; child = ElementTraversal::nextSibling(*child)) {
- if (is<HTMLTableRowElement>(*child))
- return downcast<HTMLTableRowElement>(child);
+ else if (previous->parentNode() == table)
+ child = ElementTraversal::nextSibling(previous);
+ else if (isInSection(previous, tbodyTag))
+ child = ElementTraversal::nextSibling(previous->parentNode());
+ for (; child; child = ElementTraversal::nextSibling(child)) {
+ if (isHTMLTableRowElement(child))
+ return toHTMLTableRowElement(child);
if (child->hasTagName(tbodyTag)) {
if (auto row = childrenOfType<HTMLTableRowElement>(*child).first())
return row;
@@ -106,11 +107,11 @@ HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement& table,
}
// Find the first row in the next foot section.
- if (!previous || !isInSection(*previous, tfootTag))
+ if (!previous || !isInSection(previous, tfootTag))
child = ElementTraversal::firstChild(table);
else
- child = ElementTraversal::nextSibling(*previous->parentNode());
- for (; child; child = ElementTraversal::nextSibling(*child)) {
+ child = ElementTraversal::nextSibling(previous->parentNode());
+ for (; child; child = ElementTraversal::nextSibling(child)) {
if (child->hasTagName(tfootTag)) {
if (auto row = childrenOfType<HTMLTableRowElement>(*child).first())
return row;
@@ -120,27 +121,27 @@ HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement& table,
return nullptr;
}
-HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement& table)
+HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table)
{
- for (auto* child = ElementTraversal::lastChild(table); child; child = ElementTraversal::previousSibling(*child)) {
+ for (auto child = ElementTraversal::lastChild(table); child; child = ElementTraversal::previousSibling(child)) {
if (child->hasTagName(tfootTag)) {
- if (auto* row = childrenOfType<HTMLTableRowElement>(*child).last())
+ if (auto row = childrenOfType<HTMLTableRowElement>(*child).last())
return row;
}
}
- for (auto* child = ElementTraversal::lastChild(table); child; child = ElementTraversal::previousSibling(*child)) {
- if (is<HTMLTableRowElement>(*child))
- return downcast<HTMLTableRowElement>(child);
+ for (auto child = ElementTraversal::lastChild(table); child; child = ElementTraversal::previousSibling(child)) {
+ if (isHTMLTableRowElement(child))
+ return toHTMLTableRowElement(child);
if (child->hasTagName(tbodyTag)) {
- if (auto* row = childrenOfType<HTMLTableRowElement>(*child).last())
+ if (auto row = childrenOfType<HTMLTableRowElement>(*child).last())
return row;
}
}
- for (auto* child = ElementTraversal::lastChild(table); child; child = ElementTraversal::previousSibling(*child)) {
+ for (auto child = ElementTraversal::lastChild(table); child; child = ElementTraversal::previousSibling(child)) {
if (child->hasTagName(theadTag)) {
- if (auto* row = childrenOfType<HTMLTableRowElement>(*child).last())
+ if (auto row = childrenOfType<HTMLTableRowElement>(*child).last())
return row;
}
}
@@ -153,7 +154,7 @@ HTMLTableRowsCollection::HTMLTableRowsCollection(HTMLTableElement& table)
{
}
-Ref<HTMLTableRowsCollection> HTMLTableRowsCollection::create(HTMLTableElement& table, CollectionType type)
+PassRef<HTMLTableRowsCollection> HTMLTableRowsCollection::create(HTMLTableElement& table, CollectionType type)
{
ASSERT_UNUSED(type, type == TableRows);
return adoptRef(*new HTMLTableRowsCollection(table));
@@ -161,7 +162,7 @@ Ref<HTMLTableRowsCollection> HTMLTableRowsCollection::create(HTMLTableElement& t
Element* HTMLTableRowsCollection::customElementAfter(Element* previous) const
{
- return rowAfter(const_cast<HTMLTableElement&>(tableElement()), downcast<HTMLTableRowElement>(previous));
+ return rowAfter(const_cast<HTMLTableElement*>(&tableElement()), toHTMLTableRowElement(previous));
}
}
diff --git a/Source/WebCore/html/HTMLTableRowsCollection.h b/Source/WebCore/html/HTMLTableRowsCollection.h
index 9eb5fa6a7..5f4fdf100 100644
--- a/Source/WebCore/html/HTMLTableRowsCollection.h
+++ b/Source/WebCore/html/HTMLTableRowsCollection.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -38,13 +38,13 @@ class HTMLTableRowElement;
class HTMLTableRowsCollection final : public HTMLCollection {
public:
- static Ref<HTMLTableRowsCollection> create(HTMLTableElement&, CollectionType);
+ static PassRef<HTMLTableRowsCollection> create(HTMLTableElement&, CollectionType);
- HTMLTableElement& tableElement() { return downcast<HTMLTableElement>(ownerNode()); }
- const HTMLTableElement& tableElement() const { return downcast<HTMLTableElement>(ownerNode()); }
+ HTMLTableElement& tableElement() { return toHTMLTableElement(ownerNode()); }
+ const HTMLTableElement& tableElement() const { return toHTMLTableElement(ownerNode()); }
- static HTMLTableRowElement* rowAfter(HTMLTableElement&, HTMLTableRowElement*);
- static HTMLTableRowElement* lastRow(HTMLTableElement&);
+ static HTMLTableRowElement* rowAfter(HTMLTableElement*, HTMLTableRowElement*);
+ static HTMLTableRowElement* lastRow(HTMLTableElement*);
private:
explicit HTMLTableRowsCollection(HTMLTableElement&);
@@ -52,8 +52,6 @@ private:
virtual Element* customElementAfter(Element*) const override;
};
-} // namespace WebCore
+} // namespace
-SPECIALIZE_TYPE_TRAITS_HTMLCOLLECTION(HTMLTableRowsCollection, TableRows)
-
-#endif // HTMLTableRowsCollection_h
+#endif
diff --git a/Source/WebCore/html/HTMLTableSectionElement.cpp b/Source/WebCore/html/HTMLTableSectionElement.cpp
index f75717e59..32b8396f4 100644
--- a/Source/WebCore/html/HTMLTableSectionElement.cpp
+++ b/Source/WebCore/html/HTMLTableSectionElement.cpp
@@ -42,9 +42,9 @@ inline HTMLTableSectionElement::HTMLTableSectionElement(const QualifiedName& tag
{
}
-Ref<HTMLTableSectionElement> HTMLTableSectionElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLTableSectionElement> HTMLTableSectionElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLTableSectionElement(tagName, document));
+ return adoptRef(new HTMLTableSectionElement(tagName, document));
}
const StyleProperties* HTMLTableSectionElement::additionalPresentationAttributeStyle()
@@ -56,11 +56,11 @@ const StyleProperties* HTMLTableSectionElement::additionalPresentationAttributeS
// these functions are rather slow, since we need to get the row at
// the index... but they aren't used during usual HTML parsing anyway
-RefPtr<HTMLElement> HTMLTableSectionElement::insertRow(int index, ExceptionCode& ec)
+PassRefPtr<HTMLElement> HTMLTableSectionElement::insertRow(int index, ExceptionCode& ec)
{
RefPtr<HTMLTableRowElement> row;
- Ref<HTMLCollection> children = rows();
- int numRows = children->length();
+ RefPtr<HTMLCollection> children = rows();
+ int numRows = children ? (int)children->length() : 0;
if (index < -1 || index > numRows)
ec = INDEX_SIZE_ERR; // per the DOM
else {
@@ -76,13 +76,13 @@ RefPtr<HTMLElement> HTMLTableSectionElement::insertRow(int index, ExceptionCode&
insertBefore(row, n, ec);
}
}
- return row;
+ return row.release();
}
void HTMLTableSectionElement::deleteRow(int index, ExceptionCode& ec)
{
- Ref<HTMLCollection> children = rows();
- int numRows = children->length();
+ RefPtr<HTMLCollection> children = rows();
+ int numRows = children ? (int)children->length() : 0;
if (index == -1)
index = numRows - 1;
if (index >= 0 && index < numRows) {
@@ -105,47 +105,47 @@ int HTMLTableSectionElement::numRows() const
return rows;
}
-const AtomicString& HTMLTableSectionElement::align() const
+String HTMLTableSectionElement::align() const
{
- return fastGetAttribute(alignAttr);
+ return getAttribute(alignAttr);
}
-void HTMLTableSectionElement::setAlign(const AtomicString& value)
+void HTMLTableSectionElement::setAlign(const String &value)
{
setAttribute(alignAttr, value);
}
-const AtomicString& HTMLTableSectionElement::ch() const
+String HTMLTableSectionElement::ch() const
{
- return fastGetAttribute(charAttr);
+ return getAttribute(charAttr);
}
-void HTMLTableSectionElement::setCh(const AtomicString& value)
+void HTMLTableSectionElement::setCh(const String &value)
{
setAttribute(charAttr, value);
}
-const AtomicString& HTMLTableSectionElement::chOff() const
+String HTMLTableSectionElement::chOff() const
{
return getAttribute(charoffAttr);
}
-void HTMLTableSectionElement::setChOff(const AtomicString& value)
+void HTMLTableSectionElement::setChOff(const String &value)
{
setAttribute(charoffAttr, value);
}
-const AtomicString& HTMLTableSectionElement::vAlign() const
+String HTMLTableSectionElement::vAlign() const
{
- return fastGetAttribute(valignAttr);
+ return getAttribute(valignAttr);
}
-void HTMLTableSectionElement::setVAlign(const AtomicString& value)
+void HTMLTableSectionElement::setVAlign(const String &value)
{
setAttribute(valignAttr, value);
}
-Ref<HTMLCollection> HTMLTableSectionElement::rows()
+PassRefPtr<HTMLCollection> HTMLTableSectionElement::rows()
{
return ensureCachedHTMLCollection(TSectionRows);
}
diff --git a/Source/WebCore/html/HTMLTableSectionElement.h b/Source/WebCore/html/HTMLTableSectionElement.h
index 0c1440011..7825e6864 100644
--- a/Source/WebCore/html/HTMLTableSectionElement.h
+++ b/Source/WebCore/html/HTMLTableSectionElement.h
@@ -33,27 +33,26 @@ namespace WebCore {
class HTMLTableSectionElement final : public HTMLTablePartElement {
public:
- static Ref<HTMLTableSectionElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLTableSectionElement> create(const QualifiedName&, Document&);
- RefPtr<HTMLElement> insertRow(ExceptionCode& ec) { return insertRow(-1, ec); }
- RefPtr<HTMLElement> insertRow(int index, ExceptionCode&);
+ PassRefPtr<HTMLElement> insertRow(int index, ExceptionCode&);
void deleteRow(int index, ExceptionCode&);
int numRows() const;
- const AtomicString& align() const;
- void setAlign(const AtomicString&);
+ String align() const;
+ void setAlign(const String&);
- const AtomicString& ch() const;
- void setCh(const AtomicString&);
+ String ch() const;
+ void setCh(const String&);
- const AtomicString& chOff() const;
- void setChOff(const AtomicString&);
+ String chOff() const;
+ void setChOff(const String&);
- const AtomicString& vAlign() const;
- void setVAlign(const AtomicString&);
+ String vAlign() const;
+ void setVAlign(const String&);
- Ref<HTMLCollection> rows();
+ PassRefPtr<HTMLCollection> rows();
private:
HTMLTableSectionElement(const QualifiedName& tagName, Document&);
@@ -61,11 +60,13 @@ private:
virtual const StyleProperties* additionalPresentationAttributeStyle() override;
};
-} // namespace WebCore
+inline bool isHTMLTableSectionElement(const Node& node)
+{
+ return node.hasTagName(HTMLNames::theadTag) || node.hasTagName(HTMLNames::tfootTag) || node.hasTagName(HTMLNames::tbodyTag);
+}
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLTableSectionElement)
- static bool isType(const WebCore::HTMLElement& element) { return element.hasTagName(WebCore::HTMLNames::theadTag) || element.hasTagName(WebCore::HTMLNames::tfootTag) || element.hasTagName(WebCore::HTMLNames::tbodyTag); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::HTMLElement>(node) && isType(downcast<WebCore::HTMLElement>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+NODE_TYPE_CASTS(HTMLTableSectionElement)
+
+} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLTableSectionElement.idl b/Source/WebCore/html/HTMLTableSectionElement.idl
index e9ae2a500..c66d806c2 100644
--- a/Source/WebCore/html/HTMLTableSectionElement.idl
+++ b/Source/WebCore/html/HTMLTableSectionElement.idl
@@ -26,7 +26,7 @@
[Reflect=charoff] attribute DOMString chOff;
[Reflect] attribute DOMString vAlign;
readonly attribute HTMLCollection rows;
- [RaisesException] HTMLElement insertRow(optional long index);
+ [RaisesException] HTMLElement insertRow([Default=Undefined] optional long index);
[RaisesException] void deleteRow([Default=Undefined] optional long index);
};
diff --git a/Source/WebCore/html/HTMLTagNames.in b/Source/WebCore/html/HTMLTagNames.in
index 91387b053..09f682735 100644
--- a/Source/WebCore/html/HTMLTagNames.in
+++ b/Source/WebCore/html/HTMLTagNames.in
@@ -3,29 +3,28 @@ namespacePrefix="xhtml"
namespaceURI="http://www.w3.org/1999/xhtml"
fallbackInterfaceName="HTMLUnknownElement"
-a interfaceName=HTMLAnchorElement
+a interfaceName=HTMLAnchorElement, generateTypeHelpers
abbr interfaceName=HTMLElement
acronym interfaceName=HTMLElement
address interfaceName=HTMLElement
-applet constructorNeedsCreatedByParser
-area
+applet constructorNeedsCreatedByParser, generateTypeHelpers
+area generateTypeHelpers
article interfaceName=HTMLElement
aside interfaceName=HTMLElement
-attachment conditional=ATTACHMENT_ELEMENT, settingsConditional=attachmentElementEnabled
-audio wrapperOnlyIfMediaIsAvailable, conditional=VIDEO, constructorNeedsCreatedByParser, customTypeHelper
+audio wrapperOnlyIfMediaIsAvailable, conditional=VIDEO, constructorNeedsCreatedByParser, generateTypeHelpers
b interfaceName=HTMLElement
-base
+base generateTypeHelpers
basefont interfaceName=HTMLBaseFontElement
bdi interfaceName=HTMLBDIElement, JSInterfaceName=HTMLElement
bdo interfaceName=HTMLElement
bgsound interfaceName=HTMLElement
big interfaceName=HTMLElement
blockquote interfaceName=HTMLQuoteElement
-body
+body generateTypeHelpers
br interfaceName=HTMLBRElement
button constructorNeedsFormElement
-canvas
-caption interfaceName=HTMLTableCaptionElement
+canvas generateTypeHelpers
+caption interfaceName=HTMLTableCaptionElement, generateTypeHelpers
center interfaceName=HTMLElement
cite interfaceName=HTMLElement
code interfaceName=HTMLElement
@@ -33,110 +32,107 @@ col interfaceName=HTMLTableColElement
colgroup interfaceName=HTMLTableColElement
command interfaceName=HTMLElement
webkitShadowContent interfaceName=HTMLElement, noConstructor
-datalist interfaceName=HTMLDataListElement, conditional=DATALIST_ELEMENT
+datalist interfaceName=HTMLDataListElement, conditional=DATALIST_ELEMENT, generateTypeHelpers
dd interfaceName=HTMLElement
del interfaceName=HTMLModElement
-details conditional=DETAILS_ELEMENT
+details conditional=DETAILS_ELEMENT, generateTypeHelpers
dfn interfaceName=HTMLElement
dir interfaceName=HTMLDirectoryElement
div
dl interfaceName=HTMLDListElement
dt interfaceName=HTMLElement
em interfaceName=HTMLElement
-embed constructorNeedsCreatedByParser
-fieldset interfaceName=HTMLFieldSetElement, constructorNeedsFormElement
+embed constructorNeedsCreatedByParser, generateTypeHelpers
+fieldset interfaceName=HTMLFieldSetElement, constructorNeedsFormElement, generateTypeHelpers
figcaption interfaceName=HTMLElement
figure interfaceName=HTMLElement
font
footer interfaceName=HTMLElement
-form
-frame
-frameset interfaceName=HTMLFrameSetElement
+form generateTypeHelpers
+frame generateTypeHelpers
+frameset interfaceName=HTMLFrameSetElement, generateTypeHelpers
h1 interfaceName=HTMLHeadingElement
h2 interfaceName=HTMLHeadingElement
h3 interfaceName=HTMLHeadingElement
h4 interfaceName=HTMLHeadingElement
h5 interfaceName=HTMLHeadingElement
h6 interfaceName=HTMLHeadingElement
-head
+head generateTypeHelpers
header interfaceName=HTMLElement
hgroup interfaceName=HTMLElement
hr interfaceName=HTMLHRElement
-html
+html generateTypeHelpers
i interfaceName=HTMLElement
-iframe interfaceName=HTMLIFrameElement
-image interfaceName=HTMLUnknownElement
-img interfaceName=HTMLImageElement, constructorNeedsFormElement
-input constructorNeedsFormElement, constructorNeedsCreatedByParser
+iframe interfaceName=HTMLIFrameElement, generateTypeHelpers
+image interfaceName=HTMLElement
+img interfaceName=HTMLImageElement, constructorNeedsFormElement, generateTypeHelpers
+input constructorNeedsFormElement, constructorNeedsCreatedByParser, generateTypeHelpers
ins interfaceName=HTMLModElement
isindex interfaceName=HTMLUnknownElement
kbd interfaceName=HTMLElement
keygen constructorNeedsFormElement
-label
+label generateTypeHelpers
layer interfaceName=HTMLElement
-legend
+legend generateTypeHelpers
li interfaceName=HTMLLIElement
-link constructorNeedsCreatedByParser
+link constructorNeedsCreatedByParser, generateTypeHelpers
listing interfaceName=HTMLPreElement
main interfaceName=HTMLElement
-map
+map generateTypeHelpers
mark interfaceName=HTMLElement
-marquee
+marquee generateTypeHelpers
menu
-meta
-meter interfaceName=HTMLMeterElement, conditional=METER_ELEMENT
+meta generateTypeHelpers
+meter interfaceName=HTMLMeterElement, conditional=METER_ELEMENT, generateTypeHelpers
nav interfaceName=HTMLElement
nobr interfaceName=HTMLElement
noembed interfaceName=HTMLElement
noframes interfaceName=HTMLElement
nolayer interfaceName=HTMLElement
-object constructorNeedsFormElement, constructorNeedsCreatedByParser
-ol interfaceName=HTMLOListElement
-optgroup interfaceName=HTMLOptGroupElement
-option
+object constructorNeedsFormElement, constructorNeedsCreatedByParser, generateTypeHelpers
+ol interfaceName=HTMLOListElement, generateTypeHelpers
+optgroup interfaceName=HTMLOptGroupElement, generateTypeHelpers
+option generateTypeHelpers
output constructorNeedsFormElement
p interfaceName=HTMLParagraphElement
-param
+param generateTypeHelpers
plaintext interfaceName=HTMLElement
pre
-progress interfaceName=HTMLProgressElement
+progress interfaceName=HTMLProgressElement, conditional=PROGRESS_ELEMENT, generateTypeHelpers
q interfaceName=HTMLQuoteElement
-rb interfaceName=HTMLElement
rp interfaceName=HTMLElement
-rt interfaceName=RubyTextElement, JSInterfaceName=HTMLElement
-rtc interfaceName=HTMLElement
-ruby interfaceName=RubyElement, JSInterfaceName=HTMLElement
+rt interfaceName=HTMLElement
+ruby interfaceName=HTMLElement
s interfaceName=HTMLElement
samp interfaceName=HTMLElement
-script constructorNeedsCreatedByParser
+script constructorNeedsCreatedByParser, generateTypeHelpers
section interfaceName=HTMLElement
-select constructorNeedsFormElement
+select constructorNeedsFormElement, generateTypeHelpers
small interfaceName=HTMLElement
-source wrapperOnlyIfMediaIsAvailable, conditional=VIDEO
+source wrapperOnlyIfMediaIsAvailable, conditional=VIDEO, generateTypeHelpers
span
strike interfaceName=HTMLElement
strong interfaceName=HTMLElement
-style constructorNeedsCreatedByParser
+style constructorNeedsCreatedByParser, generateTypeHelpers
sub interfaceName=HTMLElement
-summary interfaceName=HTMLSummaryElement, JSInterfaceName=HTMLElement, conditional=DETAILS_ELEMENT
+summary interfaceName=HTMLSummaryElement, JSInterfaceName=HTMLElement, conditional=DETAILS_ELEMENT, generateTypeHelpers
sup interfaceName=HTMLElement
-table
+table generateTypeHelpers
tbody interfaceName=HTMLTableSectionElement
td interfaceName=HTMLTableCellElement
-template conditional=TEMPLATE_ELEMENT
-textarea interfaceName=HTMLTextAreaElement, constructorNeedsFormElement
+template conditional=TEMPLATE_ELEMENT, generateTypeHelpers
+textarea interfaceName=HTMLTextAreaElement, constructorNeedsFormElement, generateTypeHelpers
tfoot interfaceName=HTMLTableSectionElement
th interfaceName=HTMLTableCellElement
thead interfaceName=HTMLTableSectionElement
-time interfaceName=HTMLElement
-title
-tr interfaceName=HTMLTableRowElement
-track wrapperOnlyIfMediaIsAvailable, conditional=VIDEO_TRACK
+title generateTypeHelpers
+tr interfaceName=HTMLTableRowElement, generateTypeHelpers
+track wrapperOnlyIfMediaIsAvailable, conditional=VIDEO_TRACK, generateTypeHelpers
tt interfaceName=HTMLElement
u interfaceName=HTMLElement
ul interfaceName=HTMLUListElement
var interfaceName=HTMLElement
-video wrapperOnlyIfMediaIsAvailable, conditional=VIDEO, constructorNeedsCreatedByParser, customTypeHelper
-wbr interfaceName=HTMLWBRElement, JSInterfaceName=HTMLElement
+video wrapperOnlyIfMediaIsAvailable, conditional=VIDEO, constructorNeedsCreatedByParser, generateTypeHelpers
+wbr interfaceName=HTMLElement
xmp interfaceName=HTMLPreElement
noscript interfaceName=HTMLElement
diff --git a/Source/WebCore/html/HTMLTemplateElement.cpp b/Source/WebCore/html/HTMLTemplateElement.cpp
index aec3010f6..17e4c0807 100644
--- a/Source/WebCore/html/HTMLTemplateElement.cpp
+++ b/Source/WebCore/html/HTMLTemplateElement.cpp
@@ -55,34 +55,27 @@ HTMLTemplateElement::~HTMLTemplateElement()
m_content->clearHost();
}
-Ref<HTMLTemplateElement> HTMLTemplateElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLTemplateElement> HTMLTemplateElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLTemplateElement(tagName, document));
+ return adoptRef(new HTMLTemplateElement(tagName, document));
}
DocumentFragment* HTMLTemplateElement::content() const
{
if (!m_content)
- m_content = TemplateContentDocumentFragment::create(document().ensureTemplateDocument(), this);
+ m_content = TemplateContentDocumentFragment::create(*document().ensureTemplateDocument(), this);
return m_content.get();
}
-RefPtr<Node> HTMLTemplateElement::cloneNodeInternal(Document& targetDocument, CloningOperation type)
+PassRefPtr<Node> HTMLTemplateElement::cloneNode(bool deep)
{
- RefPtr<Node> clone;
- switch (type) {
- case CloningOperation::OnlySelf:
- return cloneElementWithoutChildren(targetDocument);
- case CloningOperation::SelfWithTemplateContent:
- clone = cloneElementWithoutChildren(targetDocument);
- break;
- case CloningOperation::Everything:
- clone = cloneElementWithChildren(targetDocument);
- break;
- }
+ if (!deep)
+ return cloneElementWithoutChildren();
+
+ RefPtr<Node> clone = cloneElementWithChildren();
if (m_content)
- content()->cloneChildNodes(downcast<HTMLTemplateElement>(clone.get())->content());
+ content()->cloneChildNodes(toHTMLTemplateElement(clone.get())->content());
return clone.release();
}
@@ -91,7 +84,7 @@ void HTMLTemplateElement::didMoveToNewDocument(Document* oldDocument)
HTMLElement::didMoveToNewDocument(oldDocument);
if (!m_content)
return;
- document().ensureTemplateDocument().adoptIfNeeded(m_content.get());
+ document().ensureTemplateDocument()->adoptIfNeeded(m_content.get());
}
} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLTemplateElement.h b/Source/WebCore/html/HTMLTemplateElement.h
index 767f2a184..d7ff951b7 100644
--- a/Source/WebCore/html/HTMLTemplateElement.h
+++ b/Source/WebCore/html/HTMLTemplateElement.h
@@ -42,7 +42,7 @@ class TemplateContentDocumentFragment;
class HTMLTemplateElement final : public HTMLElement {
public:
- static Ref<HTMLTemplateElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLTemplateElement> create(const QualifiedName&, Document&);
virtual ~HTMLTemplateElement();
DocumentFragment* content() const;
@@ -50,12 +50,14 @@ public:
private:
HTMLTemplateElement(const QualifiedName&, Document&);
- virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override;
+ virtual PassRefPtr<Node> cloneNode(bool deep) override;
virtual void didMoveToNewDocument(Document* oldDocument) override;
mutable RefPtr<TemplateContentDocumentFragment> m_content;
};
+NODE_TYPE_CASTS(HTMLTemplateElement)
+
} // namespace WebCore
#endif // ENABLE(TEMPLATE_ELEMENT)
diff --git a/Source/WebCore/html/HTMLTextAreaElement.cpp b/Source/WebCore/html/HTMLTextAreaElement.cpp
index 939291155..d40d4e810 100644
--- a/Source/WebCore/html/HTMLTextAreaElement.cpp
+++ b/Source/WebCore/html/HTMLTextAreaElement.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
*
@@ -26,6 +26,7 @@
#include "config.h"
#include "HTMLTextAreaElement.h"
+#include "Attribute.h"
#include "BeforeTextInsertedEvent.h"
#include "CSSValueKeywords.h"
#include "Document.h"
@@ -100,22 +101,21 @@ HTMLTextAreaElement::HTMLTextAreaElement(const QualifiedName& tagName, Document&
setFormControlValueMatchesRenderer(true);
}
-Ref<HTMLTextAreaElement> HTMLTextAreaElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
+PassRefPtr<HTMLTextAreaElement> HTMLTextAreaElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
{
- Ref<HTMLTextAreaElement> textArea = adoptRef(*new HTMLTextAreaElement(tagName, document, form));
+ RefPtr<HTMLTextAreaElement> textArea = adoptRef(new HTMLTextAreaElement(tagName, document, form));
textArea->ensureUserAgentShadowRoot();
- return textArea;
+ return textArea.release();
}
void HTMLTextAreaElement::didAddUserAgentShadowRoot(ShadowRoot* root)
{
root->appendChild(TextControlInnerTextElement::create(document()), ASSERT_NO_EXCEPTION);
- updateInnerTextElementEditability();
}
const AtomicString& HTMLTextAreaElement::formControlType() const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, textarea, ("textarea", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, textarea, ("textarea", AtomicString::ConstructFromLiteral));
return textarea;
}
@@ -204,14 +204,14 @@ void HTMLTextAreaElement::parseAttribute(const QualifiedName& name, const Atomic
} else if (name == accesskeyAttr) {
// ignore for the moment
} else if (name == maxlengthAttr)
- updateValidity();
+ setNeedsValidityCheck();
else
HTMLTextFormControlElement::parseAttribute(name, value);
}
-RenderPtr<RenderElement> HTMLTextAreaElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLTextAreaElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderTextControlMultiLine>(*this, WTF::move(style));
+ return createRenderer<RenderTextControlMultiLine>(*this, std::move(style));
}
bool HTMLTextAreaElement::appendFormData(FormDataList& encoding, bool)
@@ -257,9 +257,9 @@ void HTMLTextAreaElement::updateFocusAppearance(bool restorePreviousSelection)
// If this is the first focus, set a caret at the beginning of the text.
// This matches some browsers' behavior; see bug 11746 Comment #15.
// http://bugs.webkit.org/show_bug.cgi?id=11746#c15
- setSelectionRange(0, 0, SelectionHasNoDirection, Element::defaultFocusTextStateChangeIntent());
+ setSelectionRange(0, 0);
} else
- restoreCachedSelection(Element::defaultFocusTextStateChangeIntent());
+ restoreCachedSelection();
if (document().frame())
document().frame()->selection().revealSelection();
@@ -269,8 +269,8 @@ void HTMLTextAreaElement::defaultEventHandler(Event* event)
{
if (renderer() && (event->isMouseEvent() || event->isDragEvent() || event->eventInterface() == WheelEventInterfaceType || event->type() == eventNames().blurEvent))
forwardEvent(event);
- else if (renderer() && is<BeforeTextInsertedEvent>(*event))
- handleBeforeTextInsertedEvent(downcast<BeforeTextInsertedEvent>(event));
+ else if (renderer() && event->isBeforeTextInsertedEvent())
+ handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(event));
HTMLTextFormControlElement::defaultEventHandler(event);
}
@@ -279,7 +279,7 @@ void HTMLTextAreaElement::subtreeHasChanged()
{
setChangedSinceLastFormControlChangeEvent(true);
setFormControlValueMatchesRenderer(false);
- updateValidity();
+ setNeedsValidityCheck();
if (!focused())
return;
@@ -325,7 +325,8 @@ String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue,
TextControlInnerTextElement* HTMLTextAreaElement::innerTextElement() const
{
- return downcast<TextControlInnerTextElement>(userAgentShadowRoot()->firstChild());
+ Node* node = userAgentShadowRoot()->firstChild();
+ return toTextControlInnerTextElement(node);
}
void HTMLTextAreaElement::rendererWillBeDestroyed()
@@ -341,9 +342,10 @@ void HTMLTextAreaElement::updateValue() const
ASSERT(renderer());
m_value = innerTextValue();
const_cast<HTMLTextAreaElement*>(this)->setFormControlValueMatchesRenderer(true);
+ const_cast<HTMLTextAreaElement*>(this)->notifyFormStateChanged();
m_isDirty = true;
m_wasModifiedByUser = true;
- const_cast<HTMLTextAreaElement*>(this)->updatePlaceholderVisibility();
+ const_cast<HTMLTextAreaElement*>(this)->updatePlaceholderVisibility(false);
}
String HTMLTextAreaElement::value() const
@@ -356,14 +358,14 @@ void HTMLTextAreaElement::setValue(const String& value)
{
setValueCommon(value);
m_isDirty = true;
- updateValidity();
+ setNeedsValidityCheck();
}
void HTMLTextAreaElement::setNonDirtyValue(const String& value)
{
setValueCommon(value);
m_isDirty = false;
- updateValidity();
+ setNeedsValidityCheck();
}
void HTMLTextAreaElement::setValueCommon(const String& newValue)
@@ -383,7 +385,7 @@ void HTMLTextAreaElement::setValueCommon(const String& newValue)
m_value = normalizedValue;
setInnerTextValue(m_value);
setLastChangeWasNotUserEdit();
- updatePlaceholderVisibility();
+ updatePlaceholderVisibility(false);
setNeedsStyleRecalc();
setFormControlValueMatchesRenderer(true);
@@ -393,12 +395,13 @@ void HTMLTextAreaElement::setValueCommon(const String& newValue)
setSelectionRange(endOfString, endOfString);
}
+ notifyFormStateChanged();
setTextAsOfLastFormControlChangeEvent(normalizedValue);
}
String HTMLTextAreaElement::defaultValue() const
{
- return TextNodeTraversal::contentsAsString(*this);
+ return TextNodeTraversal::contentsAsString(this);
}
void HTMLTextAreaElement::setDefaultValue(const String& defaultValue)
@@ -407,7 +410,7 @@ void HTMLTextAreaElement::setDefaultValue(const String& defaultValue)
// To preserve comments, remove only the text nodes, then add a single text node.
Vector<RefPtr<Text>> textNodes;
- for (Text* textNode = TextNodeTraversal::firstChild(*this); textNode; textNode = TextNodeTraversal::nextSibling(*textNode))
+ for (Text* textNode = TextNodeTraversal::firstChild(this); textNode; textNode = TextNodeTraversal::nextSibling(textNode))
textNodes.append(textNode);
size_t size = textNodes.size();
@@ -428,7 +431,7 @@ void HTMLTextAreaElement::setDefaultValue(const String& defaultValue)
int HTMLTextAreaElement::maxLength() const
{
bool ok;
- int value = fastGetAttribute(maxlengthAttr).string().toInt(&ok);
+ int value = getAttribute(maxlengthAttr).string().toInt(&ok);
return ok && value >= 0 ? value : -1;
}
@@ -513,6 +516,11 @@ HTMLElement* HTMLTextAreaElement::placeholderElement() const
return m_placeholder;
}
+bool HTMLTextAreaElement::matchesReadOnlyPseudoClass() const
+{
+ return isReadOnly();
+}
+
bool HTMLTextAreaElement::matchesReadWritePseudoClass() const
{
return !isDisabledOrReadOnly();
@@ -532,7 +540,6 @@ void HTMLTextAreaElement::updatePlaceholderText()
RefPtr<HTMLDivElement> placeholder = HTMLDivElement::create(document());
m_placeholder = placeholder.get();
m_placeholder->setPseudo(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
- m_placeholder->setInlineStyleProperty(CSSPropertyDisplay, isPlaceholderVisible() ? CSSValueBlock : CSSValueNone, true);
userAgentShadowRoot()->insertBefore(m_placeholder, innerTextElement()->nextSibling());
}
m_placeholder->setInnerText(placeholderText, ASSERT_NO_EXCEPTION);
diff --git a/Source/WebCore/html/HTMLTextAreaElement.h b/Source/WebCore/html/HTMLTextAreaElement.h
index c358cc103..7620706c0 100644
--- a/Source/WebCore/html/HTMLTextAreaElement.h
+++ b/Source/WebCore/html/HTMLTextAreaElement.h
@@ -33,15 +33,15 @@ class VisibleSelection;
class HTMLTextAreaElement final : public HTMLTextFormControlElement {
public:
- static Ref<HTMLTextAreaElement> create(const QualifiedName&, Document&, HTMLFormElement*);
+ static PassRefPtr<HTMLTextAreaElement> create(const QualifiedName&, Document&, HTMLFormElement*);
int cols() const { return m_cols; }
int rows() const { return m_rows; }
bool shouldWrapText() const { return m_wrap != NoWrap; }
- WEBCORE_EXPORT virtual String value() const override;
- WEBCORE_EXPORT void setValue(const String&);
+ virtual String value() const override;
+ void setValue(const String&);
String defaultValue() const;
void setDefaultValue(const String&);
int textLength() const { return value().length(); }
@@ -68,6 +68,7 @@ private:
enum WrapMethod { NoWrap, SoftWrap, HardWrap };
virtual void didAddUserAgentShadowRoot(ShadowRoot*) override;
+ virtual bool areAuthorShadowsAllowed() const override { return false; }
void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) const;
static String sanitizeUserInputValue(const String&, unsigned maxLength);
@@ -101,7 +102,7 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
virtual bool isPresentationAttribute(const QualifiedName&) const override;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual bool appendFormData(FormDataList&, bool) override;
virtual void reset() override;
virtual bool hasCustomFocusLogic() const override;
@@ -112,6 +113,7 @@ private:
virtual void accessKeyAction(bool sendMouseEvents) override;
virtual bool shouldUseInputMethod() override;
+ virtual bool matchesReadOnlyPseudoClass() const override;
virtual bool matchesReadWritePseudoClass() const override;
bool valueMissing(const String& value) const { return isRequiredFormControl() && !isDisabledOrReadOnly() && value.isEmpty(); }
@@ -126,6 +128,8 @@ private:
mutable bool m_wasModifiedByUser;
};
+NODE_TYPE_CASTS(HTMLTextAreaElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLTextFormControlElement.cpp b/Source/WebCore/html/HTMLTextFormControlElement.cpp
index d665ca31b..af222e4ac 100644
--- a/Source/WebCore/html/HTMLTextFormControlElement.cpp
+++ b/Source/WebCore/html/HTMLTextFormControlElement.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
*
* This library is free software; you can redistribute it and/or
@@ -26,10 +26,12 @@
#include "HTMLTextFormControlElement.h"
#include "AXObjectCache.h"
+#include "Attribute.h"
#include "ChromeClient.h"
#include "Document.h"
#include "Event.h"
#include "EventNames.h"
+#include "FeatureObserver.h"
#include "Frame.h"
#include "FrameSelection.h"
#include "HTMLBRElement.h"
@@ -37,7 +39,6 @@
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "NodeTraversal.h"
-#include "Page.h"
#include "RenderBlockFlow.h"
#include "RenderTextControlSingleLine.h"
#include "RenderTheme.h"
@@ -51,15 +52,12 @@ namespace WebCore {
using namespace HTMLNames;
-static Position positionForIndex(TextControlInnerTextElement*, unsigned);
-
HTMLTextFormControlElement::HTMLTextFormControlElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
: HTMLFormControlElementWithState(tagName, document, form)
+ , m_lastChangeWasUserEdit(false)
, m_cachedSelectionStart(-1)
, m_cachedSelectionEnd(-1)
, m_cachedSelectionDirection(SelectionHasNoDirection)
- , m_lastChangeWasUserEdit(false)
- , m_isPlaceholderVisible(false)
{
}
@@ -78,37 +76,39 @@ bool HTMLTextFormControlElement::childShouldCreateRenderer(const Node& child) co
Node::InsertionNotificationRequest HTMLTextFormControlElement::insertedInto(ContainerNode& insertionPoint)
{
- InsertionNotificationRequest insertionNotificationRequest = HTMLFormControlElementWithState::insertedInto(insertionPoint);
+ HTMLFormControlElementWithState::insertedInto(insertionPoint);
if (!insertionPoint.inDocument())
- return insertionNotificationRequest;
+ return InsertionDone;
String initialValue = value();
setTextAsOfLastFormControlChangeEvent(initialValue.isNull() ? emptyString() : initialValue);
- return insertionNotificationRequest;
+ return InsertionDone;
}
-void HTMLTextFormControlElement::dispatchFocusEvent(RefPtr<Element>&& oldFocusedElement, FocusDirection direction)
+void HTMLTextFormControlElement::dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection direction)
{
if (supportsPlaceholder())
- updatePlaceholderVisibility();
+ updatePlaceholderVisibility(false);
handleFocusEvent(oldFocusedElement.get(), direction);
- HTMLFormControlElementWithState::dispatchFocusEvent(WTF::move(oldFocusedElement), direction);
+ HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, direction);
}
-void HTMLTextFormControlElement::dispatchBlurEvent(RefPtr<Element>&& newFocusedElement)
+void HTMLTextFormControlElement::dispatchBlurEvent(PassRefPtr<Element> newFocusedElement)
{
if (supportsPlaceholder())
- updatePlaceholderVisibility();
+ updatePlaceholderVisibility(false);
handleBlurEvent();
- HTMLFormControlElementWithState::dispatchBlurEvent(WTF::move(newFocusedElement));
+ HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement);
}
-void HTMLTextFormControlElement::didEditInnerTextValue()
+void HTMLTextFormControlElement::defaultEventHandler(Event* event)
{
- if (!isTextFormControl())
+ if (event->type() == eventNames().webkitEditableContentChangedEvent && renderer() && renderer()->isTextControl()) {
+ m_lastChangeWasUserEdit = true;
+ subtreeHasChanged();
return;
+ }
- m_lastChangeWasUserEdit = true;
- subtreeHasChanged();
+ HTMLFormControlElementWithState::defaultEventHandler(event);
}
void HTMLTextFormControlElement::forwardEvent(Event* event)
@@ -148,23 +148,24 @@ bool HTMLTextFormControlElement::isPlaceholderEmpty() const
bool HTMLTextFormControlElement::placeholderShouldBeVisible() const
{
- // This function is used by the style resolver to match the :placeholder-shown pseudo class.
- // Since it is used for styling, it must not use any value depending on the style.
- return supportsPlaceholder() && isEmptyValue() && !isPlaceholderEmpty();
+ return supportsPlaceholder()
+ && isEmptyValue()
+ && isEmptySuggestedValue()
+ && !isPlaceholderEmpty()
+ && (document().focusedElement() != this || (renderer() && renderer()->theme().shouldShowPlaceholderWhenFocused()))
+ && (!renderer() || renderer()->style().visibility() == VISIBLE);
}
-void HTMLTextFormControlElement::updatePlaceholderVisibility()
+void HTMLTextFormControlElement::updatePlaceholderVisibility(bool placeholderValueChanged)
{
- bool placeHolderWasVisible = m_isPlaceholderVisible;
- m_isPlaceholderVisible = placeholderShouldBeVisible();
-
- if (placeHolderWasVisible == m_isPlaceholderVisible)
+ if (!supportsPlaceholder())
return;
-
- setNeedsStyleRecalc();
-
- if (HTMLElement* placeholder = placeholderElement())
- placeholder->setInlineStyleProperty(CSSPropertyDisplay, m_isPlaceholderVisible ? CSSValueBlock : CSSValueNone, true);
+ if (!placeholderElement() || placeholderValueChanged)
+ updatePlaceholderText();
+ HTMLElement* placeholder = placeholderElement();
+ if (!placeholder)
+ return;
+ placeholder->setInlineStyleProperty(CSSPropertyVisibility, placeholderShouldBeVisible() ? CSSValueVisible : CSSValueHidden);
}
void HTMLTextFormControlElement::setSelectionStart(int start)
@@ -182,15 +183,15 @@ void HTMLTextFormControlElement::setSelectionDirection(const String& direction)
setSelectionRange(selectionStart(), selectionEnd(), direction);
}
-void HTMLTextFormControlElement::select(const AXTextStateChangeIntent& intent)
+void HTMLTextFormControlElement::select()
{
// FIXME: We should abstract the selection behavior into an EditingBehavior function instead
// of hardcoding the behavior using a macro define.
#if PLATFORM(IOS)
// We don't want to select all the text on iOS. Instead use the standard textfield behavior of going to the end of the line.
- setSelectionRange(std::numeric_limits<int>::max(), std::numeric_limits<int>::max(), SelectionHasForwardDirection, intent);
+ setSelectionRange(std::numeric_limits<int>::max(), std::numeric_limits<int>::max(), SelectionHasForwardDirection);
#else
- setSelectionRange(0, std::numeric_limits<int>::max(), SelectionHasNoDirection, intent);
+ setSelectionRange(0, std::numeric_limits<int>::max(), SelectionHasNoDirection);
#endif
}
@@ -210,6 +211,11 @@ void HTMLTextFormControlElement::dispatchFormControlChangeEvent()
setChangedSinceLastFormControlChangeEvent(false);
}
+static inline bool hasVisibleTextArea(RenderElement& textControl, TextControlInnerTextElement* innerText)
+{
+ return textControl.style().visibility() != HIDDEN && innerText && innerText->renderer() && innerText->renderBox()->height();
+}
+
void HTMLTextFormControlElement::setRangeText(const String& replacement, ExceptionCode& ec)
{
setRangeText(replacement, selectionStart(), selectionEnd(), String(), ec);
@@ -269,7 +275,7 @@ void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigne
setSelectionRange(newSelectionStart, newSelectionEnd, SelectionHasNoDirection);
}
-void HTMLTextFormControlElement::setSelectionRange(int start, int end, const String& directionString, const AXTextStateChangeIntent& intent)
+void HTMLTextFormControlElement::setSelectionRange(int start, int end, const String& directionString)
{
TextFieldSelectionDirection direction = SelectionHasNoDirection;
if (directionString == "forward")
@@ -277,61 +283,60 @@ void HTMLTextFormControlElement::setSelectionRange(int start, int end, const Str
else if (directionString == "backward")
direction = SelectionHasBackwardDirection;
- return setSelectionRange(start, end, direction, intent);
+ return setSelectionRange(start, end, direction);
}
-void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextFieldSelectionDirection direction, const AXTextStateChangeIntent& intent)
+void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextFieldSelectionDirection direction)
{
- if (!isTextFormControl())
+ document().updateLayoutIgnorePendingStylesheets();
+
+ if (!renderer() || !renderer()->isTextControl())
return;
end = std::max(end, 0);
start = std::min(std::max(start, 0), end);
- TextControlInnerTextElement* innerText = innerTextElement();
- bool hasFocus = document().focusedElement() == this;
- if (!hasFocus && innerText) {
- // FIXME: Removing this synchronous layout requires fixing <https://webkit.org/b/128797>
- document().updateLayoutIgnorePendingStylesheets();
- if (RenderElement* rendererTextControl = renderer()) {
- if (rendererTextControl->style().visibility() == HIDDEN || !innerText->renderBox()->height()) {
- cacheSelection(start, end, direction);
- return;
- }
- }
+ if (!hasVisibleTextArea(*renderer(), innerTextElement())) {
+ cacheSelection(start, end, direction);
+ return;
}
-
- Position startPosition = positionForIndex(innerText, start);
- Position endPosition;
+ VisiblePosition startPosition = visiblePositionForIndex(start);
+ VisiblePosition endPosition;
if (start == end)
endPosition = startPosition;
- else {
- if (direction == SelectionHasBackwardDirection) {
- endPosition = startPosition;
- startPosition = positionForIndex(innerText, end);
- } else
- endPosition = positionForIndex(innerText, end);
+ else
+ endPosition = visiblePositionForIndex(end);
+
+#if !PLATFORM(IOS)
+ // startPosition and endPosition can be null position for example when
+ // "-webkit-user-select: none" style attribute is specified.
+ if (startPosition.isNotNull() && endPosition.isNotNull()) {
+ ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowHost() == this
+ && endPosition.deepEquivalent().deprecatedNode()->shadowHost() == this);
}
+#endif
+ VisibleSelection newSelection;
+ if (direction == SelectionHasBackwardDirection)
+ newSelection = VisibleSelection(endPosition, startPosition);
+ else
+ newSelection = VisibleSelection(startPosition, endPosition);
+ newSelection.setIsDirectional(direction != SelectionHasNoDirection);
if (Frame* frame = document().frame())
- frame->selection().moveWithoutValidationTo(startPosition, endPosition, direction != SelectionHasNoDirection, !hasFocus, intent);
+ frame->selection().setSelection(newSelection);
}
-int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition& position) const
+int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition& pos) const
{
- TextControlInnerTextElement* innerText = innerTextElement();
- if (!innerText || !innerText->contains(position.deepEquivalent().anchorNode()))
+ if (enclosingTextFormControl(pos.deepEquivalent()) != this)
return 0;
- unsigned index = indexForPosition(position.deepEquivalent());
- ASSERT(VisiblePosition(positionForIndex(innerTextElement(), index)) == position);
- return index;
+ bool forSelectionPreservation = false;
+ return WebCore::indexForVisiblePosition(innerTextElement(), pos, forSelectionPreservation);
}
VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) const
{
- VisiblePosition position = positionForIndex(innerTextElement(), index);
- ASSERT(indexForVisiblePosition(position) == index);
- return position;
+ return visiblePositionForIndexUsingCharacterIterator(innerTextElement(), index);
}
int HTMLTextFormControlElement::selectionStart() const
@@ -351,7 +356,7 @@ int HTMLTextFormControlElement::computeSelectionStart() const
if (!frame)
return 0;
- return indexForPosition(frame->selection().selection().start());
+ return indexForVisiblePosition(frame->selection().start());
}
int HTMLTextFormControlElement::selectionEnd() const
@@ -370,14 +375,14 @@ int HTMLTextFormControlElement::computeSelectionEnd() const
if (!frame)
return 0;
- return indexForPosition(frame->selection().selection().end());
+ return indexForVisiblePosition(frame->selection().end());
}
static const AtomicString& directionString(TextFieldSelectionDirection direction)
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, none, ("none", AtomicString::ConstructFromLiteral));
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, forward, ("forward", AtomicString::ConstructFromLiteral));
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, backward, ("backward", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, none, ("none", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, forward, ("forward", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, backward, ("backward", AtomicString::ConstructFromLiteral));
switch (direction) {
case SelectionHasNoDirection:
@@ -397,7 +402,7 @@ const AtomicString& HTMLTextFormControlElement::selectionDirection() const
if (!isTextFormControl())
return directionString(SelectionHasNoDirection);
if (document().focusedElement() != this && hasCachedSelection())
- return directionString(cachedSelectionDirection());
+ return directionString(m_cachedSelectionDirection);
return directionString(computeSelectionDirection());
}
@@ -420,14 +425,14 @@ static inline void setContainerAndOffsetForRange(Node* node, int offset, Node*&
offsetInContainer = offset;
} else {
containerNode = node->parentNode();
- offsetInContainer = node->computeNodeIndex() + offset;
+ offsetInContainer = node->nodeIndex() + offset;
}
}
PassRefPtr<Range> HTMLTextFormControlElement::selection() const
{
if (!renderer() || !isTextFormControl() || !hasCachedSelection())
- return nullptr;
+ return 0;
int start = m_cachedSelectionStart;
int end = m_cachedSelectionEnd;
@@ -435,15 +440,15 @@ PassRefPtr<Range> HTMLTextFormControlElement::selection() const
ASSERT(start <= end);
TextControlInnerTextElement* innerText = innerTextElement();
if (!innerText)
- return nullptr;
+ return 0;
if (!innerText->firstChild())
return Range::create(document(), innerText, 0, innerText, 0);
int offset = 0;
- Node* startNode = nullptr;
- Node* endNode = nullptr;
- for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) {
+ Node* startNode = 0;
+ Node* endNode = 0;
+ for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(node, innerText)) {
ASSERT(!node->firstChild());
ASSERT(node->isTextNode() || node->hasTagName(brTag));
int length = node->isTextNode() ? lastOffsetInNode(node) : 1;
@@ -460,17 +465,17 @@ PassRefPtr<Range> HTMLTextFormControlElement::selection() const
}
if (!startNode || !endNode)
- return nullptr;
+ return 0;
return Range::create(document(), startNode, start, endNode, end);
}
-void HTMLTextFormControlElement::restoreCachedSelection(const AXTextStateChangeIntent& intent)
+void HTMLTextFormControlElement::restoreCachedSelection()
{
- setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, cachedSelectionDirection(), intent);
+ setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSelectionDirection);
}
-void HTMLTextFormControlElement::selectionChanged(bool shouldFireSelectEvent)
+void HTMLTextFormControlElement::selectionChanged(bool userTriggered)
{
if (!isTextFormControl())
return;
@@ -478,38 +483,22 @@ void HTMLTextFormControlElement::selectionChanged(bool shouldFireSelectEvent)
// FIXME: Don't re-compute selection start and end if this function was called inside setSelectionRange.
// selectionStart() or selectionEnd() will return cached selection when this node doesn't have focus
cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelectionDirection());
-
- if (shouldFireSelectEvent && m_cachedSelectionStart != m_cachedSelectionEnd)
- dispatchEvent(Event::create(eventNames().selectEvent, true, false));
+
+ if (Frame* frame = document().frame()) {
+ if (frame->selection().isRange() && userTriggered)
+ dispatchEvent(Event::create(eventNames().selectEvent, true, false));
+ }
}
void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == placeholderAttr) {
- updatePlaceholderText();
- updatePlaceholderVisibility();
+ updatePlaceholderVisibility(true);
+ FeatureObserver::observe(&document(), FeatureObserver::PlaceholderAttribute);
} else
HTMLFormControlElementWithState::parseAttribute(name, value);
}
-void HTMLTextFormControlElement::disabledStateChanged()
-{
- HTMLFormControlElementWithState::disabledStateChanged();
- updateInnerTextElementEditability();
-}
-
-void HTMLTextFormControlElement::readOnlyAttributeChanged()
-{
- HTMLFormControlElementWithState::disabledAttributeChanged();
- updateInnerTextElementEditability();
-}
-
-void HTMLTextFormControlElement::updateInnerTextElementEditability()
-{
- if (TextControlInnerTextElement* innerText = innerTextElement())
- innerText->setAttribute(contenteditableAttr, isDisabledOrReadOnly() ? "false" : "plaintext-only");
-}
-
bool HTMLTextFormControlElement::lastChangeWasUserEdit() const
{
if (!isTextFormControl())
@@ -517,136 +506,70 @@ bool HTMLTextFormControlElement::lastChangeWasUserEdit() const
return m_lastChangeWasUserEdit;
}
-static void stripTrailingNewline(StringBuilder& result)
-{
- // Remove one trailing newline; there's always one that's collapsed out by rendering.
- size_t size = result.length();
- if (size && result[size - 1] == newlineCharacter)
- result.resize(size - 1);
-}
-
-static String innerTextValueFrom(TextControlInnerTextElement& innerText)
-{
- StringBuilder result;
- for (Node* node = innerText.firstChild(); node; node = NodeTraversal::next(*node, &innerText)) {
- if (is<HTMLBRElement>(*node))
- result.append(newlineCharacter);
- else if (is<Text>(*node))
- result.append(downcast<Text>(*node).data());
- }
- stripTrailingNewline(result);
- return result.toString();
-}
-
void HTMLTextFormControlElement::setInnerTextValue(const String& value)
{
- TextControlInnerTextElement* innerText = innerTextElement();
- if (!innerText)
+ if (!isTextFormControl())
return;
- ASSERT(isTextFormControl());
- String previousValue = innerTextValueFrom(*innerText);
- bool textIsChanged = value != previousValue;
- if (textIsChanged || !innerText->hasChildNodes()) {
-#if HAVE(ACCESSIBILITY) && !PLATFORM(COCOA)
+ bool textIsChanged = value != innerTextValue();
+ if (textIsChanged || !innerTextElement()->hasChildNodes()) {
if (textIsChanged && renderer()) {
if (AXObjectCache* cache = document().existingAXObjectCache())
cache->postNotification(this, AXObjectCache::AXValueChanged, TargetObservableParent);
}
-#endif
- innerText->setInnerText(value, ASSERT_NO_EXCEPTION);
+ innerTextElement()->setInnerText(value, ASSERT_NO_EXCEPTION);
if (value.endsWith('\n') || value.endsWith('\r'))
- innerText->appendChild(HTMLBRElement::create(document()), ASSERT_NO_EXCEPTION);
-
-#if HAVE(ACCESSIBILITY) && PLATFORM(COCOA)
- if (textIsChanged && renderer()) {
- if (AXObjectCache* cache = document().existingAXObjectCache())
- cache->postTextReplacementNotification(this, AXTextEditTypeDelete, previousValue, AXTextEditTypeInsert, value, VisiblePosition(Position(this, Position::PositionIsBeforeAnchor)));
- }
-#endif
+ innerTextElement()->appendChild(HTMLBRElement::create(document()), ASSERT_NO_EXCEPTION);
}
setFormControlValueMatchesRenderer(true);
}
-String HTMLTextFormControlElement::innerTextValue() const
+static String finishText(StringBuilder& result)
{
- TextControlInnerTextElement* innerText = innerTextElement();
- return innerText ? innerTextValueFrom(*innerText) : emptyString();
-}
-
-static Position positionForIndex(TextControlInnerTextElement* innerText, unsigned index)
-{
- unsigned remainingCharactersToMoveForward = index;
- Node* lastBrOrText = innerText;
- for (Node* node = innerText; node; node = NodeTraversal::next(*node, innerText)) {
- if (node->hasTagName(brTag)) {
- if (!remainingCharactersToMoveForward)
- return positionBeforeNode(node);
- remainingCharactersToMoveForward--;
- lastBrOrText = node;
- } else if (is<Text>(*node)) {
- Text& text = downcast<Text>(*node);
- if (remainingCharactersToMoveForward < text.length())
- return Position(&text, remainingCharactersToMoveForward);
- remainingCharactersToMoveForward -= text.length();
- lastBrOrText = node;
- }
- }
- return lastPositionInOrAfterNode(lastBrOrText);
+ // Remove one trailing newline; there's always one that's collapsed out by rendering.
+ size_t size = result.length();
+ if (size && result[size - 1] == '\n')
+ result.resize(--size);
+ return result.toString();
}
-unsigned HTMLTextFormControlElement::indexForPosition(const Position& passedPosition) const
+String HTMLTextFormControlElement::innerTextValue() const
{
- TextControlInnerTextElement* innerText = innerTextElement();
- if (!innerText || !innerText->contains(passedPosition.anchorNode()) || passedPosition.isNull())
- return 0;
+ if (!isTextFormControl())
+ return emptyString();
- if (positionBeforeNode(innerText) == passedPosition)
- return 0;
+ TextControlInnerTextElement* innerText = innerTextElement();
+ if (!innerText)
+ return emptyString();
- unsigned index = 0;
- Node* startNode = passedPosition.computeNodeBeforePosition();
- if (!startNode)
- startNode = passedPosition.containerNode();
- ASSERT(startNode);
- ASSERT(innerText->contains(startNode));
-
- for (Node* node = startNode; node; node = NodeTraversal::previous(*node, innerText)) {
- if (is<Text>(*node)) {
- unsigned length = downcast<Text>(*node).length();
- if (node == passedPosition.containerNode())
- index += std::min<unsigned>(length, passedPosition.offsetInContainerNode());
- else
- index += length;
- } else if (is<HTMLBRElement>(*node))
- ++index;
+ StringBuilder result;
+ for (Node* node = innerText; node; node = NodeTraversal::next(node, innerText)) {
+ if (node->hasTagName(brTag))
+ result.append(newlineCharacter);
+ else if (node->isTextNode())
+ result.append(toText(node)->data());
}
-
- unsigned length = innerTextValue().length();
- index = std::min(index, length); // FIXME: We shouldn't have to call innerTextValue() just to ignore the last LF. See finishText.
-#ifndef ASSERT_DISABLED
- VisiblePosition visiblePosition = passedPosition;
- unsigned indexComputedByVisiblePosition = 0;
- if (visiblePosition.isNotNull())
- indexComputedByVisiblePosition = WebCore::indexForVisiblePosition(innerText, visiblePosition, false /* forSelectionPreservation */);
- ASSERT(index == indexComputedByVisiblePosition);
-#endif
- return index;
+ return finishText(result);
}
#if PLATFORM(IOS)
void HTMLTextFormControlElement::hidePlaceholder()
{
- if (HTMLElement* placeholder = placeholderElement())
- placeholder->setInlineStyleProperty(CSSPropertyVisibility, CSSValueHidden, true);
+ if (!supportsPlaceholder())
+ return;
+ HTMLElement* placeholder = placeholderElement();
+ if (!placeholder) {
+ updatePlaceholderText();
+ return;
+ }
+ placeholder->setInlineStyleProperty(CSSPropertyVisibility, ASCIILiteral("hidden"));
}
void HTMLTextFormControlElement::showPlaceholderIfNecessary()
{
- if (HTMLElement* placeholder = placeholderElement())
- placeholder->setInlineStyleProperty(CSSPropertyVisibility, CSSValueVisible, true);
+ updatePlaceholderVisibility(false);
}
#endif
@@ -691,11 +614,11 @@ String HTMLTextFormControlElement::valueWithHardLineBreaks() const
getNextSoftBreak(line, breakNode, breakOffset);
StringBuilder result;
- for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) {
- if (is<HTMLBRElement>(*node))
+ for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(node, innerText)) {
+ if (node->hasTagName(brTag))
result.append(newlineCharacter);
- else if (is<Text>(*node)) {
- String data = downcast<Text>(*node).data();
+ else if (node->isTextNode()) {
+ String data = toText(node)->data();
unsigned length = data.length();
unsigned position = 0;
while (breakNode == node && breakOffset <= length) {
@@ -711,8 +634,7 @@ String HTMLTextFormControlElement::valueWithHardLineBreaks() const
while (breakNode == node)
getNextSoftBreak(line, breakNode, breakOffset);
}
- stripTrailingNewline(result);
- return result.toString();
+ return finishText(result);
}
HTMLTextFormControlElement* enclosingTextFormControl(const Position& position)
@@ -725,7 +647,7 @@ HTMLTextFormControlElement* enclosingTextFormControl(const Position& position)
if (!container)
return nullptr;
Element* ancestor = container->shadowHost();
- return ancestor && is<HTMLTextFormControlElement>(*ancestor) ? downcast<HTMLTextFormControlElement>(ancestor) : nullptr;
+ return ancestor && isHTMLTextFormControlElement(*ancestor) ? toHTMLTextFormControlElement(ancestor) : nullptr;
}
static const Element* parentHTMLElement(const Element* element)
diff --git a/Source/WebCore/html/HTMLTextFormControlElement.h b/Source/WebCore/html/HTMLTextFormControlElement.h
index 5551160c8..976670ad5 100644
--- a/Source/WebCore/html/HTMLTextFormControlElement.h
+++ b/Source/WebCore/html/HTMLTextFormControlElement.h
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -44,31 +44,30 @@ public:
virtual ~HTMLTextFormControlElement();
- void didEditInnerTextValue();
void forwardEvent(Event*);
virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
// The derived class should return true if placeholder processing is needed.
- bool isPlaceholderVisible() const { return m_isPlaceholderVisible; }
virtual bool supportsPlaceholder() const = 0;
String strippedPlaceholder() const;
+ bool placeholderShouldBeVisible() const;
virtual HTMLElement* placeholderElement() const = 0;
- void updatePlaceholderVisibility();
+ void updatePlaceholderVisibility(bool);
int indexForVisiblePosition(const VisiblePosition&) const;
- WEBCORE_EXPORT VisiblePosition visiblePositionForIndex(int index) const;
+ VisiblePosition visiblePositionForIndex(int index) const;
int selectionStart() const;
int selectionEnd() const;
const AtomicString& selectionDirection() const;
void setSelectionStart(int);
void setSelectionEnd(int);
void setSelectionDirection(const String&);
- void select(const AXTextStateChangeIntent& = AXTextStateChangeIntent());
+ void select();
virtual void setRangeText(const String& replacement, ExceptionCode&);
virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionCode&);
- void setSelectionRange(int start, int end, const String& direction, const AXTextStateChangeIntent& = AXTextStateChangeIntent());
- void setSelectionRange(int start, int end, TextFieldSelectionDirection = SelectionHasNoDirection, const AXTextStateChangeIntent& = AXTextStateChangeIntent());
+ void setSelectionRange(int start, int end, const String& direction);
+ void setSelectionRange(int start, int end, TextFieldSelectionDirection = SelectionHasNoDirection);
PassRefPtr<Range> selection() const;
String selectedText() const;
@@ -79,8 +78,8 @@ public:
virtual TextControlInnerTextElement* innerTextElement() const = 0;
- void selectionChanged(bool shouldFireSelectEvent);
- WEBCORE_EXPORT bool lastChangeWasUserEdit() const;
+ void selectionChanged(bool userTriggered);
+ bool lastChangeWasUserEdit() const;
void setInnerTextValue(const String&);
String innerTextValue() const;
@@ -88,8 +87,8 @@ public:
void setTextAsOfLastFormControlChangeEvent(const String& text) { m_textAsOfLastFormControlChangeEvent = text; }
#if PLATFORM(IOS)
- WEBCORE_EXPORT void hidePlaceholder();
- WEBCORE_EXPORT void showPlaceholderIfNecessary();
+ void hidePlaceholder();
+ void showPlaceholderIfNecessary();
#endif
protected:
@@ -99,10 +98,6 @@ protected:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
- virtual void disabledStateChanged() override;
- virtual void readOnlyAttributeChanged() override;
- void updateInnerTextElementEditability();
-
void cacheSelection(int start, int end, TextFieldSelectionDirection direction)
{
m_cachedSelectionStart = start;
@@ -110,9 +105,10 @@ protected:
m_cachedSelectionDirection = direction;
}
- void restoreCachedSelection(const AXTextStateChangeIntent& = AXTextStateChangeIntent());
+ void restoreCachedSelection();
bool hasCachedSelection() const { return m_cachedSelectionStart >= 0; }
+ virtual void defaultEventHandler(Event*) override;
virtual void subtreeHasChanged() = 0;
void setLastChangeWasNotUserEdit() { m_lastChangeWasUserEdit = false; }
@@ -120,44 +116,38 @@ protected:
String valueWithHardLineBreaks() const;
private:
- TextFieldSelectionDirection cachedSelectionDirection() const { return static_cast<TextFieldSelectionDirection>(m_cachedSelectionDirection); }
-
int computeSelectionStart() const;
int computeSelectionEnd() const;
TextFieldSelectionDirection computeSelectionDirection() const;
- virtual void dispatchFocusEvent(RefPtr<Element>&& oldFocusedElement, FocusDirection) override final;
- virtual void dispatchBlurEvent(RefPtr<Element>&& newFocusedElement) override final;
+ virtual void dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection) override final;
+ virtual void dispatchBlurEvent(PassRefPtr<Element> newFocusedElement) override final;
virtual bool childShouldCreateRenderer(const Node&) const override;
- unsigned indexForPosition(const Position&) const;
-
// Returns true if user-editable value is empty. Used to check placeholder visibility.
virtual bool isEmptyValue() const = 0;
+ // Returns true if suggested value is empty. Used to check placeholder visibility.
+ virtual bool isEmptySuggestedValue() const { return true; }
// Called in dispatchFocusEvent(), after placeholder process, before calling parent's dispatchFocusEvent().
virtual void handleFocusEvent(Node* /* oldFocusedNode */, FocusDirection) { }
// Called in dispatchBlurEvent(), after placeholder process, before calling parent's dispatchBlurEvent().
virtual void handleBlurEvent() { }
- bool placeholderShouldBeVisible() const;
-
String m_textAsOfLastFormControlChangeEvent;
-
+ bool m_lastChangeWasUserEdit;
+
int m_cachedSelectionStart;
int m_cachedSelectionEnd;
-
- unsigned char m_cachedSelectionDirection : 2;
- unsigned char m_lastChangeWasUserEdit : 1;
- unsigned char m_isPlaceholderVisible : 1;
+ TextFieldSelectionDirection m_cachedSelectionDirection;
};
-HTMLTextFormControlElement* enclosingTextFormControl(const Position&);
+void isHTMLTextFormControlElement(const HTMLTextFormControlElement&); // Catch unnecessary runtime check of type known at compile time.
+inline bool isHTMLTextFormControlElement(const Element& element) { return element.isTextFormControl(); }
+inline bool isHTMLTextFormControlElement(const Node& node) { return node.isElementNode() && toElement(node).isTextFormControl(); }
+NODE_TYPE_CASTS(HTMLTextFormControlElement)
-} // namespace WebCore
+HTMLTextFormControlElement* enclosingTextFormControl(const Position&);
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLTextFormControlElement)
- static bool isType(const WebCore::Element& element) { return element.isTextFormControl(); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLTitleElement.cpp b/Source/WebCore/html/HTMLTitleElement.cpp
index de95a640d..a62d9a37a 100644
--- a/Source/WebCore/html/HTMLTitleElement.cpp
+++ b/Source/WebCore/html/HTMLTitleElement.cpp
@@ -25,10 +25,8 @@
#include "Document.h"
#include "HTMLNames.h"
-#include "NodeRenderStyle.h"
#include "RenderStyle.h"
#include "StyleInheritedData.h"
-#include "StyleResolver.h"
#include "Text.h"
#include "TextNodeTraversal.h"
#include <wtf/Ref.h>
@@ -44,16 +42,16 @@ inline HTMLTitleElement::HTMLTitleElement(const QualifiedName& tagName, Document
ASSERT(hasTagName(titleTag));
}
-Ref<HTMLTitleElement> HTMLTitleElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLTitleElement> HTMLTitleElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLTitleElement(tagName, document));
+ return adoptRef(new HTMLTitleElement(tagName, document));
}
Node::InsertionNotificationRequest HTMLTitleElement::insertedInto(ContainerNode& insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
if (inDocument() && !isInShadowTree())
- document().titleElementAdded(*this);
+ document().setTitleElement(m_title, this);
return InsertionDone;
}
@@ -61,52 +59,57 @@ void HTMLTitleElement::removedFrom(ContainerNode& insertionPoint)
{
HTMLElement::removedFrom(insertionPoint);
if (insertionPoint.inDocument() && !insertionPoint.isInShadowTree())
- document().titleElementRemoved(*this);
+ document().removeTitle(this);
}
void HTMLTitleElement::childrenChanged(const ChildChange& change)
{
HTMLElement::childrenChanged(change);
- m_title = computedTextWithDirection();
- document().titleElementTextChanged(*this);
+ m_title = textWithDirection();
+ if (inDocument()) {
+ if (!isInShadowTree())
+ document().setTitleElement(m_title, this);
+ else
+ document().removeTitle(this);
+ }
}
String HTMLTitleElement::text() const
{
- return TextNodeTraversal::contentsAsString(*this);
+ return TextNodeTraversal::contentsAsString(this);
}
-StringWithDirection HTMLTitleElement::computedTextWithDirection()
+StringWithDirection HTMLTitleElement::textWithDirection()
{
TextDirection direction = LTR;
if (RenderStyle* computedStyle = this->computedStyle())
direction = computedStyle->direction();
else {
- Ref<RenderStyle> style(document().ensureStyleResolver().styleForElement(this, parentElement() ? parentElement()->renderStyle() : nullptr));
+ Ref<RenderStyle> style(styleForRenderer());
direction = style.get().direction();
}
return StringWithDirection(text(), direction);
}
-void HTMLTitleElement::setText(const String& value)
+void HTMLTitleElement::setText(const String &value)
{
Ref<HTMLTitleElement> protectFromMutationEvents(*this);
-
- if (!value.isEmpty() && hasOneChild() && is<Text>(*firstChild())) {
- downcast<Text>(*firstChild()).setData(value, IGNORE_EXCEPTION);
- return;
- }
- // We make a copy here because entity of "value" argument can be Document::m_title,
- // which goes empty during removeChildren() invocation below,
- // which causes HTMLTitleElement::childrenChanged(), which ends up Document::setTitle().
- String valueCopy(value);
+ int numChildren = childNodeCount();
+
+ if (numChildren == 1 && firstChild()->isTextNode())
+ toText(firstChild())->setData(value, IGNORE_EXCEPTION);
+ else {
+ // We make a copy here because entity of "value" argument can be Document::m_title,
+ // which goes empty during removeChildren() invocation below,
+ // which causes HTMLTitleElement::childrenChanged(), which ends up Document::setTitle().
+ String valueCopy(value);
- if (hasChildNodes())
- removeChildren();
+ if (numChildren > 0)
+ removeChildren();
- if (!valueCopy.isEmpty())
- appendChild(document().createTextNode(valueCopy), IGNORE_EXCEPTION);
+ appendChild(document().createTextNode(valueCopy.impl()), IGNORE_EXCEPTION);
+ }
}
}
diff --git a/Source/WebCore/html/HTMLTitleElement.h b/Source/WebCore/html/HTMLTitleElement.h
index 6a9283f81..ebe1d3cc5 100644
--- a/Source/WebCore/html/HTMLTitleElement.h
+++ b/Source/WebCore/html/HTMLTitleElement.h
@@ -29,12 +29,12 @@ namespace WebCore {
class HTMLTitleElement final : public HTMLElement {
public:
- static Ref<HTMLTitleElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLTitleElement> create(const QualifiedName&, Document&);
String text() const;
void setText(const String&);
- const StringWithDirection& textWithDirection() const { return m_title; }
+ StringWithDirection textWithDirection();
private:
HTMLTitleElement(const QualifiedName&, Document&);
@@ -43,11 +43,11 @@ private:
virtual void removedFrom(ContainerNode&) override;
virtual void childrenChanged(const ChildChange&) override;
- StringWithDirection computedTextWithDirection();
-
StringWithDirection m_title;
};
+NODE_TYPE_CASTS(HTMLTitleElement)
+
} //namespace
#endif
diff --git a/Source/WebCore/html/HTMLTitleElement.idl b/Source/WebCore/html/HTMLTitleElement.idl
index 2b312f5a6..f5639fe17 100644
--- a/Source/WebCore/html/HTMLTitleElement.idl
+++ b/Source/WebCore/html/HTMLTitleElement.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
diff --git a/Source/WebCore/html/HTMLTrackElement.cpp b/Source/WebCore/html/HTMLTrackElement.cpp
index d6b1f9a6e..449b63268 100644
--- a/Source/WebCore/html/HTMLTrackElement.cpp
+++ b/Source/WebCore/html/HTMLTrackElement.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -52,7 +52,7 @@ static String urlForLoggingTrack(const URL& url)
inline HTMLTrackElement::HTMLTrackElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
- , m_loadTimer(*this, &HTMLTrackElement::loadTimerFired)
+ , m_loadTimer(this, &HTMLTrackElement::loadTimerFired)
{
LOG(Media, "HTMLTrackElement::HTMLTrackElement - %p", this);
ASSERT(hasTagName(trackTag));
@@ -64,9 +64,9 @@ HTMLTrackElement::~HTMLTrackElement()
m_track->clearClient();
}
-Ref<HTMLTrackElement> HTMLTrackElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLTrackElement> HTMLTrackElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLTrackElement(tagName, document));
+ return adoptRef(new HTMLTrackElement(tagName, document));
}
Node::InsertionNotificationRequest HTMLTrackElement::insertedInto(ContainerNode& insertionPoint)
@@ -85,8 +85,8 @@ Node::InsertionNotificationRequest HTMLTrackElement::insertedInto(ContainerNode&
void HTMLTrackElement::removedFrom(ContainerNode& insertionPoint)
{
- if (!parentNode() && is<HTMLMediaElement>(insertionPoint))
- downcast<HTMLMediaElement>(insertionPoint).didRemoveTextTrack(this);
+ if (!parentNode() && isHTMLMediaElement(insertionPoint))
+ toHTMLMediaElement(insertionPoint).didRemoveTextTrack(this);
HTMLElement::removedFrom(insertionPoint);
}
@@ -200,7 +200,7 @@ void HTMLTrackElement::scheduleLoad()
m_loadTimer.startOneShot(0);
}
-void HTMLTrackElement::loadTimerFired()
+void HTMLTrackElement::loadTimerFired(Timer<HTMLTrackElement>&)
{
if (!fastHasAttribute(srcAttr))
return;
@@ -238,7 +238,7 @@ bool HTMLTrackElement::canLoadURL(const URL& url)
if (url.isEmpty())
return false;
- if (!document().contentSecurityPolicy()->allowMediaFromSource(url, isInUserAgentShadowTree())) {
+ if (!document().contentSecurityPolicy()->allowMediaFromSource(url)) {
LOG(Media, "HTMLTrackElement::canLoadURL(%s) -> rejected by Content Security Policy", urlForLoggingTrack(url).utf8().data());
return false;
}
@@ -343,10 +343,10 @@ void HTMLTrackElement::textTrackRemoveCue(TextTrack* track, PassRefPtr<TextTrack
HTMLMediaElement* HTMLTrackElement::mediaElement() const
{
Element* parent = parentElement();
- if (is<HTMLMediaElement>(parent))
- return downcast<HTMLMediaElement>(parentNode());
+ if (parent && parent->isMediaElement())
+ return toHTMLMediaElement(parentNode());
- return nullptr;
+ return 0;
}
}
diff --git a/Source/WebCore/html/HTMLTrackElement.h b/Source/WebCore/html/HTMLTrackElement.h
index 0546adeba..f34405f7b 100644
--- a/Source/WebCore/html/HTMLTrackElement.h
+++ b/Source/WebCore/html/HTMLTrackElement.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -37,7 +37,7 @@ class HTMLMediaElement;
class HTMLTrackElement final : public HTMLElement, public TextTrackClient {
public:
- static Ref<HTMLTrackElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLTrackElement> create(const QualifiedName&, Document&);
String kind();
void setKind(const String&);
@@ -75,7 +75,7 @@ private:
virtual bool isURLAttribute(const Attribute&) const override;
- void loadTimerFired();
+ void loadTimerFired(Timer<HTMLTrackElement>&);
HTMLMediaElement* mediaElement() const;
@@ -91,9 +91,11 @@ private:
bool canLoadURL(const URL&);
RefPtr<LoadableTextTrack> m_track;
- Timer m_loadTimer;
+ Timer<HTMLTrackElement> m_loadTimer;
};
+NODE_TYPE_CASTS(HTMLTrackElement)
+
}
#endif
diff --git a/Source/WebCore/html/HTMLTrackElement.idl b/Source/WebCore/html/HTMLTrackElement.idl
index 023c706ac..e4844fde0 100644
--- a/Source/WebCore/html/HTMLTrackElement.idl
+++ b/Source/WebCore/html/HTMLTrackElement.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/HTMLUListElement.cpp b/Source/WebCore/html/HTMLUListElement.cpp
index a6c223c6f..bc9e40fb4 100644
--- a/Source/WebCore/html/HTMLUListElement.cpp
+++ b/Source/WebCore/html/HTMLUListElement.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLUListElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "HTMLNames.h"
@@ -36,14 +37,14 @@ HTMLUListElement::HTMLUListElement(const QualifiedName& tagName, Document& docum
ASSERT(hasTagName(ulTag));
}
-Ref<HTMLUListElement> HTMLUListElement::create(Document& document)
+PassRefPtr<HTMLUListElement> HTMLUListElement::create(Document& document)
{
- return adoptRef(*new HTMLUListElement(ulTag, document));
+ return adoptRef(new HTMLUListElement(ulTag, document));
}
-Ref<HTMLUListElement> HTMLUListElement::create(const QualifiedName& tagName, Document& document)
+PassRefPtr<HTMLUListElement> HTMLUListElement::create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLUListElement(tagName, document));
+ return adoptRef(new HTMLUListElement(tagName, document));
}
bool HTMLUListElement::isPresentationAttribute(const QualifiedName& name) const
diff --git a/Source/WebCore/html/HTMLUListElement.h b/Source/WebCore/html/HTMLUListElement.h
index 558f14ba0..b25f07186 100644
--- a/Source/WebCore/html/HTMLUListElement.h
+++ b/Source/WebCore/html/HTMLUListElement.h
@@ -29,8 +29,8 @@ namespace WebCore {
class HTMLUListElement final : public HTMLElement {
public:
- static Ref<HTMLUListElement> create(Document&);
- static Ref<HTMLUListElement> create(const QualifiedName&, Document&);
+ static PassRefPtr<HTMLUListElement> create(Document&);
+ static PassRefPtr<HTMLUListElement> create(const QualifiedName&, Document&);
private:
HTMLUListElement(const QualifiedName&, Document&);
diff --git a/Source/WebCore/html/HTMLUnknownElement.h b/Source/WebCore/html/HTMLUnknownElement.h
index c9da76b18..755caef1d 100644
--- a/Source/WebCore/html/HTMLUnknownElement.h
+++ b/Source/WebCore/html/HTMLUnknownElement.h
@@ -36,20 +36,26 @@ namespace WebCore {
class HTMLUnknownElement final : public HTMLElement {
public:
- static Ref<HTMLUnknownElement> create(const QualifiedName& tagName, Document& document)
+ static PassRefPtr<HTMLUnknownElement> create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(*new HTMLUnknownElement(tagName, document));
+ return adoptRef(new HTMLUnknownElement(tagName, document));
}
+ virtual bool isHTMLUnknownElement() const override { return true; }
+
private:
HTMLUnknownElement(const QualifiedName& tagName, Document& document)
- : HTMLElement(tagName, document, CreateHTMLElement)
+ : HTMLElement(tagName, document)
{
}
-
- virtual bool isHTMLUnknownElement() const override { return true; }
};
+inline HTMLUnknownElement* toHTMLUnknownElement(HTMLElement* element)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!element || element->isHTMLUnknownElement());
+ return static_cast<HTMLUnknownElement*>(element);
+}
+
} // namespace
#endif
diff --git a/Source/WebCore/html/HTMLVideoElement.cpp b/Source/WebCore/html/HTMLVideoElement.cpp
index c4ece4e0f..69237e435 100644
--- a/Source/WebCore/html/HTMLVideoElement.cpp
+++ b/Source/WebCore/html/HTMLVideoElement.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -27,6 +27,7 @@
#if ENABLE(VIDEO)
#include "HTMLVideoElement.h"
+#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "Chrome.h"
#include "ChromeClient.h"
@@ -35,13 +36,11 @@
#include "HTMLImageLoader.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
-#include "Logging.h"
#include "Page.h"
#include "RenderImage.h"
#include "RenderVideo.h"
#include "ScriptController.h"
#include "Settings.h"
-#include <wtf/NeverDestroyed.h>
namespace WebCore {
@@ -56,11 +55,11 @@ inline HTMLVideoElement::HTMLVideoElement(const QualifiedName& tagName, Document
m_defaultPosterURL = document.settings()->defaultVideoPosterURL();
}
-Ref<HTMLVideoElement> HTMLVideoElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
+PassRefPtr<HTMLVideoElement> HTMLVideoElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
{
- Ref<HTMLVideoElement> videoElement = adoptRef(*new HTMLVideoElement(tagName, document, createdByParser));
+ RefPtr<HTMLVideoElement> videoElement(adoptRef(new HTMLVideoElement(tagName, document, createdByParser)));
videoElement->suspendIfNeeded();
- return videoElement;
+ return videoElement.release();
}
bool HTMLVideoElement::rendererIsNeeded(const RenderStyle& style)
@@ -68,23 +67,33 @@ bool HTMLVideoElement::rendererIsNeeded(const RenderStyle& style)
return HTMLElement::rendererIsNeeded(style);
}
-RenderPtr<RenderElement> HTMLVideoElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> HTMLVideoElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderVideo>(*this, WTF::move(style));
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy())
+ return HTMLMediaElement::createElementRenderer(std::move(style));
+#endif
+ return createRenderer<RenderVideo>(*this, std::move(style));
}
void HTMLVideoElement::didAttachRenderers()
{
HTMLMediaElement::didAttachRenderers();
- updateDisplayState();
- if (shouldDisplayPosterImage()) {
- if (!m_imageLoader)
- m_imageLoader = std::make_unique<HTMLImageLoader>(*this);
- m_imageLoader->updateFromElement();
- if (renderer())
- downcast<RenderImage>(*renderer()).imageResource().setCachedImage(m_imageLoader->image());
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (!shouldUseVideoPluginProxy()) {
+#endif
+ updateDisplayState();
+ if (shouldDisplayPosterImage()) {
+ if (!m_imageLoader)
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader->updateFromElement();
+ if (renderer())
+ toRenderImage(renderer())->imageResource().setCachedImage(m_imageLoader->image());
+ }
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
}
+#endif
}
void HTMLVideoElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
@@ -110,33 +119,35 @@ void HTMLVideoElement::parseAttribute(const QualifiedName& name, const AtomicStr
// Force a poster recalc by setting m_displayMode to Unknown directly before calling updateDisplayState.
HTMLMediaElement::setDisplayMode(Unknown);
updateDisplayState();
-
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy())
+ return;
+#endif
if (shouldDisplayPosterImage()) {
if (!m_imageLoader)
- m_imageLoader = std::make_unique<HTMLImageLoader>(*this);
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
m_imageLoader->updateFromElementIgnoringPreviousError();
} else {
if (renderer())
- downcast<RenderImage>(*renderer()).imageResource().setCachedImage(nullptr);
+ toRenderImage(renderer())->imageResource().setCachedImage(0);
}
}
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- else if (name == webkitwirelessvideoplaybackdisabledAttr)
- mediaSession().setWirelessVideoPlaybackDisabled(*this, true);
-#endif
- else {
- HTMLMediaElement::parseAttribute(name, value);
+#if ENABLE(IOS_AIRPLAY)
+ else if (name == webkitwirelessvideoplaybackdisabledAttr) {
+ if (player())
+ player()->setWirelessVideoPlaybackDisabled(webkitWirelessVideoPlaybackDisabled());
+ } else {
+ HTMLMediaElement::parseAttribute(name, value);
-#if PLATFORM(IOS) && ENABLE(WIRELESS_PLAYBACK_TARGET)
if (name == webkitairplayAttr) {
- bool disabled = false;
- if (equalIgnoringCase(fastGetAttribute(HTMLNames::webkitairplayAttr), "deny"))
- disabled = true;
- mediaSession().setWirelessVideoPlaybackDisabled(*this, disabled);
+ if (player())
+ player()->setWirelessVideoPlaybackDisabled(webkitWirelessVideoPlaybackDisabled());
}
-#endif
}
-
+#else
+ else
+ HTMLMediaElement::parseAttribute(name, value);
+#endif
}
bool HTMLVideoElement::supportsFullscreen() const
@@ -162,7 +173,7 @@ bool HTMLVideoElement::supportsFullscreen() const
if (!player()->hasVideo())
return false;
- return page->chrome().client().supportsVideoFullscreen();
+ return page->chrome().client().supportsFullscreenForNode(this);
#endif // PLATFORM(IOS)
}
@@ -170,14 +181,14 @@ unsigned HTMLVideoElement::videoWidth() const
{
if (!player())
return 0;
- return clampToUnsigned(player()->naturalSize().width());
+ return player()->naturalSize().width();
}
unsigned HTMLVideoElement::videoHeight() const
{
if (!player())
return 0;
- return clampToUnsigned(player()->naturalSize().height());
+ return player()->naturalSize().height();
}
bool HTMLVideoElement::isURLAttribute(const Attribute& attribute) const
@@ -222,6 +233,10 @@ void HTMLVideoElement::setDisplayMode(DisplayMode mode)
player()->setPoster(poster);
}
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (shouldUseVideoPluginProxy())
+ return;
+#endif
if (renderer() && displayMode() != oldMode)
renderer()->updateFromElement();
}
@@ -234,7 +249,7 @@ void HTMLVideoElement::updateDisplayState()
setDisplayMode(Poster);
}
-void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const FloatRect& destRect)
+void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
{
MediaPlayer* player = HTMLMediaElement::player();
if (!player)
@@ -262,7 +277,7 @@ bool HTMLVideoElement::hasAvailableVideoFrame() const
PassNativeImagePtr HTMLVideoElement::nativeImageForCurrentTime()
{
if (!player())
- return nullptr;
+ return 0;
return player()->nativeImageForCurrentTime();
}
@@ -298,10 +313,17 @@ bool HTMLVideoElement::webkitDisplayingFullscreen()
return isFullscreen();
}
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#if ENABLE(IOS_AIRPLAY)
bool HTMLVideoElement::webkitWirelessVideoPlaybackDisabled() const
{
- return mediaSession().wirelessVideoPlaybackDisabled(*this);
+ Settings* settings = document().settings();
+ if (!settings || !settings->mediaPlaybackAllowsAirPlay())
+ return true;
+
+ String legacyAirplayAttributeValue = fastGetAttribute(webkitairplayAttr);
+ if (equalIgnoringCase(legacyAirplayAttributeValue, "deny"))
+ return true;
+ return fastHasAttribute(webkitwirelessvideoplaybackdisabledAttr);
}
void HTMLVideoElement::setWebkitWirelessVideoPlaybackDisabled(bool disabled)
@@ -343,90 +365,6 @@ URL HTMLVideoElement::posterImageURL() const
return document().completeURL(url);
}
-#if ENABLE(VIDEO_PRESENTATION_MODE)
-
-static const AtomicString& presentationModeFullscreen()
-{
- static NeverDestroyed<AtomicString> fullscreen("fullscreen", AtomicString::ConstructFromLiteral);
- return fullscreen;
-}
-
-static const AtomicString& presentationModePictureInPicture()
-{
- static NeverDestroyed<AtomicString> pictureInPicture("picture-in-picture", AtomicString::ConstructFromLiteral);
- return pictureInPicture;
-}
-
-static const AtomicString& presentationModeInline()
-{
- static NeverDestroyed<AtomicString> inlineMode("inline", AtomicString::ConstructFromLiteral);
- return inlineMode;
-}
-
-bool HTMLVideoElement::webkitSupportsPresentationMode(const String& mode) const
-{
- if (mode == presentationModeFullscreen())
- return mediaSession().fullscreenPermitted(*this) && supportsFullscreen();
-
- if (mode == presentationModePictureInPicture())
- return wkIsOptimizedFullscreenSupported() && mediaSession().allowsPictureInPicture(*this) && supportsFullscreen();
-
- if (mode == presentationModeInline())
- return !mediaSession().requiresFullscreenForVideoPlayback(*this);
-
- return false;
-}
-
-void HTMLVideoElement::webkitSetPresentationMode(const String& mode)
-{
- if (mode == presentationModeInline() && isFullscreen()) {
- exitFullscreen();
- return;
- }
-
- if (!mediaSession().fullscreenPermitted(*this) || !supportsFullscreen())
- return;
-
- LOG(Media, "HTMLVideoElement::webkitSetPresentationMode(%p) - setting to \"%s\"", this, mode.utf8().data());
-
- if (mode == presentationModeFullscreen())
- enterFullscreen(VideoFullscreenModeStandard);
- else if (mode == presentationModePictureInPicture())
- enterFullscreen(VideoFullscreenModePictureInPicture);
-}
-
-String HTMLVideoElement::webkitPresentationMode() const
-{
- HTMLMediaElement::VideoFullscreenMode mode = fullscreenMode();
-
- if (mode == VideoFullscreenModeStandard)
- return presentationModeFullscreen();
-
- if (mode & VideoFullscreenModePictureInPicture)
- return presentationModePictureInPicture();
-
- if (mode == VideoFullscreenModeNone)
- return presentationModeInline();
-
- ASSERT_NOT_REACHED();
- return presentationModeInline();
-}
-
-void HTMLVideoElement::fullscreenModeChanged(VideoFullscreenMode mode)
-{
- if (mode != fullscreenMode()) {
- LOG(Media, "HTMLVideoElement::fullscreenModeChanged(%p) - mode changed from %i to %i", this, fullscreenMode(), mode);
- scheduleEvent(eventNames().webkitpresentationmodechangedEvent);
- }
-
- if (player())
- player()->setVideoFullscreenMode(mode);
-
- HTMLMediaElement::fullscreenModeChanged(mode);
-}
-
-#endif
-
}
#endif
diff --git a/Source/WebCore/html/HTMLVideoElement.h b/Source/WebCore/html/HTMLVideoElement.h
index aea6ba8b8..536c32262 100644
--- a/Source/WebCore/html/HTMLVideoElement.h
+++ b/Source/WebCore/html/HTMLVideoElement.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -27,9 +27,7 @@
#define HTMLVideoElement_h
#if ENABLE(VIDEO)
-
#include "HTMLMediaElement.h"
-#include <memory>
namespace WebCore {
@@ -37,10 +35,10 @@ class HTMLImageLoader;
class HTMLVideoElement final : public HTMLMediaElement {
public:
- static Ref<HTMLVideoElement> create(const QualifiedName&, Document&, bool);
+ static PassRefPtr<HTMLVideoElement> create(const QualifiedName&, Document&, bool);
- WEBCORE_EXPORT unsigned videoWidth() const;
- WEBCORE_EXPORT unsigned videoHeight() const;
+ unsigned videoWidth() const;
+ unsigned videoHeight() const;
// Fullscreen
void webkitEnterFullscreen(ExceptionCode&);
@@ -53,7 +51,7 @@ public:
void webkitEnterFullScreen(ExceptionCode& ec) { webkitEnterFullscreen(ec); }
void webkitExitFullScreen() { webkitExitFullscreen(); }
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#if ENABLE(IOS_AIRPLAY)
bool webkitWirelessVideoPlaybackDisabled() const;
void setWebkitWirelessVideoPlaybackDisabled(bool);
#endif
@@ -65,7 +63,7 @@ public:
#endif
// Used by canvas to gain raw pixel access
- void paintCurrentFrameInContext(GraphicsContext*, const FloatRect&);
+ void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
PassNativeImagePtr nativeImageForCurrentTime();
@@ -76,14 +74,7 @@ public:
bool shouldDisplayPosterImage() const { return displayMode() == Poster || displayMode() == PosterWaitingForVideo; }
URL posterImageURL() const;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
-
-#if ENABLE(VIDEO_PRESENTATION_MODE)
- bool webkitSupportsPresentationMode(const String&) const;
- void webkitSetPresentationMode(const String&);
- String webkitPresentationMode() const;
- virtual void fullscreenModeChanged(VideoFullscreenMode) override;
-#endif
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
private:
HTMLVideoElement(const QualifiedName&, Document&, bool);
@@ -99,25 +90,19 @@ private:
virtual bool isURLAttribute(const Attribute&) const override;
virtual const AtomicString& imageSourceURL() const override;
- bool hasAvailableVideoFrame() const;
+ virtual bool hasAvailableVideoFrame() const;
virtual void updateDisplayState() override;
virtual void didMoveToNewDocument(Document* oldDocument) override;
virtual void setDisplayMode(DisplayMode) override;
- virtual PlatformMediaSession::MediaType presentationType() const override { return PlatformMediaSession::Video; }
-
- std::unique_ptr<HTMLImageLoader> m_imageLoader;
+ OwnPtr<HTMLImageLoader> m_imageLoader;
AtomicString m_defaultPosterURL;
};
-} // namespace WebCore
+NODE_TYPE_CASTS(HTMLVideoElement)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLVideoElement)
- static bool isType(const WebCore::HTMLMediaElement& element) { return element.hasTagName(WebCore::HTMLNames::videoTag); }
- static bool isType(const WebCore::Element& element) { return is<WebCore::HTMLMediaElement>(element) && isType(downcast<WebCore::HTMLMediaElement>(element)); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::HTMLMediaElement>(node) && isType(downcast<WebCore::HTMLMediaElement>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+} //namespace
-#endif // ENABLE(VIDEO)
-#endif // HTMLVideoElement_h
+#endif
+#endif
diff --git a/Source/WebCore/html/HTMLVideoElement.idl b/Source/WebCore/html/HTMLVideoElement.idl
index 8cd0e4bd1..51dcccfb7 100644
--- a/Source/WebCore/html/HTMLVideoElement.idl
+++ b/Source/WebCore/html/HTMLVideoElement.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -23,9 +23,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// FIXME: This should be Conditional=VIDEO_PRESENTATION_MODE.
-enum VideoPresentationMode { "fullscreen", "picture-in-picture", "inline" };
-
[
Conditional=VIDEO,
JSGenerateToNativeObject,
@@ -46,17 +43,13 @@ enum VideoPresentationMode { "fullscreen", "picture-in-picture", "inline" };
[RaisesException] void webkitEnterFullScreen();
void webkitExitFullScreen();
- [Conditional=WIRELESS_PLAYBACK_TARGET] attribute boolean webkitWirelessVideoPlaybackDisabled;
+ [Conditional=IOS_AIRPLAY] attribute boolean webkitWirelessVideoPlaybackDisabled;
- // The number of frames that have been decoded and made available for playback.
+ // The number of frames that have been decoded and made available for
+ // playback.
[Conditional=MEDIA_STATISTICS] readonly attribute unsigned long webkitDecodedFrameCount;
- // The number of decoded frames that have been dropped by the player for performance reasons during playback.
+ // The number of decoded frames that have been dropped by the player
+ // for performance reasons during playback.
[Conditional=MEDIA_STATISTICS] readonly attribute unsigned long webkitDroppedFrameCount;
-
-#if !defined(LANGUAGE_GOBJECT) || !LANGUAGE_GOBJECT // Work around shortcomings in the gobject binding generator handling of conditional features by turning these off for gobject.
- [Conditional=VIDEO_PRESENTATION_MODE] boolean webkitSupportsPresentationMode(VideoPresentationMode mode);
- [Conditional=VIDEO_PRESENTATION_MODE] readonly attribute VideoPresentationMode webkitPresentationMode;
- [Conditional=VIDEO_PRESENTATION_MODE] void webkitSetPresentationMode(VideoPresentationMode mode);
-#endif
};
diff --git a/Source/WebCore/html/HTMLViewSourceDocument.cpp b/Source/WebCore/html/HTMLViewSourceDocument.cpp
new file mode 100644
index 000000000..5b705d9ce
--- /dev/null
+++ b/Source/WebCore/html/HTMLViewSourceDocument.cpp
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLViewSourceDocument.h"
+
+#include "DOMImplementation.h"
+#include "DocumentStyleSheetCollection.h"
+#include "HTMLAnchorElement.h"
+#include "HTMLBRElement.h"
+#include "HTMLBaseElement.h"
+#include "HTMLBodyElement.h"
+#include "HTMLDivElement.h"
+#include "HTMLHtmlElement.h"
+#include "HTMLTableCellElement.h"
+#include "HTMLTableElement.h"
+#include "HTMLTableRowElement.h"
+#include "HTMLTableSectionElement.h"
+#include "Text.h"
+#include "TextViewSourceParser.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLViewSourceDocument::HTMLViewSourceDocument(Frame* frame, const URL& url, const String& mimeType)
+ : HTMLDocument(frame, url)
+ , m_type(mimeType)
+{
+ styleSheetCollection().setUsesBeforeAfterRulesOverride(true);
+ setIsViewSource(true);
+
+ setCompatibilityMode(QuirksMode);
+ lockCompatibilityMode();
+}
+
+PassRefPtr<DocumentParser> HTMLViewSourceDocument::createParser()
+{
+ if (m_type == "text/html" || m_type == "application/xhtml+xml" || m_type == "image/svg+xml" || DOMImplementation::isXMLMIMEType(m_type))
+ return HTMLViewSourceParser::create(*this);
+
+ return TextViewSourceParser::create(*this);
+}
+
+void HTMLViewSourceDocument::createContainingTable()
+{
+ RefPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*this);
+ parserAppendChild(html);
+ RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this);
+ html->parserAppendChild(body);
+ // Create a line gutter div that can be used to make sure the gutter extends down the height of the whole
+ // document.
+ RefPtr<HTMLDivElement> div = HTMLDivElement::create(*this);
+ div->setAttribute(classAttr, "webkit-line-gutter-backdrop");
+ body->parserAppendChild(div);
+
+ RefPtr<HTMLTableElement> table = HTMLTableElement::create(*this);
+ body->parserAppendChild(table);
+ m_tbody = HTMLTableSectionElement::create(tbodyTag, *this);
+ table->parserAppendChild(m_tbody);
+ m_current = m_tbody;
+}
+
+void HTMLViewSourceDocument::addSource(const String& source, HTMLToken& token)
+{
+ if (!m_current)
+ createContainingTable();
+
+ switch (token.type()) {
+ case HTMLToken::Uninitialized:
+ ASSERT_NOT_REACHED();
+ break;
+ case HTMLToken::DOCTYPE:
+ processDoctypeToken(source, token);
+ break;
+ case HTMLToken::EndOfFile:
+ if (!m_tbody->hasChildNodes())
+ addLine(String());
+ break;
+ case HTMLToken::StartTag:
+ case HTMLToken::EndTag:
+ processTagToken(source, token);
+ break;
+ case HTMLToken::Comment:
+ processCommentToken(source, token);
+ break;
+ case HTMLToken::Character:
+ processCharacterToken(source, token);
+ break;
+ }
+}
+
+void HTMLViewSourceDocument::processDoctypeToken(const String& source, HTMLToken&)
+{
+ if (!m_current)
+ createContainingTable();
+ m_current = addSpanWithClassName("webkit-html-doctype");
+ addText(source, "webkit-html-doctype");
+ m_current = m_td;
+}
+
+void HTMLViewSourceDocument::processTagToken(const String& source, HTMLToken& token)
+{
+ m_current = addSpanWithClassName("webkit-html-tag");
+
+ AtomicString tagName(token.name());
+
+ unsigned index = 0;
+ HTMLToken::AttributeList::const_iterator iter = token.attributes().begin();
+ while (index < source.length()) {
+ if (iter == token.attributes().end()) {
+ // We want to show the remaining characters in the token.
+ index = addRange(source, index, source.length(), "");
+ ASSERT(index == source.length());
+ break;
+ }
+
+ AtomicString name(iter->name);
+ String value = StringImpl::create8BitIfPossible(iter->value);
+
+ index = addRange(source, index, iter->nameRange.start - token.startIndex(), "");
+ index = addRange(source, index, iter->nameRange.end - token.startIndex(), "webkit-html-attribute-name");
+
+ if (tagName == baseTag && name == hrefAttr)
+ m_current = addBase(value);
+
+ index = addRange(source, index, iter->valueRange.start - token.startIndex(), "");
+
+ bool isLink = name == srcAttr || name == hrefAttr;
+ index = addRange(source, index, iter->valueRange.end - token.startIndex(), "webkit-html-attribute-value", isLink, tagName == aTag, value);
+
+ ++iter;
+ }
+ m_current = m_td;
+}
+
+void HTMLViewSourceDocument::processCommentToken(const String& source, HTMLToken&)
+{
+ m_current = addSpanWithClassName("webkit-html-comment");
+ addText(source, "webkit-html-comment");
+ m_current = m_td;
+}
+
+void HTMLViewSourceDocument::processCharacterToken(const String& source, HTMLToken&)
+{
+ addText(source, "");
+}
+
+PassRefPtr<Element> HTMLViewSourceDocument::addSpanWithClassName(const AtomicString& className)
+{
+ if (m_current == m_tbody) {
+ addLine(className);
+ return m_current;
+ }
+
+ RefPtr<HTMLElement> span = HTMLElement::create(spanTag, *this);
+ span->setAttribute(classAttr, className);
+ m_current->parserAppendChild(span);
+ return span.release();
+}
+
+void HTMLViewSourceDocument::addLine(const AtomicString& className)
+{
+ // Create a table row.
+ RefPtr<HTMLTableRowElement> trow = HTMLTableRowElement::create(*this);
+ m_tbody->parserAppendChild(trow);
+
+ // Create a cell that will hold the line number (it is generated in the stylesheet using counters).
+ RefPtr<HTMLTableCellElement> td = HTMLTableCellElement::create(tdTag, *this);
+ td->setAttribute(classAttr, "webkit-line-number");
+ trow->parserAppendChild(td);
+
+ // Create a second cell for the line contents
+ td = HTMLTableCellElement::create(tdTag, *this);
+ td->setAttribute(classAttr, "webkit-line-content");
+ trow->parserAppendChild(td);
+ m_current = m_td = td;
+
+#ifdef DEBUG_LINE_NUMBERS
+ RefPtr<Text> lineNumberText = Text::create(*this, String::number(parser()->lineNumber() + 1) + " ");
+ td->addChild(lineNumberText);
+#endif
+
+ // Open up the needed spans.
+ if (!className.isEmpty()) {
+ if (className == "webkit-html-attribute-name" || className == "webkit-html-attribute-value")
+ m_current = addSpanWithClassName("webkit-html-tag");
+ m_current = addSpanWithClassName(className);
+ }
+}
+
+void HTMLViewSourceDocument::finishLine()
+{
+ if (!m_current->hasChildNodes()) {
+ RefPtr<HTMLBRElement> br = HTMLBRElement::create(*this);
+ m_current->parserAppendChild(br);
+ }
+ m_current = m_tbody;
+}
+
+void HTMLViewSourceDocument::addText(const String& text, const AtomicString& className)
+{
+ if (text.isEmpty())
+ return;
+
+ // Add in the content, splitting on newlines.
+ Vector<String> lines;
+ text.split('\n', true, lines);
+ unsigned size = lines.size();
+ for (unsigned i = 0; i < size; i++) {
+ String substring = lines[i];
+ if (m_current == m_tbody)
+ addLine(className);
+ if (substring.isEmpty()) {
+ if (i == size - 1)
+ break;
+ finishLine();
+ continue;
+ }
+ RefPtr<Text> text = Text::create(*this, substring);
+ m_current->parserAppendChild(text);
+ if (i < size - 1)
+ finishLine();
+ }
+}
+
+int HTMLViewSourceDocument::addRange(const String& source, int start, int end, const String& className, bool isLink, bool isAnchor, const String& link)
+{
+ ASSERT(start <= end);
+ if (start == end)
+ return start;
+
+ String text = source.substring(start, end - start);
+ if (!className.isEmpty()) {
+ if (isLink)
+ m_current = addLink(link, isAnchor);
+ else
+ m_current = addSpanWithClassName(className);
+ }
+ addText(text, className);
+ if (!className.isEmpty() && m_current != m_tbody)
+ m_current = toElement(m_current->parentNode());
+ return end;
+}
+
+PassRefPtr<Element> HTMLViewSourceDocument::addBase(const AtomicString& href)
+{
+ RefPtr<HTMLBaseElement> base = HTMLBaseElement::create(baseTag, *this);
+ base->setAttribute(hrefAttr, href);
+ m_current->parserAppendChild(base);
+ return base.release();
+}
+
+PassRefPtr<Element> HTMLViewSourceDocument::addLink(const AtomicString& url, bool isAnchor)
+{
+ if (m_current == m_tbody)
+ addLine("webkit-html-tag");
+
+ // Now create a link for the attribute value instead of a span.
+ RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(*this);
+ const char* classValue;
+ if (isAnchor)
+ classValue = "webkit-html-attribute-value webkit-html-external-link";
+ else
+ classValue = "webkit-html-attribute-value webkit-html-resource-link";
+ anchor->setAttribute(classAttr, classValue);
+ anchor->setAttribute(targetAttr, "_blank");
+ anchor->setAttribute(hrefAttr, url);
+ m_current->parserAppendChild(anchor);
+ return anchor.release();
+}
+
+}
diff --git a/Source/WebCore/html/HTMLViewSourceDocument.h b/Source/WebCore/html/HTMLViewSourceDocument.h
new file mode 100644
index 000000000..5c592d228
--- /dev/null
+++ b/Source/WebCore/html/HTMLViewSourceDocument.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2006, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLViewSourceDocument_h
+#define HTMLViewSourceDocument_h
+
+#include "HTMLDocument.h"
+
+namespace WebCore {
+
+class HTMLTableCellElement;
+class HTMLTableSectionElement;
+class HTMLToken;
+
+class HTMLViewSourceDocument final : public HTMLDocument {
+public:
+ static PassRefPtr<HTMLViewSourceDocument> create(Frame* frame, const URL& url, const String& mimeType)
+ {
+ return adoptRef(new HTMLViewSourceDocument(frame, url, mimeType));
+ }
+
+ void addSource(const String&, HTMLToken&);
+
+private:
+ HTMLViewSourceDocument(Frame*, const URL&, const String& mimeType);
+
+ // Returns HTMLViewSourceParser or TextDocumentParser based on m_type.
+ virtual PassRefPtr<DocumentParser> createParser() override;
+
+ void processDoctypeToken(const String& source, HTMLToken&);
+ void processTagToken(const String& source, HTMLToken&);
+ void processCommentToken(const String& source, HTMLToken&);
+ void processCharacterToken(const String& source, HTMLToken&);
+
+ void createContainingTable();
+ PassRefPtr<Element> addSpanWithClassName(const AtomicString&);
+ void addLine(const AtomicString& className);
+ void finishLine();
+ void addText(const String& text, const AtomicString& className);
+ int addRange(const String& source, int start, int end, const String& className, bool isLink = false, bool isAnchor = false, const String& link = String());
+ PassRefPtr<Element> addLink(const AtomicString& url, bool isAnchor);
+ PassRefPtr<Element> addBase(const AtomicString& href);
+
+ String m_type;
+ RefPtr<Element> m_current;
+ RefPtr<HTMLTableSectionElement> m_tbody;
+ RefPtr<HTMLTableCellElement> m_td;
+};
+
+}
+
+#endif // HTMLViewSourceDocument_h
diff --git a/Source/WebCore/html/HTMLWBRElement.cpp b/Source/WebCore/html/HTMLWBRElement.cpp
deleted file mode 100644
index 4e9e630f3..000000000
--- a/Source/WebCore/html/HTMLWBRElement.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "HTMLWBRElement.h"
-
-#include "HTMLNames.h"
-#include "RenderLineBreak.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-Ref<HTMLWBRElement> HTMLWBRElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(*new HTMLWBRElement(tagName, document));
-}
-
-HTMLWBRElement::HTMLWBRElement(const QualifiedName& tagName, Document& document)
- : HTMLElement(tagName, document)
-{
- ASSERT(hasTagName(wbrTag));
-}
-
-RenderPtr<RenderElement> HTMLWBRElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
-{
- return createRenderer<RenderLineBreak>(*this, WTF::move(style));
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLWBRElement.h b/Source/WebCore/html/HTMLWBRElement.h
deleted file mode 100644
index 7047516a7..000000000
--- a/Source/WebCore/html/HTMLWBRElement.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLWBRElement_h
-#define HTMLWBRElement_h
-
-#include "HTMLElement.h"
-
-namespace WebCore {
-
-class HTMLWBRElement final : public HTMLElement {
-public:
- static Ref<HTMLWBRElement> create(const QualifiedName&, Document&);
-
-private:
- HTMLWBRElement(const QualifiedName&, Document&);
-
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
-};
-
-} // namespace WebCore
-
-#endif // HTMLWBRElement_h
-
diff --git a/Source/WebCore/html/HiddenInputType.cpp b/Source/WebCore/html/HiddenInputType.cpp
index d6ee16798..15eac5d51 100644
--- a/Source/WebCore/html/HiddenInputType.cpp
+++ b/Source/WebCore/html/HiddenInputType.cpp
@@ -67,7 +67,7 @@ bool HiddenInputType::supportsValidation() const
return false;
}
-RenderPtr<RenderElement> HiddenInputType::createInputRenderer(Ref<RenderStyle>&&)
+RenderPtr<RenderElement> HiddenInputType::createInputRenderer(PassRef<RenderStyle>)
{
ASSERT_NOT_REACHED();
return nullptr;
diff --git a/Source/WebCore/html/HiddenInputType.h b/Source/WebCore/html/HiddenInputType.h
index ee6d319e1..29208e0ad 100644
--- a/Source/WebCore/html/HiddenInputType.h
+++ b/Source/WebCore/html/HiddenInputType.h
@@ -35,7 +35,7 @@
namespace WebCore {
-class HiddenInputType final : public InputType {
+class HiddenInputType : public InputType {
public:
explicit HiddenInputType(HTMLInputElement& element) : InputType(element) { }
@@ -44,7 +44,7 @@ private:
virtual FormControlState saveFormControlState() const override;
virtual void restoreFormControlState(const FormControlState&) override;
virtual bool supportsValidation() const override;
- virtual RenderPtr<RenderElement> createInputRenderer(Ref<RenderStyle>&&) override;
+ virtual RenderPtr<RenderElement> createInputRenderer(PassRef<RenderStyle>) override;
virtual void accessKeyAction(bool sendMouseEvents) override;
virtual bool rendererIsNeeded() override;
virtual bool storesValueSeparateFromAttribute() override;
diff --git a/Source/WebCore/html/ImageData.cpp b/Source/WebCore/html/ImageData.cpp
index 27b57c372..57afb0b72 100644
--- a/Source/WebCore/html/ImageData.cpp
+++ b/Source/WebCore/html/ImageData.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -30,33 +29,8 @@
#include "config.h"
#include "ImageData.h"
-#include "ExceptionCode.h"
-#include <runtime/JSCInlines.h>
-#include <runtime/TypedArrayInlines.h>
-
namespace WebCore {
-PassRefPtr<ImageData> ImageData::create(unsigned sw, unsigned sh, ExceptionCode& ec)
-{
- if (!sw || !sh) {
- ec = INDEX_SIZE_ERR;
- return nullptr;
- }
-
- Checked<int, RecordOverflow> dataSize = 4;
- dataSize *= sw;
- dataSize *= sh;
- if (dataSize.hasOverflowed()) {
- ec = TypeError;
- return nullptr;
- }
-
- IntSize size(sw, sh);
- RefPtr<ImageData> data = adoptRef(new ImageData(size));
- data->data()->zeroFill();
- return data.release();
-}
-
PassRefPtr<ImageData> ImageData::create(const IntSize& size)
{
Checked<int, RecordOverflow> dataSize = 4;
@@ -83,34 +57,6 @@ PassRefPtr<ImageData> ImageData::create(const IntSize& size, PassRefPtr<Uint8Cla
return adoptRef(new ImageData(size, byteArray));
}
-PassRefPtr<ImageData> ImageData::create(PassRefPtr<Uint8ClampedArray> byteArray, unsigned sw, unsigned sh, ExceptionCode& ec)
-{
- unsigned length = byteArray->length();
- if (!length || length % 4 != 0) {
- ec = INVALID_STATE_ERR;
- return nullptr;
- }
-
- if (!sw) {
- ec = INDEX_SIZE_ERR;
- return nullptr;
- }
-
- length /= 4;
- if (length % sw != 0) {
- ec = INVALID_STATE_ERR;
- return nullptr;
- }
-
- unsigned height = length / sw;
- if (sh && sh != height) {
- ec = INDEX_SIZE_ERR;
- return nullptr;
- }
-
- return create(IntSize(sw, height), byteArray);
-}
-
ImageData::ImageData(const IntSize& size)
: m_size(size)
, m_data(Uint8ClampedArray::createUninitialized(size.width() * size.height() * 4))
diff --git a/Source/WebCore/html/ImageData.h b/Source/WebCore/html/ImageData.h
index 7d121d1fd..a90077938 100644
--- a/Source/WebCore/html/ImageData.h
+++ b/Source/WebCore/html/ImageData.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -36,14 +36,10 @@
namespace WebCore {
-typedef int ExceptionCode;
-
class ImageData : public RefCounted<ImageData> {
public:
- static PassRefPtr<ImageData> create(unsigned sw, unsigned sh, ExceptionCode&);
static PassRefPtr<ImageData> create(const IntSize&);
static PassRefPtr<ImageData> create(const IntSize&, PassRefPtr<Uint8ClampedArray>);
- static PassRefPtr<ImageData> create(PassRefPtr<Uint8ClampedArray>, unsigned sw, unsigned sh, ExceptionCode&);
IntSize size() const { return m_size; }
int width() const { return m_size.width(); }
diff --git a/Source/WebCore/html/ImageData.idl b/Source/WebCore/html/ImageData.idl
index 980ab2cc1..44102a10e 100644
--- a/Source/WebCore/html/ImageData.idl
+++ b/Source/WebCore/html/ImageData.idl
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -27,14 +27,7 @@
*/
[
- GlobalContext=DOMWindow&WorkerGlobalScope,
CustomToJSObject,
- // FIXME: Without [Default=Undefined] CodeGeneratorJS can't generate JSImageData. But with
- // the extended attribute we accept a value of 0 for sh and don't throw.
- // https://bugs.webkit.org/show_bug.cgi?id=130667
- Constructor(Uint8ClampedArray data, unsigned long sw, [Default=Undefined] optional unsigned long sh),
- Constructor(unsigned long sw, unsigned long sh),
- ConstructorRaisesException,
ImplementationLacksVTable
] interface ImageData {
readonly attribute long width;
diff --git a/Source/WebCore/html/ImageDocument.cpp b/Source/WebCore/html/ImageDocument.cpp
index 891e67e52..fd4de6490 100644
--- a/Source/WebCore/html/ImageDocument.cpp
+++ b/Source/WebCore/html/ImageDocument.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2010, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
@@ -26,7 +26,6 @@
#include "ImageDocument.h"
#include "CachedImage.h"
-#include "Chrome.h"
#include "DocumentLoader.h"
#include "EventListener.h"
#include "EventNames.h"
@@ -34,64 +33,72 @@
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "FrameView.h"
-#include "HTMLBodyElement.h"
#include "HTMLHtmlElement.h"
#include "HTMLImageElement.h"
#include "HTMLNames.h"
#include "LocalizedStrings.h"
-#include "MIMETypeRegistry.h"
#include "MainFrame.h"
#include "MouseEvent.h"
+#include "NotImplemented.h"
#include "Page.h"
#include "RawDataDocumentParser.h"
#include "RenderElement.h"
+#include "ResourceBuffer.h"
#include "Settings.h"
namespace WebCore {
using namespace HTMLNames;
-#if !PLATFORM(IOS)
-class ImageEventListener final : public EventListener {
+class ImageEventListener : public EventListener {
public:
- static Ref<ImageEventListener> create(ImageDocument& document) { return adoptRef(*new ImageEventListener(document)); }
+ static PassRefPtr<ImageEventListener> create(ImageDocument* document) { return adoptRef(new ImageEventListener(document)); }
+ static const ImageEventListener* cast(const EventListener* listener)
+ {
+ return listener->type() == ImageEventListenerType
+ ? static_cast<const ImageEventListener*>(listener)
+ : 0;
+ }
+
+ virtual bool operator==(const EventListener& other) override;
private:
- ImageEventListener(ImageDocument& document)
+ ImageEventListener(ImageDocument* document)
: EventListener(ImageEventListenerType)
- , m_document(document)
+ , m_doc(document)
{
}
- virtual bool operator==(const EventListener&) override;
virtual void handleEvent(ScriptExecutionContext*, Event*) override;
- ImageDocument& m_document;
+ ImageDocument* m_doc;
};
-#endif
-
+
class ImageDocumentParser final : public RawDataDocumentParser {
public:
- static Ref<ImageDocumentParser> create(ImageDocument& document)
+ static PassRefPtr<ImageDocumentParser> create(ImageDocument& document)
{
- return adoptRef(*new ImageDocumentParser(document));
+ return adoptRef(new ImageDocumentParser(document));
}
+ ImageDocument* document() const
+ {
+ return toImageDocument(RawDataDocumentParser::document());
+ }
+
private:
ImageDocumentParser(ImageDocument& document)
: RawDataDocumentParser(document)
{
}
- ImageDocument& document() const;
-
virtual void appendBytes(DocumentWriter&, const char*, size_t) override;
virtual void finish() override;
};
class ImageDocumentElement final : public HTMLImageElement {
public:
- static RefPtr<ImageDocumentElement> create(ImageDocument&);
+ static PassRefPtr<ImageDocumentElement> create(ImageDocument&);
private:
ImageDocumentElement(ImageDocument& document)
@@ -106,103 +113,80 @@ private:
ImageDocument* m_imageDocument;
};
-inline RefPtr<ImageDocumentElement> ImageDocumentElement::create(ImageDocument& document)
+inline PassRefPtr<ImageDocumentElement> ImageDocumentElement::create(ImageDocument& document)
{
return adoptRef(new ImageDocumentElement(document));
}
// --------
-HTMLImageElement* ImageDocument::imageElement() const
-{
- return m_imageElement;
-}
-
-LayoutSize ImageDocument::imageSize()
+static float pageZoomFactor(const Document* document)
{
- ASSERT(m_imageElement);
- updateStyleIfNeeded();
- return m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), frame() ? frame()->pageZoomFactor() : 1);
+ Frame* frame = document->frame();
+ return frame ? frame->pageZoomFactor() : 1;
}
-void ImageDocument::updateDuringParsing()
+void ImageDocumentParser::appendBytes(DocumentWriter&, const char*, size_t)
{
- if (!frame()->settings().areImagesEnabled())
+ Frame* frame = document()->frame();
+ if (!frame->loader().client().allowImage(frame->settings().areImagesEnabled(), document()->url()))
return;
- if (!m_imageElement)
- createDocumentStructure();
-
- if (RefPtr<SharedBuffer> buffer = loader()->mainResourceData())
- m_imageElement->cachedImage()->addDataBuffer(*buffer);
+ CachedImage* cachedImage = document()->cachedImage();
+ RefPtr<ResourceBuffer> resourceData = frame->loader().documentLoader()->mainResourceData();
+ cachedImage->addDataBuffer(resourceData.get());
- imageUpdated();
+ document()->imageUpdated();
}
-void ImageDocument::finishedParsing()
+void ImageDocumentParser::finish()
{
- if (!parser()->isStopped() && m_imageElement) {
- CachedImage& cachedImage = *m_imageElement->cachedImage();
- RefPtr<SharedBuffer> data = loader()->mainResourceData();
+ if (!isStopped() && document()->imageElement()) {
+ CachedImage* cachedImage = document()->cachedImage();
+ RefPtr<ResourceBuffer> data = document()->frame()->loader().documentLoader()->mainResourceData();
// If this is a multipart image, make a copy of the current part, since the resource data
// will be overwritten by the next part.
- if (data && loader()->isLoadingMultipartContent())
+ if (document()->frame()->loader().documentLoader()->isLoadingMultipartContent())
data = data->copy();
- cachedImage.finishLoading(data.get());
- cachedImage.finish();
+ cachedImage->finishLoading(data.get());
+ cachedImage->finish();
+
+ cachedImage->setResponse(document()->frame()->loader().documentLoader()->response());
// Report the natural image size in the page title, regardless of zoom level.
// At a zoom level of 1 the image is guaranteed to have an integer size.
- updateStyleIfNeeded();
- IntSize size = flooredIntSize(cachedImage.imageSizeForRenderer(m_imageElement->renderer(), 1));
+ IntSize size = flooredIntSize(cachedImage->imageSizeForRenderer(document()->imageElement()->renderer(), 1.0f));
if (size.width()) {
- // Compute the title. We use the decoded filename of the resource, falling
- // back on the hostname if there is no path.
- String name = decodeURLEscapeSequences(url().lastPathComponent());
- if (name.isEmpty())
- name = url().host();
- setTitle(imageTitle(name, size));
+ // Compute the title, we use the decoded filename of the resource, falling
+ // back on the (decoded) hostname if there is no path.
+ String fileName = decodeURLEscapeSequences(document()->url().lastPathComponent());
+ if (fileName.isEmpty())
+ fileName = document()->url().host();
+ document()->setTitle(imageTitle(fileName, size));
}
- imageUpdated();
+ document()->imageUpdated();
}
- HTMLDocument::finishedParsing();
+ document()->finishedParsing();
}
-inline ImageDocument& ImageDocumentParser::document() const
-{
- // Only used during parsing, so document is guaranteed to be non-null.
- ASSERT(RawDataDocumentParser::document());
- return downcast<ImageDocument>(*RawDataDocumentParser::document());
-}
-
-void ImageDocumentParser::appendBytes(DocumentWriter&, const char*, size_t)
-{
- document().updateDuringParsing();
-}
-
-void ImageDocumentParser::finish()
-{
- document().finishedParsing();
-}
+// --------
-ImageDocument::ImageDocument(Frame& frame, const URL& url)
- : HTMLDocument(&frame, url, ImageDocumentClass)
- , m_imageElement(nullptr)
+ImageDocument::ImageDocument(Frame* frame, const URL& url)
+ : HTMLDocument(frame, url, ImageDocumentClass)
+ , m_imageElement(0)
, m_imageSizeIsKnown(false)
-#if !PLATFORM(IOS)
, m_didShrinkImage(false)
-#endif
- , m_shouldShrinkImage(frame.settings().shrinksStandaloneImagesToFit() && frame.isMainFrame())
+ , m_shouldShrinkImage(shouldShrinkToFit())
{
- setCompatibilityMode(DocumentCompatibilityMode::QuirksMode);
+ setCompatibilityMode(QuirksMode);
lockCompatibilityMode();
}
-Ref<DocumentParser> ImageDocument::createParser()
+PassRefPtr<DocumentParser> ImageDocument::createParser()
{
return ImageDocumentParser::create(*this);
}
@@ -210,132 +194,163 @@ Ref<DocumentParser> ImageDocument::createParser()
void ImageDocument::createDocumentStructure()
{
RefPtr<Element> rootElement = Document::createElement(htmlTag, false);
- appendChild(rootElement);
- downcast<HTMLHtmlElement>(*rootElement).insertedByParser();
+ appendChild(rootElement, IGNORE_EXCEPTION);
+ toHTMLHtmlElement(rootElement.get())->insertedByParser();
- frame()->injectUserScripts(InjectAtDocumentStart);
+ if (frame())
+ frame()->injectUserScripts(InjectAtDocumentStart);
RefPtr<Element> body = Document::createElement(bodyTag, false);
- body->setAttribute(styleAttr, "margin: 0px");
- if (MIMETypeRegistry::isPDFMIMEType(document().loader()->responseMIMEType()))
- downcast<HTMLBodyElement>(*body).setInlineStyleProperty(CSSPropertyBackgroundColor, "white", CSSPrimitiveValue::CSS_IDENT);
- rootElement->appendChild(body);
+ body->setAttribute(styleAttr, "margin: 0px;");
+
+ rootElement->appendChild(body, IGNORE_EXCEPTION);
RefPtr<ImageDocumentElement> imageElement = ImageDocumentElement::create(*this);
- if (m_shouldShrinkImage)
- imageElement->setAttribute(styleAttr, "-webkit-user-select:none; display:block; margin:auto;");
- else
- imageElement->setAttribute(styleAttr, "-webkit-user-select:none;");
+
+ imageElement->setAttribute(styleAttr, "-webkit-user-select: none");
imageElement->setLoadManually(true);
imageElement->setSrc(url().string());
- imageElement->cachedImage()->setResponse(loader()->response());
- body->appendChild(imageElement);
- if (m_shouldShrinkImage) {
+ body->appendChild(imageElement, IGNORE_EXCEPTION);
+
+ if (shouldShrinkToFit()) {
+ // Add event listeners
+ RefPtr<EventListener> listener = ImageEventListener::create(this);
+ if (DOMWindow* domWindow = this->domWindow())
+ domWindow->addEventListener("resize", listener, false);
+ imageElement->addEventListener("click", listener.release(), false);
#if PLATFORM(IOS)
// Set the viewport to be in device pixels (rather than the default of 980).
processViewport(ASCIILiteral("width=device-width"), ViewportArguments::ImageDocument);
-#else
- RefPtr<EventListener> listener = ImageEventListener::create(*this);
- if (DOMWindow* window = this->domWindow())
- window->addEventListener("resize", listener, false);
- imageElement->addEventListener("click", listener.release(), false);
#endif
}
m_imageElement = imageElement.get();
}
-void ImageDocument::imageUpdated()
+float ImageDocument::scale() const
{
- ASSERT(m_imageElement);
-
- if (m_imageSizeIsKnown)
- return;
-
- LayoutSize imageSize = this->imageSize();
- if (imageSize.isEmpty())
- return;
-
- m_imageSizeIsKnown = true;
-
- if (m_shouldShrinkImage) {
#if PLATFORM(IOS)
- FloatSize screenSize = page()->chrome().screenSize();
- if (imageSize.width() > screenSize.width())
- processViewport(String::format("width=%u", static_cast<unsigned>(imageSize.width().toInt())), ViewportArguments::ImageDocument);
+ // On iOS big images are subsampled to make them smaller. So, don't resize them.
+ return 1;
#else
- // Call windowSizeChanged for its side effect of sizing the image.
- windowSizeChanged();
-#endif
- }
-}
-
-#if !PLATFORM(IOS)
-float ImageDocument::scale()
-{
if (!m_imageElement)
return 1;
- FrameView* view = this->view();
+ FrameView* view = frame()->view();
if (!view)
return 1;
- LayoutSize imageSize = this->imageSize();
+ LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
+ LayoutSize windowSize = LayoutSize(view->width(), view->height());
- IntSize viewportSize = view->visibleSize();
- float widthScale = viewportSize.width() / imageSize.width().toFloat();
- float heightScale = viewportSize.height() / imageSize.height().toFloat();
+ float widthScale = static_cast<float>(windowSize.width()) / imageSize.width();
+ float heightScale = static_cast<float>(windowSize.height()) / imageSize.height();
return std::min(widthScale, heightScale);
+#endif
}
void ImageDocument::resizeImageToFit()
{
+#if PLATFORM(IOS)
+ // On iOS big images are subsampled to make them smaller. So, don't resize them.
+#else
if (!m_imageElement)
return;
- LayoutSize imageSize = this->imageSize();
+ LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
float scale = this->scale();
m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale));
m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale));
- m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn);
+ m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueWebkitZoomIn);
+#endif
+}
+
+void ImageDocument::imageClicked(int x, int y)
+{
+#if PLATFORM(IOS)
+ // On iOS big images are subsampled to make them smaller. So, don't resize them.
+ UNUSED_PARAM(x);
+ UNUSED_PARAM(y);
+#else
+ if (!m_imageSizeIsKnown || imageFitsInWindow())
+ return;
+
+ m_shouldShrinkImage = !m_shouldShrinkImage;
+
+ if (m_shouldShrinkImage)
+ windowSizeChanged();
+ else {
+ restoreImageSize();
+
+ updateLayout();
+
+ float scale = this->scale();
+
+ int scrollX = static_cast<int>(x / scale - (float)frame()->view()->width() / 2);
+ int scrollY = static_cast<int>(y / scale - (float)frame()->view()->height() / 2);
+
+ frame()->view()->setScrollPosition(IntPoint(scrollX, scrollY));
+ }
+#endif
+}
+
+void ImageDocument::imageUpdated()
+{
+ ASSERT(m_imageElement);
+
+ if (m_imageSizeIsKnown)
+ return;
+
+ if (m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this)).isEmpty())
+ return;
+
+ m_imageSizeIsKnown = true;
+
+ if (shouldShrinkToFit()) {
+ // Force resizing of the image
+ windowSizeChanged();
+ }
}
void ImageDocument::restoreImageSize()
{
if (!m_imageElement || !m_imageSizeIsKnown)
return;
-
- LayoutSize imageSize = this->imageSize();
+
+ LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
m_imageElement->setWidth(imageSize.width());
m_imageElement->setHeight(imageSize.height());
-
+
if (imageFitsInWindow())
m_imageElement->removeInlineStyleProperty(CSSPropertyCursor);
else
- m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut);
-
+ m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueWebkitZoomOut);
+
m_didShrinkImage = false;
}
-bool ImageDocument::imageFitsInWindow()
+bool ImageDocument::imageFitsInWindow() const
{
if (!m_imageElement)
return true;
- FrameView* view = this->view();
+ FrameView* view = frame()->view();
if (!view)
return true;
- LayoutSize imageSize = this->imageSize();
- IntSize viewportSize = view->visibleSize();
- return imageSize.width() <= viewportSize.width() && imageSize.height() <= viewportSize.height();
+ LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
+#if PLATFORM(IOS)
+ LayoutSize windowSize = view->contentsToScreen(view->visibleContentRect()).size();
+#else
+ LayoutSize windowSize = LayoutSize(view->width(), view->height());
+#endif
+ return imageSize.width() <= windowSize.width() && imageSize.height() <= windowSize.height();
}
-
void ImageDocument::windowSizeChanged()
{
if (!m_imageElement || !m_imageSizeIsKnown)
@@ -343,18 +358,32 @@ void ImageDocument::windowSizeChanged()
bool fitsInWindow = imageFitsInWindow();
+#if PLATFORM(IOS)
+ if (fitsInWindow)
+ return;
+
+ LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
+ LayoutRect visibleScreenSize = frame()->view()->contentsToScreen(frame()->view()->visibleContentRect());
+
+ float widthScale = static_cast<float>(visibleScreenSize.width()) / imageSize.width();
+ float heightScale = static_cast<float>(visibleScreenSize.height()) / imageSize.height();
+ if (widthScale < heightScale)
+ processViewport(String::format("width=%d", imageSize.width().toInt()), ViewportArguments::ImageDocument);
+ else
+ processViewport(String::format("width=%d", static_cast<int>(1.0f + (1.0f - heightScale)) * imageSize.width().toInt()), ViewportArguments::ImageDocument);
+#else
// If the image has been explicitly zoomed in, restore the cursor if the image fits
// and set it to a zoom out cursor if the image doesn't fit
if (!m_shouldShrinkImage) {
if (fitsInWindow)
m_imageElement->removeInlineStyleProperty(CSSPropertyCursor);
else
- m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut);
+ m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueWebkitZoomOut);
return;
}
if (m_didShrinkImage) {
- // If the window has been resized so that the image fits, restore the image size,
+ // If the window has been resized so that the image fits, restore the image size
// otherwise update the restored image size.
if (fitsInWindow)
restoreImageSize();
@@ -367,49 +396,38 @@ void ImageDocument::windowSizeChanged()
m_didShrinkImage = true;
}
}
+#endif
}
-void ImageDocument::imageClicked(int x, int y)
-{
- if (!m_imageSizeIsKnown || imageFitsInWindow())
- return;
-
- m_shouldShrinkImage = !m_shouldShrinkImage;
-
- if (m_shouldShrinkImage) {
- // Call windowSizeChanged for its side effect of sizing the image.
- windowSizeChanged();
- } else {
- restoreImageSize();
-
- updateLayout();
-
- float scale = this->scale();
-
- IntSize viewportSize = view()->visibleSize();
- int scrollX = static_cast<int>(x / scale - viewportSize.width() / 2.0f);
- int scrollY = static_cast<int>(y / scale - viewportSize.height() / 2.0f);
+CachedImage* ImageDocument::cachedImage()
+{
+ if (!m_imageElement)
+ createDocumentStructure();
+
+ return m_imageElement->cachedImage();
+}
- view()->setScrollPosition(IntPoint(scrollX, scrollY));
- }
+bool ImageDocument::shouldShrinkToFit() const
+{
+ return frame()->settings().shrinksStandaloneImagesToFit() && frame()->isMainFrame();
}
void ImageEventListener::handleEvent(ScriptExecutionContext*, Event* event)
{
if (event->type() == eventNames().resizeEvent)
- m_document.windowSizeChanged();
- else if (event->type() == eventNames().clickEvent && is<MouseEvent>(*event)) {
- MouseEvent& mouseEvent = downcast<MouseEvent>(*event);
- m_document.imageClicked(mouseEvent.x(), mouseEvent.y());
+ m_doc->windowSizeChanged();
+ else if (event->type() == eventNames().clickEvent && event->isMouseEvent()) {
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ m_doc->imageClicked(mouseEvent->x(), mouseEvent->y());
}
}
-bool ImageEventListener::operator==(const EventListener& other)
+bool ImageEventListener::operator==(const EventListener& listener)
{
- // All ImageEventListener objects compare as equal; OK since there is only one per document.
- return other.type() == ImageEventListenerType;
+ if (const ImageEventListener* imageEventListener = ImageEventListener::cast(&listener))
+ return m_doc == imageEventListener->m_doc;
+ return false;
}
-#endif
// --------
@@ -423,7 +441,7 @@ void ImageDocumentElement::didMoveToNewDocument(Document* oldDocument)
{
if (m_imageDocument) {
m_imageDocument->disconnectImageElement();
- m_imageDocument = nullptr;
+ m_imageDocument = 0;
}
HTMLImageElement::didMoveToNewDocument(oldDocument);
}
diff --git a/Source/WebCore/html/ImageDocument.h b/Source/WebCore/html/ImageDocument.h
index 5e7e4bd5b..a18fdef55 100644
--- a/Source/WebCore/html/ImageDocument.h
+++ b/Source/WebCore/html/ImageDocument.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
@@ -29,64 +29,53 @@
namespace WebCore {
+class CachedImage;
class ImageDocumentElement;
-class HTMLImageElement;
class ImageDocument final : public HTMLDocument {
public:
- static Ref<ImageDocument> create(Frame& frame, const URL& url)
+ static PassRefPtr<ImageDocument> create(Frame* frame, const URL& url)
{
- return adoptRef(*new ImageDocument(frame, url));
+ return adoptRef(new ImageDocument(frame, url));
}
- WEBCORE_EXPORT HTMLImageElement* imageElement() const;
-
- void updateDuringParsing();
- void finishedParsing();
-
- void disconnectImageElement() { m_imageElement = nullptr; }
-
-#if !PLATFORM(IOS)
+ CachedImage* cachedImage();
+ ImageDocumentElement* imageElement() const { return m_imageElement; }
+ void disconnectImageElement() { m_imageElement = 0; }
+
void windowSizeChanged();
+ void imageUpdated();
void imageClicked(int x, int y);
-#endif
private:
- ImageDocument(Frame&, const URL&);
-
- virtual Ref<DocumentParser> createParser() override;
-
- LayoutSize imageSize();
+ ImageDocument(Frame*, const URL&);
+ virtual PassRefPtr<DocumentParser> createParser() override;
+
void createDocumentStructure();
-#if !PLATFORM(IOS)
void resizeImageToFit();
void restoreImageSize();
- bool imageFitsInWindow();
- float scale();
-#endif
-
- void imageUpdated();
-
+ bool imageFitsInWindow() const;
+ bool shouldShrinkToFit() const;
+ float scale() const;
+
ImageDocumentElement* m_imageElement;
-
- // Whether enough of the image has been loaded to determine its size.
+
+ // Whether enough of the image has been loaded to determine its size
bool m_imageSizeIsKnown;
-
-#if !PLATFORM(IOS)
- // Whether the image is shrunk to fit or not.
+
+ // Whether the image is shrunk to fit or not
bool m_didShrinkImage;
-#endif
-
- // Whether the image should be shrunk or not.
+
+ // Whether the image should be shrunk or not
bool m_shouldShrinkImage;
};
-} // namespace WebCore
+inline bool isImageDocument(const Document& document) { return document.isImageDocument(); }
+void isImageDocument(const ImageDocument&); // Catch unnecessary runtime check of type known at compile time.
+
+DOCUMENT_TYPE_CASTS(ImageDocument)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ImageDocument)
- static bool isType(const WebCore::Document& document) { return document.isImageDocument(); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::Document>(node) && isType(downcast<WebCore::Document>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+}
#endif // ImageDocument_h
diff --git a/Source/WebCore/html/ImageInputType.cpp b/Source/WebCore/html/ImageInputType.cpp
index 9548c9c02..803358efe 100644
--- a/Source/WebCore/html/ImageInputType.cpp
+++ b/Source/WebCore/html/ImageInputType.cpp
@@ -64,8 +64,8 @@ bool ImageInputType::appendFormData(FormDataList& encoding, bool) const
return true;
}
- DEPRECATED_DEFINE_STATIC_LOCAL(String, dotXString, (ASCIILiteral(".x")));
- DEPRECATED_DEFINE_STATIC_LOCAL(String, dotYString, (ASCIILiteral(".y")));
+ DEFINE_STATIC_LOCAL(String, dotXString, (ASCIILiteral(".x")));
+ DEFINE_STATIC_LOCAL(String, dotYString, (ASCIILiteral(".y")));
encoding.appendData(name + dotXString, m_clickLocation.x());
encoding.appendData(name + dotYString, m_clickLocation.y());
@@ -89,8 +89,8 @@ void ImageInputType::handleDOMActivateEvent(Event* event)
m_clickLocation = IntPoint();
if (event->underlyingEvent()) {
Event& underlyingEvent = *event->underlyingEvent();
- if (is<MouseEvent>(underlyingEvent)) {
- MouseEvent& mouseEvent = downcast<MouseEvent>(underlyingEvent);
+ if (underlyingEvent.isMouseEvent()) {
+ MouseEvent& mouseEvent = toMouseEvent(underlyingEvent);
if (!mouseEvent.isSimulated())
m_clickLocation = IntPoint(mouseEvent.offsetX(), mouseEvent.offsetY());
}
@@ -101,46 +101,46 @@ void ImageInputType::handleDOMActivateEvent(Event* event)
event->setDefaultHandled();
}
-RenderPtr<RenderElement> ImageInputType::createInputRenderer(Ref<RenderStyle>&& style)
+RenderPtr<RenderElement> ImageInputType::createInputRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderImage>(element(), WTF::move(style));
+ return createRenderer<RenderImage>(element(), std::move(style));
}
void ImageInputType::altAttributeChanged()
{
- auto* renderer = downcast<RenderImage>(element().renderer());
- if (!renderer)
+ RenderImage* image = toRenderImage(element().renderer());
+ if (!image)
return;
- renderer->updateAltText();
+ image->updateAltText();
}
void ImageInputType::srcAttributeChanged()
{
if (!element().renderer())
return;
- element().ensureImageLoader().updateFromElementIgnoringPreviousError();
+ element().imageLoader()->updateFromElementIgnoringPreviousError();
}
void ImageInputType::attach()
{
BaseButtonInputType::attach();
- HTMLImageLoader& imageLoader = element().ensureImageLoader();
- imageLoader.updateFromElement();
+ HTMLImageLoader* imageLoader = element().imageLoader();
+ imageLoader->updateFromElement();
- auto* renderer = downcast<RenderImage>(element().renderer());
+ RenderImage* renderer = toRenderImage(element().renderer());
if (!renderer)
return;
- if (imageLoader.hasPendingBeforeLoadEvent())
+ if (imageLoader->hasPendingBeforeLoadEvent())
return;
auto& imageResource = renderer->imageResource();
- imageResource.setCachedImage(imageLoader.image());
+ imageResource.setCachedImage(imageLoader->image());
// If we have no image at all because we have no src attribute, set
// image height and width for the alt text instead.
- if (!imageLoader.image() && !imageResource.cachedImage())
+ if (!imageLoader->image() && !imageResource.cachedImage())
renderer->setImageSizeForAltText();
}
@@ -180,9 +180,11 @@ unsigned ImageInputType::height() const
return height;
// If the image is available, use its height.
- HTMLImageLoader* imageLoader = element->imageLoader();
- if (imageLoader && imageLoader->image())
- return imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).height();
+ if (element->hasImageLoader()) {
+ HTMLImageLoader* imageLoader = element->imageLoader();
+ if (imageLoader->image())
+ return imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).height();
+ }
}
element->document().updateLayout();
@@ -202,9 +204,11 @@ unsigned ImageInputType::width() const
return width;
// If the image is available, use its width.
- HTMLImageLoader* imageLoader = element->imageLoader();
- if (imageLoader && imageLoader->image())
- return imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).width();
+ if (element->hasImageLoader()) {
+ HTMLImageLoader* imageLoader = element->imageLoader();
+ if (imageLoader->image())
+ return imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).width();
+ }
}
element->document().updateLayout();
diff --git a/Source/WebCore/html/ImageInputType.h b/Source/WebCore/html/ImageInputType.h
index 7236d31fa..a3c2f8549 100644
--- a/Source/WebCore/html/ImageInputType.h
+++ b/Source/WebCore/html/ImageInputType.h
@@ -38,7 +38,7 @@
namespace WebCore {
-class ImageInputType final : public BaseButtonInputType {
+class ImageInputType : public BaseButtonInputType {
public:
explicit ImageInputType(HTMLInputElement&);
@@ -47,7 +47,7 @@ private:
virtual bool isFormDataAppendable() const override;
virtual bool appendFormData(FormDataList&, bool) const override;
virtual bool supportsValidation() const override;
- virtual RenderPtr<RenderElement> createInputRenderer(Ref<RenderStyle>&&) override;
+ virtual RenderPtr<RenderElement> createInputRenderer(PassRef<RenderStyle>) override;
virtual void handleDOMActivateEvent(Event*) override;
virtual void altAttributeChanged() override;
virtual void srcAttributeChanged() override;
diff --git a/Source/WebCore/html/InputType.cpp b/Source/WebCore/html/InputType.cpp
index 607cebe22..3857d1575 100644
--- a/Source/WebCore/html/InputType.cpp
+++ b/Source/WebCore/html/InputType.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
* Copyright (C) 2009, 2010, 2011, 2012 Google Inc. All rights reserved.
@@ -471,7 +471,7 @@ void InputType::forwardEvent(Event*)
bool InputType::shouldSubmitImplicitly(Event* event)
{
- return is<KeyboardEvent>(*event) && event->type() == eventNames().keypressEvent && downcast<KeyboardEvent>(*event).charCode() == '\r';
+ return event->isKeyboardEvent() && event->type() == eventNames().keypressEvent && static_cast<KeyboardEvent*>(event)->charCode() == '\r';
}
PassRefPtr<HTMLFormElement> InputType::formForSubmission() const
@@ -479,9 +479,9 @@ PassRefPtr<HTMLFormElement> InputType::formForSubmission() const
return element().form();
}
-RenderPtr<RenderElement> InputType::createInputRenderer(Ref<RenderStyle>&& style)
+RenderPtr<RenderElement> InputType::createInputRenderer(PassRef<RenderStyle> style)
{
- return RenderPtr<RenderElement>(RenderElement::createFor(element(), WTF::move(style)));
+ return RenderPtr<RenderElement>(RenderElement::createFor(element(), std::move(style)));
}
void InputType::blur()
@@ -604,10 +604,6 @@ void InputType::srcAttributeChanged()
{
}
-void InputType::maxResultsAttributeChanged()
-{
-}
-
bool InputType::shouldRespectAlignAttribute()
{
return false;
@@ -665,6 +661,11 @@ String InputType::defaultValue() const
return String();
}
+bool InputType::canSetSuggestedValue()
+{
+ return false;
+}
+
bool InputType::shouldSendChangeEventAfterCheckedChanged()
{
return true;
@@ -717,11 +718,6 @@ String InputType::visibleValue() const
return element().value();
}
-bool InputType::isEmptyValue() const
-{
- return true;
-}
-
String InputType::sanitizeValue(const String& proposedValue) const
{
return proposedValue;
@@ -759,6 +755,11 @@ bool InputType::shouldRespectListAttribute()
return false;
}
+bool InputType::shouldRespectSpeechAttribute()
+{
+ return false;
+}
+
bool InputType::isTextButton() const
{
return false;
@@ -924,11 +925,7 @@ void InputType::requiredAttributeChanged()
{
}
-void InputType::capsLockStateMayHaveChanged()
-{
-}
-
-void InputType::updateAutoFillButton()
+void InputType::valueAttributeChanged()
{
}
@@ -961,6 +958,10 @@ Decimal InputType::findClosestTickMarkValue(const Decimal&)
}
#endif
+void InputType::updateClearButtonVisibility()
+{
+}
+
bool InputType::supportsIndeterminateAppearance() const
{
return false;
@@ -1149,4 +1150,12 @@ void InputType::stepUpFromRenderer(int n)
}
}
+void InputType::observeFeatureIfVisible(FeatureObserver::Feature feature) const
+{
+ if (RenderStyle* style = element().renderStyle()) {
+ if (style->visibility() != HIDDEN)
+ FeatureObserver::observe(&element().document(), feature);
+ }
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/html/InputType.h b/Source/WebCore/html/InputType.h
index 70e89394b..a5d606df9 100644
--- a/Source/WebCore/html/InputType.h
+++ b/Source/WebCore/html/InputType.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
- * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2012 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,7 @@
#ifndef InputType_h
#define InputType_h
+#include "FeatureObserver.h"
#include "HTMLTextFormControlElement.h"
#include "RenderPtr.h"
#include "StepRange.h"
@@ -174,7 +175,6 @@ public:
virtual bool canSetStringValue() const;
virtual String localizeValue(const String&) const;
virtual String visibleValue() const;
- virtual bool isEmptyValue() const;
// Returing the null string means "use the default value."
// This function must be called only by HTMLInputElement::sanitizeValue().
virtual String sanitizeValue(const String&) const;
@@ -224,17 +224,20 @@ public:
virtual HTMLElement* innerBlockElement() const { return nullptr; }
virtual TextControlInnerTextElement* innerTextElement() const { return nullptr; }
virtual HTMLElement* innerSpinButtonElement() const { return nullptr; }
- virtual HTMLElement* capsLockIndicatorElement() const { return nullptr; }
- virtual HTMLElement* autoFillButtonElement() const { return nullptr; }
virtual HTMLElement* resultsButtonElement() const { return nullptr; }
virtual HTMLElement* cancelButtonElement() const { return nullptr; }
virtual HTMLElement* sliderThumbElement() const { return nullptr; }
virtual HTMLElement* sliderTrackElement() const { return nullptr; }
virtual HTMLElement* placeholderElement() const;
+#if ENABLE(INPUT_SPEECH)
+ virtual HTMLElement* speechButtonElement() const { return nullptr; }
+#endif
+
// Miscellaneous functions
+
virtual bool rendererIsNeeded();
- virtual RenderPtr<RenderElement> createInputRenderer(Ref<RenderStyle>&&);
+ virtual RenderPtr<RenderElement> createInputRenderer(PassRef<RenderStyle>);
virtual void addSearchResult();
virtual void attach();
virtual void detach();
@@ -242,7 +245,6 @@ public:
virtual void stepAttributeChanged();
virtual void altAttributeChanged();
virtual void srcAttributeChanged();
- virtual void maxResultsAttributeChanged();
virtual bool shouldRespectAlignAttribute();
virtual FileList* files();
virtual void setFiles(PassRefPtr<FileList>);
@@ -255,12 +257,15 @@ public:
virtual String displayString() const;
#endif
+ // Should return true if the corresponding renderer for a type can display a suggested value.
+ virtual bool canSetSuggestedValue();
virtual bool shouldSendChangeEventAfterCheckedChanged();
virtual bool canSetValue(const String&);
virtual bool storesValueSeparateFromAttribute();
virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior);
virtual bool shouldResetOnDocumentActivation();
virtual bool shouldRespectListAttribute();
+ virtual bool shouldRespectSpeechAttribute();
virtual bool isEnumeratable();
virtual bool isCheckable();
virtual bool isSteppable() const;
@@ -274,9 +279,9 @@ public:
virtual void disabledAttributeChanged();
virtual void readonlyAttributeChanged();
virtual void requiredAttributeChanged();
- virtual void capsLockStateMayHaveChanged();
- virtual void updateAutoFillButton();
+ virtual void valueAttributeChanged();
virtual String defaultToolTip() const;
+ virtual void updateClearButtonVisibility();
#if ENABLE(DATALIST_ELEMENT)
virtual void listAttributeTargetChanged();
@@ -320,6 +325,7 @@ protected:
HTMLInputElement& element() const { return m_element; }
Chrome* chrome() const;
Decimal parseToNumberOrNaN(const String&) const;
+ void observeFeatureIfVisible(FeatureObserver::Feature) const;
private:
// Helper for stepUp()/stepDown(). Adds step value * count to the current value.
diff --git a/Source/WebCore/html/InputTypeNames.cpp b/Source/WebCore/html/InputTypeNames.cpp
index ac0896a06..8eac7205d 100644
--- a/Source/WebCore/html/InputTypeNames.cpp
+++ b/Source/WebCore/html/InputTypeNames.cpp
@@ -31,139 +31,139 @@ namespace InputTypeNames {
const AtomicString& button()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("button", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("button", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& checkbox()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("checkbox", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("checkbox", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& color()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("color", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("color", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& date()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("date", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("date", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& datetime()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& datetimelocal()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime-local", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime-local", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& email()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("email", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("email", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& file()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("file", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("file", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& hidden()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("hidden", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("hidden", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& image()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("image", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("image", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& month()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("month", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("month", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& number()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("number", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("number", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& password()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("password", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("password", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& radio()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("radio", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("radio", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& range()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("range", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("range", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& reset()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("reset", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("reset", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& search()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("search", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("search", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& submit()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("submit", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("submit", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& telephone()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("tel", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("tel", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& text()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("text", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("text", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& time()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("time", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("time", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& url()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("url", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("url", AtomicString::ConstructFromLiteral));
return name;
}
const AtomicString& week()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, name, ("week", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("week", AtomicString::ConstructFromLiteral));
return name;
}
diff --git a/Source/WebCore/html/LabelableElement.cpp b/Source/WebCore/html/LabelableElement.cpp
index 6abb5b2ba..1d4d7f937 100644
--- a/Source/WebCore/html/LabelableElement.cpp
+++ b/Source/WebCore/html/LabelableElement.cpp
@@ -45,7 +45,7 @@ PassRefPtr<NodeList> LabelableElement::labels()
if (!supportLabels())
return 0;
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<LabelsNodeList>(*this, starAtom);
+ return ensureRareData().ensureNodeLists().addCacheWithAtomicName<LabelsNodeList>(*this, LiveNodeList::LabelsNodeListType, starAtom);
}
} // namespace Webcore
diff --git a/Source/WebCore/html/LabelableElement.h b/Source/WebCore/html/LabelableElement.h
index c2a631a1e..014f11127 100644
--- a/Source/WebCore/html/LabelableElement.h
+++ b/Source/WebCore/html/LabelableElement.h
@@ -50,11 +50,13 @@ private:
virtual bool isLabelable() const override final { return true; }
};
-} // namespace WebCore
+void isLabelableElement(const LabelableElement&); // Catch unnecessary runtime check of type known at compile time.
+inline bool isLabelableElement(const HTMLElement& element) { return element.isLabelable(); }
+inline bool isLabelableElement(const Node& node) { return node.isHTMLElement() && toHTMLElement(node).isLabelable(); }
+template <> inline bool isElementOfType<const LabelableElement>(const Element& element) { return isLabelableElement(element); }
+
+NODE_TYPE_CASTS(LabelableElement)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::LabelableElement)
- static bool isType(const WebCore::HTMLElement& element) { return element.isLabelable(); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::HTMLElement>(node) && isType(downcast<WebCore::HTMLElement>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+} // namespace WebCore
#endif
diff --git a/Source/WebCore/html/LabelsNodeList.cpp b/Source/WebCore/html/LabelsNodeList.cpp
index 11cf07ba9..8a9a348ce 100644
--- a/Source/WebCore/html/LabelsNodeList.cpp
+++ b/Source/WebCore/html/LabelsNodeList.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2007, 2008, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2010 Nokia Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -34,7 +34,7 @@ namespace WebCore {
using namespace HTMLNames;
LabelsNodeList::LabelsNodeList(LabelableElement& forNode)
- : CachedLiveNodeList(forNode, InvalidateOnForAttrChange)
+ : LiveNodeList(forNode, LabelsNodeListType, InvalidateOnForAttrChange, NodeListIsRootedAtDocument)
{
}
@@ -43,9 +43,9 @@ LabelsNodeList::~LabelsNodeList()
ownerNode().nodeLists()->removeCacheWithAtomicName(this, starAtom);
}
-bool LabelsNodeList::elementMatches(Element& testNode) const
+bool LabelsNodeList::nodeMatches(Element* testNode) const
{
- return is<HTMLLabelElement>(testNode) && downcast<HTMLLabelElement>(testNode).control() == &ownerNode();
+ return isHTMLLabelElement(testNode) && toHTMLLabelElement(testNode)->control() == &ownerNode();
}
} // namespace WebCore
diff --git a/Source/WebCore/html/LabelsNodeList.h b/Source/WebCore/html/LabelsNodeList.h
index a119d3b0b..5a1d40040 100644
--- a/Source/WebCore/html/LabelsNodeList.h
+++ b/Source/WebCore/html/LabelsNodeList.h
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2007, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2010 Nokia Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -30,19 +30,19 @@
namespace WebCore {
-class LabelsNodeList final : public CachedLiveNodeList<LabelsNodeList> {
+class LabelsNodeList final : public LiveNodeList {
public:
- static Ref<LabelsNodeList> create(LabelableElement& forNode, const AtomicString&)
+ static PassRef<LabelsNodeList> create(LabelableElement& forNode, Type type, const AtomicString&)
{
+ ASSERT_UNUSED(type, type == LabelsNodeListType);
return adoptRef(*new LabelsNodeList(forNode));
}
~LabelsNodeList();
- virtual bool elementMatches(Element&) const override;
- virtual bool isRootedAtDocument() const override { return true; }
-
-private:
+protected:
explicit LabelsNodeList(LabelableElement& forNode);
+
+ virtual bool nodeMatches(Element*) const override;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/LinkRelAttribute.cpp b/Source/WebCore/html/LinkRelAttribute.cpp
index ae70c6281..712e37069 100644
--- a/Source/WebCore/html/LinkRelAttribute.cpp
+++ b/Source/WebCore/html/LinkRelAttribute.cpp
@@ -32,55 +32,70 @@
#include "config.h"
#include "LinkRelAttribute.h"
-#include <wtf/text/WTFString.h>
-
namespace WebCore {
LinkRelAttribute::LinkRelAttribute()
+ : m_isStyleSheet(false)
+ , m_iconType(InvalidIcon)
+ , m_isAlternate(false)
+ , m_isDNSPrefetch(false)
+#if ENABLE(LINK_PREFETCH)
+ , m_isLinkPrefetch(false)
+ , m_isLinkSubresource(false)
+#endif
{
}
LinkRelAttribute::LinkRelAttribute(const String& rel)
+ : m_isStyleSheet(false)
+ , m_iconType(InvalidIcon)
+ , m_isAlternate(false)
+ , m_isDNSPrefetch(false)
+#if ENABLE(LINK_PREFETCH)
+ , m_isLinkPrefetch(false)
+ , m_isLinkSubresource(false)
+#endif
{
if (equalIgnoringCase(rel, "stylesheet"))
- isStyleSheet = true;
+ m_isStyleSheet = true;
else if (equalIgnoringCase(rel, "icon") || equalIgnoringCase(rel, "shortcut icon"))
- iconType = Favicon;
+ m_iconType = Favicon;
#if ENABLE(TOUCH_ICON_LOADING)
else if (equalIgnoringCase(rel, "apple-touch-icon"))
- iconType = TouchIcon;
+ m_iconType = TouchIcon;
else if (equalIgnoringCase(rel, "apple-touch-icon-precomposed"))
- iconType = TouchPrecomposedIcon;
+ m_iconType = TouchPrecomposedIcon;
#endif
else if (equalIgnoringCase(rel, "dns-prefetch"))
- isDNSPrefetch = true;
+ m_isDNSPrefetch = true;
else if (equalIgnoringCase(rel, "alternate stylesheet") || equalIgnoringCase(rel, "stylesheet alternate")) {
- isStyleSheet = true;
- isAlternate = true;
+ m_isStyleSheet = true;
+ m_isAlternate = true;
} else {
// Tokenize the rel attribute and set bits based on specific keywords that we find.
String relCopy = rel;
relCopy.replace('\n', ' ');
Vector<String> list;
relCopy.split(' ', list);
- for (auto& word : list) {
- if (equalIgnoringCase(word, "stylesheet"))
- isStyleSheet = true;
- else if (equalIgnoringCase(word, "alternate"))
- isAlternate = true;
- else if (equalIgnoringCase(word, "icon"))
- iconType = Favicon;
+ Vector<String>::const_iterator end = list.end();
+ for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
+ if (equalIgnoringCase(*it, "stylesheet"))
+ m_isStyleSheet = true;
+ else if (equalIgnoringCase(*it, "alternate"))
+ m_isAlternate = true;
+ else if (equalIgnoringCase(*it, "icon"))
+ m_iconType = Favicon;
#if ENABLE(TOUCH_ICON_LOADING)
- else if (equalIgnoringCase(word, "apple-touch-icon"))
- iconType = TouchIcon;
- else if (equalIgnoringCase(word, "apple-touch-icon-precomposed"))
- iconType = TouchPrecomposedIcon;
+ else if (equalIgnoringCase(*it, "apple-touch-icon"))
+ m_iconType = TouchIcon;
+ else if (equalIgnoringCase(*it, "apple-touch-icon-precomposed"))
+ m_iconType = TouchPrecomposedIcon;
#endif
#if ENABLE(LINK_PREFETCH)
- else if (equalIgnoringCase(word, "prefetch"))
- isLinkPrefetch = true;
- else if (equalIgnoringCase(word, "subresource"))
- isLinkSubresource = true;
+ else if (equalIgnoringCase(*it, "prefetch"))
+ m_isLinkPrefetch = true;
+ else if (equalIgnoringCase(*it, "subresource"))
+ m_isLinkSubresource = true;
#endif
}
}
diff --git a/Source/WebCore/html/LinkRelAttribute.h b/Source/WebCore/html/LinkRelAttribute.h
index 86358142f..fd6fabf31 100644
--- a/Source/WebCore/html/LinkRelAttribute.h
+++ b/Source/WebCore/html/LinkRelAttribute.h
@@ -33,24 +33,25 @@
#define LinkRelAttribute_h
#include "IconURL.h"
-#include <wtf/Forward.h>
namespace WebCore {
struct LinkRelAttribute {
- bool isStyleSheet { false };
- IconType iconType { InvalidIcon };
- bool isAlternate { false };
- bool isDNSPrefetch { false };
+public:
+ bool m_isStyleSheet;
+ IconType m_iconType;
+ bool m_isAlternate;
+ bool m_isDNSPrefetch;
#if ENABLE(LINK_PREFETCH)
- bool isLinkPrefetch { false };
- bool isLinkSubresource { false };
+ bool m_isLinkPrefetch;
+ bool m_isLinkSubresource;
#endif
LinkRelAttribute();
explicit LinkRelAttribute(const String&);
};
-
+
}
#endif
+
diff --git a/Source/WebCore/html/MediaController.cpp b/Source/WebCore/html/MediaController.cpp
index dcb3249f0..eb7498c5e 100644
--- a/Source/WebCore/html/MediaController.cpp
+++ b/Source/WebCore/html/MediaController.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -37,9 +37,9 @@
using namespace WebCore;
-Ref<MediaController> MediaController::create(ScriptExecutionContext& context)
+PassRefPtr<MediaController> MediaController::create(ScriptExecutionContext& context)
{
- return adoptRef(*new MediaController(context));
+ return adoptRef(new MediaController(context));
}
MediaController::MediaController(ScriptExecutionContext& context)
@@ -50,12 +50,12 @@ MediaController::MediaController(ScriptExecutionContext& context)
, m_muted(false)
, m_readyState(HAVE_NOTHING)
, m_playbackState(WAITING)
- , m_asyncEventTimer(*this, &MediaController::asyncEventTimerFired)
- , m_clearPositionTimer(*this, &MediaController::clearPositionTimerFired)
+ , m_asyncEventTimer(this, &MediaController::asyncEventTimerFired)
+ , m_clearPositionTimer(this, &MediaController::clearPositionTimerFired)
, m_closedCaptionsVisible(false)
, m_clock(Clock::create())
, m_scriptExecutionContext(context)
- , m_timeupdateTimer(*this, &MediaController::scheduleTimeupdateEvent)
+ , m_timeupdateTimer(this, &MediaController::timeupdateTimerFired)
, m_previousTimeupdateTime(0)
{
}
@@ -95,7 +95,7 @@ PassRefPtr<TimeRanges> MediaController::buffered() const
// user agent has buffered, at the time the attribute is evaluated.
RefPtr<TimeRanges> bufferedRanges = m_mediaElements.first()->buffered();
for (size_t index = 1; index < m_mediaElements.size(); ++index)
- bufferedRanges->intersectWith(*m_mediaElements[index]->buffered().get());
+ bufferedRanges->intersectWith(m_mediaElements[index]->buffered().get());
return bufferedRanges;
}
@@ -109,7 +109,7 @@ PassRefPtr<TimeRanges> MediaController::seekable() const
// user agent is able to seek to, at the time the attribute is evaluated.
RefPtr<TimeRanges> seekableRanges = m_mediaElements.first()->seekable();
for (size_t index = 1; index < m_mediaElements.size(); ++index)
- seekableRanges->intersectWith(*m_mediaElements[index]->seekable().get());
+ seekableRanges->intersectWith(m_mediaElements[index]->seekable().get());
return seekableRanges;
}
@@ -123,7 +123,7 @@ PassRefPtr<TimeRanges> MediaController::played()
// user agent has so far rendered, at the time the attribute is evaluated.
RefPtr<TimeRanges> playedRanges = m_mediaElements.first()->played();
for (size_t index = 1; index < m_mediaElements.size(); ++index)
- playedRanges->unionWith(*m_mediaElements[index]->played().get());
+ playedRanges->unionWith(m_mediaElements[index]->played().get());
return playedRanges;
}
@@ -171,10 +171,9 @@ void MediaController::setCurrentTime(double time)
// Seek each slaved media element to the new playback position relative to the media element timeline.
for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->seek(MediaTime::createWithDouble(time));
+ m_mediaElements[index]->seek(time);
scheduleTimeupdateEvent();
- m_resetCurrentTimeInNextPlay = false;
}
void MediaController::unpause()
@@ -290,19 +289,19 @@ void MediaController::setMuted(bool flag)
static const AtomicString& playbackStateWaiting()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, waiting, ("waiting", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, waiting, ("waiting", AtomicString::ConstructFromLiteral));
return waiting;
}
static const AtomicString& playbackStatePlaying()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, playing, ("playing", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, playing, ("playing", AtomicString::ConstructFromLiteral));
return playing;
}
static const AtomicString& playbackStateEnded()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, ended, ("ended", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, ended, ("ended", AtomicString::ConstructFromLiteral));
return ended;
}
@@ -446,15 +445,10 @@ void MediaController::updatePlaybackState()
break;
case ENDED:
eventName = eventNames().endedEvent;
- m_resetCurrentTimeInNextPlay = true;
m_clock->stop();
m_timeupdateTimer.stop();
break;
case PLAYING:
- if (m_resetCurrentTimeInNextPlay) {
- m_resetCurrentTimeInNextPlay = false;
- m_clock->setCurrentTime(0);
- }
eventName = eventNames().playingEvent;
m_clock->start();
startTimeupdateTimer();
@@ -484,7 +478,7 @@ void MediaController::bringElementUpToSpeed(HTMLMediaElement* element)
// When the user agent is to bring a media element up to speed with its new media controller,
// it must seek that media element to the MediaController's media controller position relative
// to the media element's timeline.
- element->seekInternal(MediaTime::createWithDouble(currentTime()));
+ element->seek(currentTime());
}
bool MediaController::isBlocked() const
@@ -543,7 +537,7 @@ void MediaController::scheduleEvent(const AtomicString& eventName)
m_asyncEventTimer.startOneShot(0);
}
-void MediaController::asyncEventTimerFired()
+void MediaController::asyncEventTimerFired(Timer<MediaController>&)
{
Vector<RefPtr<Event>> pendingEvents;
@@ -553,7 +547,7 @@ void MediaController::asyncEventTimerFired()
dispatchEvent(pendingEvents[index].release(), IGNORE_EXCEPTION);
}
-void MediaController::clearPositionTimerFired()
+void MediaController::clearPositionTimerFired(Timer<MediaController>&)
{
m_position = MediaPlayer::invalidTime();
}
@@ -617,18 +611,6 @@ void MediaController::endScrubbing()
m_clock->start();
}
-void MediaController::beginScanning(ScanDirection direction)
-{
- for (auto& mediaElement : m_mediaElements)
- mediaElement->beginScanning(direction);
-}
-
-void MediaController::endScanning()
-{
- for (auto& mediaElement : m_mediaElements)
- mediaElement->endScanning();
-}
-
bool MediaController::canPlay() const
{
if (m_paused)
@@ -677,6 +659,11 @@ void MediaController::startTimeupdateTimer()
m_timeupdateTimer.startRepeating(maxTimeupdateEventFrequency);
}
+void MediaController::timeupdateTimerFired(Timer<MediaController>&)
+{
+ scheduleTimeupdateEvent();
+}
+
void MediaController::scheduleTimeupdateEvent()
{
double now = monotonicallyIncreasingTime();
diff --git a/Source/WebCore/html/MediaController.h b/Source/WebCore/html/MediaController.h
index 7533b48c2..1e7bd8a2e 100644
--- a/Source/WebCore/html/MediaController.h
+++ b/Source/WebCore/html/MediaController.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -45,7 +45,7 @@ class ScriptExecutionContext;
class MediaController final : public RefCounted<MediaController>, public MediaControllerInterface, public EventTargetWithInlineData {
public:
- static Ref<MediaController> create(ScriptExecutionContext&);
+ static PassRefPtr<MediaController> create(ScriptExecutionContext&);
virtual ~MediaController();
void addMediaElement(HTMLMediaElement*);
@@ -98,8 +98,6 @@ public:
virtual void beginScrubbing() override;
virtual void endScrubbing() override;
- virtual void beginScanning(ScanDirection) override;
- virtual void endScanning() override;
virtual bool canPlay() const override;
@@ -123,10 +121,11 @@ private:
void updateMediaElements();
void bringElementUpToSpeed(HTMLMediaElement*);
void scheduleEvent(const AtomicString& eventName);
- void asyncEventTimerFired();
- void clearPositionTimerFired();
+ void asyncEventTimerFired(Timer<MediaController>&);
+ void clearPositionTimerFired(Timer<MediaController>&);
bool hasEnded() const;
void scheduleTimeupdateEvent();
+ void timeupdateTimerFired(Timer<MediaController>&);
void startTimeupdateTimer();
// EventTarget
@@ -146,15 +145,14 @@ private:
ReadyState m_readyState;
PlaybackState m_playbackState;
Vector<RefPtr<Event>> m_pendingEvents;
- Timer m_asyncEventTimer;
- mutable Timer m_clearPositionTimer;
+ Timer<MediaController> m_asyncEventTimer;
+ mutable Timer<MediaController> m_clearPositionTimer;
String m_mediaGroup;
bool m_closedCaptionsVisible;
std::unique_ptr<Clock> m_clock;
ScriptExecutionContext& m_scriptExecutionContext;
- Timer m_timeupdateTimer;
+ Timer<MediaController> m_timeupdateTimer;
double m_previousTimeupdateTime;
- bool m_resetCurrentTimeInNextPlay { false };
};
} // namespace WebCore
diff --git a/Source/WebCore/html/MediaController.idl b/Source/WebCore/html/MediaController.idl
index ee0c277af..515c30aca 100644
--- a/Source/WebCore/html/MediaController.idl
+++ b/Source/WebCore/html/MediaController.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -33,8 +33,8 @@
readonly attribute TimeRanges buffered;
readonly attribute TimeRanges seekable;
- readonly attribute unrestricted double duration;
- attribute unrestricted double currentTime;
+ readonly attribute double duration;
+ attribute double currentTime;
readonly attribute boolean paused;
readonly attribute TimeRanges played;
@@ -43,14 +43,18 @@
void pause();
void unpause();
- attribute unrestricted double defaultPlaybackRate;
- attribute unrestricted double playbackRate;
+ attribute double defaultPlaybackRate;
+ attribute double playbackRate;
- [SetterRaisesException] attribute unrestricted double volume;
+ [SetterRaisesException] attribute double volume;
attribute boolean muted;
// EventTarget interface
- void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
- void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
- [RaisesException] boolean dispatchEvent(Event event);
+ void addEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ void removeEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ [RaisesException] boolean dispatchEvent(Event evt);
};
diff --git a/Source/WebCore/html/MediaControllerInterface.h b/Source/WebCore/html/MediaControllerInterface.h
index ee70e2e2e..afbde0aa3 100644
--- a/Source/WebCore/html/MediaControllerInterface.h
+++ b/Source/WebCore/html/MediaControllerInterface.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,7 +28,6 @@
#if ENABLE(VIDEO)
-#include "HTMLMediaElementEnums.h"
#include <wtf/PassRefPtr.h>
namespace WebCore {
@@ -37,7 +36,7 @@ class TimeRanges;
typedef int ExceptionCode;
-class MediaControllerInterface : public HTMLMediaElementEnums {
+class MediaControllerInterface {
public:
virtual ~MediaControllerInterface() { };
@@ -65,8 +64,8 @@ public:
virtual bool muted() const = 0;
virtual void setMuted(bool) = 0;
-
- using HTMLMediaElementEnums::ReadyState;
+
+ enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
virtual ReadyState readyState() const = 0;
// MediaControlElements:
@@ -85,13 +84,6 @@ public:
virtual void beginScrubbing() = 0;
virtual void endScrubbing() = 0;
- enum ScanDirection {
- Backward,
- Forward,
- };
- virtual void beginScanning(ScanDirection) = 0;
- virtual void endScanning() = 0;
-
virtual bool canPlay() const = 0;
virtual bool isLiveStream() const = 0;
diff --git a/Source/WebCore/html/MediaDocument.cpp b/Source/WebCore/html/MediaDocument.cpp
index 2e8103e48..a4ac2d67d 100644
--- a/Source/WebCore/html/MediaDocument.cpp
+++ b/Source/WebCore/html/MediaDocument.cpp
@@ -28,8 +28,6 @@
#if ENABLE(VIDEO)
#include "MediaDocument.h"
-#include "Chrome.h"
-#include "ChromeClient.h"
#include "DocumentLoader.h"
#include "EventNames.h"
#include "ExceptionCodePlaceholder.h"
@@ -54,17 +52,16 @@ using namespace HTMLNames;
// FIXME: Share more code with PluginDocumentParser.
class MediaDocumentParser final : public RawDataDocumentParser {
public:
- static Ref<MediaDocumentParser> create(MediaDocument& document)
+ static PassRefPtr<MediaDocumentParser> create(MediaDocument& document)
{
- return adoptRef(*new MediaDocumentParser(document));
+ return adoptRef(new MediaDocumentParser(document));
}
private:
- MediaDocumentParser(MediaDocument& document)
+ MediaDocumentParser(Document& document)
: RawDataDocumentParser(document)
, m_mediaElement(0)
{
- m_outgoingReferrer = document.outgoingReferrer();
}
virtual void appendBytes(DocumentWriter&, const char*, size_t) override;
@@ -72,7 +69,6 @@ private:
void createDocumentStructure();
HTMLMediaElement* m_mediaElement;
- String m_outgoingReferrer;
};
void MediaDocumentParser::createDocumentStructure()
@@ -80,41 +76,24 @@ void MediaDocumentParser::createDocumentStructure()
RefPtr<Element> rootElement = document()->createElement(htmlTag, false);
document()->appendChild(rootElement, IGNORE_EXCEPTION);
document()->setCSSTarget(rootElement.get());
- downcast<HTMLHtmlElement>(*rootElement).insertedByParser();
+ toHTMLHtmlElement(rootElement.get())->insertedByParser();
if (document()->frame())
document()->frame()->injectUserScripts(InjectAtDocumentStart);
-#if PLATFORM(IOS)
- RefPtr<Element> headElement = document()->createElement(headTag, false);
- rootElement->appendChild(headElement, IGNORE_EXCEPTION);
-
- RefPtr<Element> metaElement = document()->createElement(metaTag, false);
- metaElement->setAttribute(nameAttr, "viewport");
- metaElement->setAttribute(contentAttr, "width=device-width,initial-scale=1,user-scalable=no");
- headElement->appendChild(metaElement, IGNORE_EXCEPTION);
-#endif
-
RefPtr<Element> body = document()->createElement(bodyTag, false);
rootElement->appendChild(body, IGNORE_EXCEPTION);
RefPtr<Element> mediaElement = document()->createElement(videoTag, false);
- m_mediaElement = downcast<HTMLVideoElement>(mediaElement.get());
- m_mediaElement->setAttribute(controlsAttr, emptyAtom);
- m_mediaElement->setAttribute(autoplayAttr, emptyAtom);
+ m_mediaElement = toHTMLVideoElement(mediaElement.get());
+ m_mediaElement->setAttribute(controlsAttr, "");
+ m_mediaElement->setAttribute(autoplayAttr, "");
m_mediaElement->setAttribute(nameAttr, "media");
- StringBuilder elementStyle;
- elementStyle.appendLiteral("max-width: 100%; max-height: 100%;");
-#if PLATFORM(IOS)
- elementStyle.appendLiteral("width: 100%; height: 100%;");
-#endif
- m_mediaElement->setAttribute(styleAttr, elementStyle.toString());
-
RefPtr<Element> sourceElement = document()->createElement(sourceTag, false);
- HTMLSourceElement& source = downcast<HTMLSourceElement>(*sourceElement);
+ HTMLSourceElement& source = toHTMLSourceElement(*sourceElement);
source.setSrc(document()->url());
if (DocumentLoader* loader = document()->loader())
@@ -128,7 +107,6 @@ void MediaDocumentParser::createDocumentStructure()
return;
frame->loader().activeDocumentLoader()->setMainResourceDataBufferingPolicy(DoNotBufferData);
- frame->loader().setOutgoingReferrer(frame->document()->completeURL(m_outgoingReferrer));
}
void MediaDocumentParser::appendBytes(DocumentWriter&, const char*, size_t)
@@ -142,12 +120,10 @@ void MediaDocumentParser::appendBytes(DocumentWriter&, const char*, size_t)
MediaDocument::MediaDocument(Frame* frame, const URL& url)
: HTMLDocument(frame, url, MediaDocumentClass)
- , m_replaceMediaElementTimer(*this, &MediaDocument::replaceMediaElementTimerFired)
+ , m_replaceMediaElementTimer(this, &MediaDocument::replaceMediaElementTimerFired)
{
- setCompatibilityMode(DocumentCompatibilityMode::QuirksMode);
+ setCompatibilityMode(QuirksMode);
lockCompatibilityMode();
- if (frame)
- m_outgoingReferrer = frame->loader().outgoingReferrer();
}
MediaDocument::~MediaDocument()
@@ -155,30 +131,30 @@ MediaDocument::~MediaDocument()
ASSERT(!m_replaceMediaElementTimer.isActive());
}
-Ref<DocumentParser> MediaDocument::createParser()
+PassRefPtr<DocumentParser> MediaDocument::createParser()
{
return MediaDocumentParser::create(*this);
}
static inline HTMLVideoElement* descendentVideoElement(ContainerNode& node)
{
- if (is<HTMLVideoElement>(node))
- return downcast<HTMLVideoElement>(&node);
+ if (isHTMLVideoElement(node))
+ return toHTMLVideoElement(&node);
RefPtr<NodeList> nodeList = node.getElementsByTagNameNS(videoTag.namespaceURI(), videoTag.localName());
- if (nodeList->length() > 0)
- return downcast<HTMLVideoElement>(nodeList->item(0));
+ if (nodeList.get()->length() > 0)
+ return toHTMLVideoElement(nodeList.get()->item(0));
- return nullptr;
+ return 0;
}
static inline HTMLVideoElement* ancestorVideoElement(Node* node)
{
- while (node && !is<HTMLVideoElement>(*node))
+ while (node && !node->hasTagName(videoTag))
node = node->parentOrShadowHostNode();
- return downcast<HTMLVideoElement>(node);
+ return toHTMLVideoElement(node);
}
void MediaDocument::defaultEventHandler(Event* event)
@@ -203,22 +179,22 @@ void MediaDocument::defaultEventHandler(Event* event)
}
}
- if (!is<ContainerNode>(*targetNode))
+ if (!targetNode->isContainerNode())
return;
- ContainerNode& targetContainer = downcast<ContainerNode>(*targetNode);
- if (event->type() == eventNames().keydownEvent && is<KeyboardEvent>(*event)) {
+ ContainerNode& targetContainer = toContainerNode(*targetNode);
+ if (event->type() == eventNames().keydownEvent && event->isKeyboardEvent()) {
HTMLVideoElement* video = descendentVideoElement(targetContainer);
if (!video)
return;
- KeyboardEvent& keyboardEvent = downcast<KeyboardEvent>(*event);
- if (keyboardEvent.keyIdentifier() == "U+0020") { // space
+ KeyboardEvent* keyboardEvent = static_cast<KeyboardEvent*>(event);
+ if (keyboardEvent->keyIdentifier() == "U+0020") { // space
if (video->paused()) {
if (video->canPlay())
video->play();
} else
video->pause();
- keyboardEvent.setDefaultHandled();
+ event->setDefaultHandled();
}
}
}
@@ -233,9 +209,9 @@ void MediaDocument::mediaElementSawUnsupportedTracks()
m_replaceMediaElementTimer.startOneShot(0);
}
-void MediaDocument::replaceMediaElementTimerFired()
+void MediaDocument::replaceMediaElementTimerFired(Timer<MediaDocument>&)
{
- auto* htmlBody = bodyOrFrameset();
+ HTMLElement* htmlBody = body();
if (!htmlBody)
return;
@@ -245,33 +221,21 @@ void MediaDocument::replaceMediaElementTimerFired()
if (HTMLVideoElement* videoElement = descendentVideoElement(*htmlBody)) {
RefPtr<Element> element = Document::createElement(embedTag, false);
- HTMLEmbedElement& embedElement = downcast<HTMLEmbedElement>(*element);
+ HTMLEmbedElement* embedElement = toHTMLEmbedElement(element.get());
- embedElement.setAttribute(widthAttr, "100%");
- embedElement.setAttribute(heightAttr, "100%");
- embedElement.setAttribute(nameAttr, "plugin");
- embedElement.setAttribute(srcAttr, url().string());
+ embedElement->setAttribute(widthAttr, "100%");
+ embedElement->setAttribute(heightAttr, "100%");
+ embedElement->setAttribute(nameAttr, "plugin");
+ embedElement->setAttribute(srcAttr, url().string());
DocumentLoader* documentLoader = loader();
ASSERT(documentLoader);
if (documentLoader)
- embedElement.setAttribute(typeAttr, documentLoader->writer().mimeType());
+ embedElement->setAttribute(typeAttr, documentLoader->writer().mimeType());
- videoElement->parentNode()->replaceChild(&embedElement, videoElement, IGNORE_EXCEPTION);
+ videoElement->parentNode()->replaceChild(embedElement, videoElement, IGNORE_EXCEPTION);
}
}
-void MediaDocument::mediaElementNaturalSizeChanged(const IntSize& newSize)
-{
- if (ownerElement())
- return;
-
- if (newSize.isZero())
- return;
-
- if (page())
- page()->chrome().client().mediaDocumentNaturalSizeChanged(newSize);
-}
-
}
#endif
diff --git a/Source/WebCore/html/MediaDocument.h b/Source/WebCore/html/MediaDocument.h
index ba691873a..3e3474719 100644
--- a/Source/WebCore/html/MediaDocument.h
+++ b/Source/WebCore/html/MediaDocument.h
@@ -34,35 +34,32 @@ namespace WebCore {
class MediaDocument final : public HTMLDocument {
public:
- static Ref<MediaDocument> create(Frame* frame, const URL& url)
+ static PassRefPtr<MediaDocument> create(Frame* frame, const URL& url)
{
- return adoptRef(*new MediaDocument(frame, url));
+ return adoptRef(new MediaDocument(frame, url));
}
virtual ~MediaDocument();
void mediaElementSawUnsupportedTracks();
- void mediaElementNaturalSizeChanged(const IntSize&);
- String outgoingReferrer() const { return m_outgoingReferrer; }
private:
MediaDocument(Frame*, const URL&);
- virtual Ref<DocumentParser> createParser() override;
+ virtual PassRefPtr<DocumentParser> createParser() override;
virtual void defaultEventHandler(Event*) override;
- void replaceMediaElementTimerFired();
+ void replaceMediaElementTimerFired(Timer<MediaDocument>&);
- Timer m_replaceMediaElementTimer;
- String m_outgoingReferrer;
+ Timer<MediaDocument> m_replaceMediaElementTimer;
};
-} // namespace WebCore
+inline bool isMediaDocument(const Document& document) { return document.isMediaDocument(); }
+void isMediaDocument(const MediaDocument&); // Catch unnecessary runtime check of type known at compile time.
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::MediaDocument)
- static bool isType(const WebCore::Document& document) { return document.isMediaDocument(); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::Document>(node) && isType(downcast<WebCore::Document>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+DOCUMENT_TYPE_CASTS(MediaDocument)
+
+}
#endif
#endif
diff --git a/Source/WebCore/html/MediaElementSession.cpp b/Source/WebCore/html/MediaElementSession.cpp
deleted file mode 100644
index bd2178b95..000000000
--- a/Source/WebCore/html/MediaElementSession.cpp
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(VIDEO)
-
-#include "MediaElementSession.h"
-
-#include "Chrome.h"
-#include "ChromeClient.h"
-#include "Document.h"
-#include "Frame.h"
-#include "FrameView.h"
-#include "HTMLMediaElement.h"
-#include "HTMLNames.h"
-#include "HTMLVideoElement.h"
-#include "Logging.h"
-#include "Page.h"
-#include "PlatformMediaSessionManager.h"
-#include "ScriptController.h"
-#include "SourceBuffer.h"
-
-#if PLATFORM(IOS)
-#include "AudioSession.h"
-#include "RuntimeApplicationChecksIOS.h"
-#endif
-
-namespace WebCore {
-
-#if !LOG_DISABLED
-static String restrictionName(MediaElementSession::BehaviorRestrictions restriction)
-{
- StringBuilder restrictionBuilder;
-#define CASE(restrictionType) \
- if (restriction & MediaElementSession::restrictionType) { \
- if (!restrictionBuilder.isEmpty()) \
- restrictionBuilder.append(", "); \
- restrictionBuilder.append(#restrictionType); \
- } \
-
- CASE(NoRestrictions);
- CASE(RequireUserGestureForLoad);
- CASE(RequireUserGestureForRateChange);
- CASE(RequireUserGestureForAudioRateChange);
- CASE(RequireUserGestureForFullscreen);
- CASE(RequirePageConsentToLoadMedia);
- CASE(RequirePageConsentToResumeMedia);
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- CASE(RequireUserGestureToShowPlaybackTargetPicker);
- CASE(WirelessVideoPlaybackDisabled);
-#endif
- CASE(RequireUserGestureForAudioRateChange);
-
- return restrictionBuilder.toString();
-}
-#endif
-
-static bool pageExplicitlyAllowsElementToAutoplayInline(const HTMLMediaElement& element)
-{
- Document& document = element.document();
- Page* page = document.page();
- return document.isMediaDocument() && !document.ownerElement() && page && page->allowsMediaDocumentInlinePlayback();
-}
-
-MediaElementSession::MediaElementSession(PlatformMediaSessionClient& client)
- : PlatformMediaSession(client)
- , m_restrictions(NoRestrictions)
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- , m_targetAvailabilityChangedTimer(*this, &MediaElementSession::targetAvailabilityChangedTimerFired)
-#endif
-{
-}
-
-void MediaElementSession::registerWithDocument(Document& document)
-{
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- document.addPlaybackTargetPickerClient(*this);
-#else
- UNUSED_PARAM(document);
-#endif
-}
-
-void MediaElementSession::unregisterWithDocument(Document& document)
-{
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- document.removePlaybackTargetPickerClient(*this);
-#else
- UNUSED_PARAM(document);
-#endif
-}
-
-void MediaElementSession::addBehaviorRestriction(BehaviorRestrictions restriction)
-{
- LOG(Media, "MediaElementSession::addBehaviorRestriction - adding %s", restrictionName(restriction).utf8().data());
- m_restrictions |= restriction;
-}
-
-void MediaElementSession::removeBehaviorRestriction(BehaviorRestrictions restriction)
-{
- LOG(Media, "MediaElementSession::removeBehaviorRestriction - removing %s", restrictionName(restriction).utf8().data());
- m_restrictions &= ~restriction;
-}
-
-bool MediaElementSession::playbackPermitted(const HTMLMediaElement& element) const
-{
- if (pageExplicitlyAllowsElementToAutoplayInline(element))
- return true;
-
- if (m_restrictions & RequireUserGestureForRateChange && !ScriptController::processingUserGesture()) {
- LOG(Media, "MediaElementSession::playbackPermitted - returning FALSE");
- return false;
- }
-
- if (m_restrictions & RequireUserGestureForAudioRateChange && element.hasAudio() && !ScriptController::processingUserGesture()) {
- LOG(Media, "MediaElementSession::playbackPermitted - returning FALSE");
- return false;
- }
-
- return true;
-}
-
-bool MediaElementSession::dataLoadingPermitted(const HTMLMediaElement&) const
-{
- if (m_restrictions & RequireUserGestureForLoad && !ScriptController::processingUserGesture()) {
- LOG(Media, "MediaElementSession::dataLoadingPermitted - returning FALSE");
- return false;
- }
-
- return true;
-}
-
-bool MediaElementSession::fullscreenPermitted(const HTMLMediaElement&) const
-{
- if (m_restrictions & RequireUserGestureForFullscreen && !ScriptController::processingUserGesture()) {
- LOG(Media, "MediaElementSession::fullscreenPermitted - returning FALSE");
- return false;
- }
-
- return true;
-}
-
-bool MediaElementSession::pageAllowsDataLoading(const HTMLMediaElement& element) const
-{
- Page* page = element.document().page();
- if (m_restrictions & RequirePageConsentToLoadMedia && page && !page->canStartMedia()) {
- LOG(Media, "MediaElementSession::pageAllowsDataLoading - returning FALSE");
- return false;
- }
-
- return true;
-}
-
-bool MediaElementSession::pageAllowsPlaybackAfterResuming(const HTMLMediaElement& element) const
-{
- Page* page = element.document().page();
- if (m_restrictions & RequirePageConsentToResumeMedia && page && !page->canStartMedia()) {
- LOG(Media, "MediaElementSession::pageAllowsPlaybackAfterResuming - returning FALSE");
- return false;
- }
-
- return true;
-}
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-void MediaElementSession::showPlaybackTargetPicker(const HTMLMediaElement& element)
-{
- LOG(Media, "MediaElementSession::showPlaybackTargetPicker");
-
- if (m_restrictions & RequireUserGestureToShowPlaybackTargetPicker && !ScriptController::processingUserGesture()) {
- LOG(Media, "MediaElementSession::showPlaybackTargetPicker - returning early because of permissions");
- return;
- }
-
- if (!element.document().page()) {
- LOG(Media, "MediaElementSession::showingPlaybackTargetPickerPermitted - returning early because page is NULL");
- return;
- }
-
-#if !PLATFORM(IOS)
- if (element.readyState() < HTMLMediaElementEnums::HAVE_METADATA) {
- LOG(Media, "MediaElementSession::showPlaybackTargetPicker - returning early because element is not playable");
- return;
- }
-#endif
-
- element.document().showPlaybackTargetPicker(*this, is<HTMLVideoElement>(element));
-}
-
-bool MediaElementSession::hasWirelessPlaybackTargets(const HTMLMediaElement&) const
-{
-#if PLATFORM(IOS)
- // FIXME: consolidate Mac and iOS implementations
- m_hasPlaybackTargets = PlatformMediaSessionManager::sharedManager().hasWirelessTargetsAvailable();
-#endif
-
- LOG(Media, "MediaElementSession::hasWirelessPlaybackTargets - returning %s", m_hasPlaybackTargets ? "TRUE" : "FALSE");
-
- return m_hasPlaybackTargets;
-}
-
-bool MediaElementSession::wirelessVideoPlaybackDisabled(const HTMLMediaElement& element) const
-{
- Settings* settings = element.document().settings();
- if (!settings || !settings->allowsAirPlayForMediaPlayback()) {
- LOG(Media, "MediaElementSession::wirelessVideoPlaybackDisabled - returning TRUE because of settings");
- return true;
- }
-
- if (element.fastHasAttribute(HTMLNames::webkitwirelessvideoplaybackdisabledAttr)) {
- LOG(Media, "MediaElementSession::wirelessVideoPlaybackDisabled - returning TRUE because of attribute");
- return true;
- }
-
-#if PLATFORM(IOS)
- String legacyAirplayAttributeValue = element.fastGetAttribute(HTMLNames::webkitairplayAttr);
- if (equalIgnoringCase(legacyAirplayAttributeValue, "deny")) {
- LOG(Media, "MediaElementSession::wirelessVideoPlaybackDisabled - returning TRUE because of legacy attribute");
- return true;
- }
- if (equalIgnoringCase(legacyAirplayAttributeValue, "allow")) {
- LOG(Media, "MediaElementSession::wirelessVideoPlaybackDisabled - returning FALSE because of legacy attribute");
- return false;
- }
-#endif
-
- MediaPlayer* player = element.player();
- if (!player)
- return true;
-
- bool disabled = player->wirelessVideoPlaybackDisabled();
- LOG(Media, "MediaElementSession::wirelessVideoPlaybackDisabled - returning %s because media engine says so", disabled ? "TRUE" : "FALSE");
-
- return disabled;
-}
-
-void MediaElementSession::setWirelessVideoPlaybackDisabled(const HTMLMediaElement& element, bool disabled)
-{
- if (disabled)
- addBehaviorRestriction(WirelessVideoPlaybackDisabled);
- else
- removeBehaviorRestriction(WirelessVideoPlaybackDisabled);
-
- MediaPlayer* player = element.player();
- if (!player)
- return;
-
- LOG(Media, "MediaElementSession::setWirelessVideoPlaybackDisabled - disabled %s", disabled ? "TRUE" : "FALSE");
- player->setWirelessVideoPlaybackDisabled(disabled);
-}
-
-void MediaElementSession::setHasPlaybackTargetAvailabilityListeners(const HTMLMediaElement& element, bool hasListeners)
-{
- LOG(Media, "MediaElementSession::setHasPlaybackTargetAvailabilityListeners - hasListeners %s", hasListeners ? "TRUE" : "FALSE");
-
-#if PLATFORM(IOS)
- UNUSED_PARAM(element);
- m_hasPlaybackTargetAvailabilityListeners = hasListeners;
- PlatformMediaSessionManager::sharedManager().configureWireLessTargetMonitoring();
-#else
- UNUSED_PARAM(hasListeners);
- element.document().playbackTargetPickerClientStateDidChange(*this, element.mediaState());
-#endif
-}
-
-void MediaElementSession::setPlaybackTarget(Ref<MediaPlaybackTarget>&& device)
-{
- m_playbackTarget = WTF::move(device);
- client().setWirelessPlaybackTarget(*m_playbackTarget.copyRef());
-}
-
-void MediaElementSession::targetAvailabilityChangedTimerFired()
-{
- client().wirelessRoutesAvailableDidChange();
-}
-
-void MediaElementSession::externalOutputDeviceAvailableDidChange(bool hasTargets)
-{
- if (m_hasPlaybackTargets == hasTargets)
- return;
-
- LOG(Media, "MediaElementSession::externalOutputDeviceAvailableDidChange(%p) - hasTargets %s", this, hasTargets ? "TRUE" : "FALSE");
-
- m_hasPlaybackTargets = hasTargets;
- m_targetAvailabilityChangedTimer.startOneShot(0);
-}
-
-bool MediaElementSession::canPlayToWirelessPlaybackTarget() const
-{
- if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
- return false;
-
- return client().canPlayToWirelessPlaybackTarget();
-}
-
-bool MediaElementSession::isPlayingToWirelessPlaybackTarget() const
-{
- if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
- return false;
-
- return client().isPlayingToWirelessPlaybackTarget();
-}
-
-void MediaElementSession::setShouldPlayToPlaybackTarget(bool shouldPlay)
-{
- LOG(Media, "MediaElementSession::setShouldPlayToPlaybackTarget - shouldPlay %s", shouldPlay ? "TRUE" : "FALSE");
- m_shouldPlayToPlaybackTarget = shouldPlay;
- client().setShouldPlayToPlaybackTarget(shouldPlay);
-}
-
-void MediaElementSession::mediaStateDidChange(const HTMLMediaElement& element, MediaProducer::MediaStateFlags state)
-{
- element.document().playbackTargetPickerClientStateDidChange(*this, state);
-}
-#endif
-
-MediaPlayer::Preload MediaElementSession::effectivePreloadForElement(const HTMLMediaElement& element) const
-{
- PlatformMediaSessionManager::SessionRestrictions restrictions = PlatformMediaSessionManager::sharedManager().restrictions(mediaType());
- MediaPlayer::Preload preload = element.preloadValue();
-
- if (pageExplicitlyAllowsElementToAutoplayInline(element))
- return preload;
-
- if ((restrictions & PlatformMediaSessionManager::MetadataPreloadingNotPermitted) == PlatformMediaSessionManager::MetadataPreloadingNotPermitted)
- return MediaPlayer::None;
-
- if ((restrictions & PlatformMediaSessionManager::AutoPreloadingNotPermitted) == PlatformMediaSessionManager::AutoPreloadingNotPermitted) {
- if (preload > MediaPlayer::MetaData)
- return MediaPlayer::MetaData;
- }
-
- return preload;
-}
-
-bool MediaElementSession::requiresFullscreenForVideoPlayback(const HTMLMediaElement& element) const
-{
- if (pageExplicitlyAllowsElementToAutoplayInline(element))
- return false;
-
- if (!PlatformMediaSessionManager::sharedManager().sessionRestrictsInlineVideoPlayback(*this))
- return false;
-
- Settings* settings = element.document().settings();
- if (!settings || !settings->allowsInlineMediaPlayback())
- return true;
-
- if (element.fastHasAttribute(HTMLNames::webkit_playsinlineAttr))
- return false;
-
-#if PLATFORM(IOS)
- if (applicationIsDumpRenderTree())
- return false;
-#endif
-
- return true;
-}
-
-bool MediaElementSession::allowsAutomaticMediaDataLoading(const HTMLMediaElement& element) const
-{
- if (pageExplicitlyAllowsElementToAutoplayInline(element))
- return true;
-
- Settings* settings = element.document().settings();
- if (settings && settings->mediaDataLoadsAutomatically())
- return true;
-
- return false;
-}
-
-void MediaElementSession::mediaEngineUpdated(const HTMLMediaElement& element)
-{
- LOG(Media, "MediaElementSession::mediaEngineUpdated");
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- if (m_restrictions & WirelessVideoPlaybackDisabled)
- setWirelessVideoPlaybackDisabled(element, true);
- if (m_playbackTarget)
- client().setWirelessPlaybackTarget(*m_playbackTarget.copyRef());
- if (m_shouldPlayToPlaybackTarget)
- client().setShouldPlayToPlaybackTarget(true);
-#else
- UNUSED_PARAM(element);
-#endif
-
-}
-
-bool MediaElementSession::allowsPictureInPicture(const HTMLMediaElement& element) const
-{
- Settings* settings = element.document().settings();
- return settings && settings->allowsPictureInPictureMediaPlayback() && !element.webkitCurrentPlaybackTargetIsWireless();
-}
-
-#if PLATFORM(IOS)
-bool MediaElementSession::requiresPlaybackTargetRouteMonitoring() const
-{
- return m_hasPlaybackTargetAvailabilityListeners && !client().elementIsHidden();
-}
-#endif
-
-#if ENABLE(MEDIA_SOURCE)
-const unsigned fiveMinutesOf1080PVideo = 290 * 1024 * 1024; // 290 MB is approximately 5 minutes of 8Mbps (1080p) content.
-const unsigned fiveMinutesStereoAudio = 14 * 1024 * 1024; // 14 MB is approximately 5 minutes of 384kbps content.
-
-size_t MediaElementSession::maximumMediaSourceBufferSize(const SourceBuffer& buffer) const
-{
- // A good quality 1080p video uses 8,000 kbps and stereo audio uses 384 kbps, so assume 95% for video and 5% for audio.
- const float bufferBudgetPercentageForVideo = .95;
- const float bufferBudgetPercentageForAudio = .05;
-
- size_t maximum;
- Settings* settings = buffer.document().settings();
- if (settings)
- maximum = settings->maximumSourceBufferSize();
- else
- maximum = fiveMinutesOf1080PVideo + fiveMinutesStereoAudio;
-
- // Allow a SourceBuffer to buffer as though it is audio-only even if it doesn't have any active tracks (yet).
- size_t bufferSize = static_cast<size_t>(maximum * bufferBudgetPercentageForAudio);
- if (buffer.hasVideo())
- bufferSize += static_cast<size_t>(maximum * bufferBudgetPercentageForVideo);
-
- // FIXME: we might want to modify this algorithm to:
- // - decrease the maximum size for background tabs
- // - decrease the maximum size allowed for inactive elements when a process has more than one
- // element, eg. so a page with many elements which are played one at a time doesn't keep
- // everything buffered after an element has finished playing.
-
- return bufferSize;
-}
-#endif
-
-}
-
-#endif // ENABLE(VIDEO)
diff --git a/Source/WebCore/html/MediaElementSession.h b/Source/WebCore/html/MediaElementSession.h
deleted file mode 100644
index 8f69724b7..000000000
--- a/Source/WebCore/html/MediaElementSession.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaElementSession_h
-#define MediaElementSession_h
-
-#if ENABLE(VIDEO)
-
-#include "MediaPlayer.h"
-#include "PlatformMediaSession.h"
-#include "Timer.h"
-
-namespace WebCore {
-
-class Document;
-class HTMLMediaElement;
-class SourceBuffer;
-
-class MediaElementSession final : public PlatformMediaSession {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit MediaElementSession(PlatformMediaSessionClient&);
- virtual ~MediaElementSession() { }
-
- void registerWithDocument(Document&);
- void unregisterWithDocument(Document&);
-
- bool playbackPermitted(const HTMLMediaElement&) const;
- bool dataLoadingPermitted(const HTMLMediaElement&) const;
- bool fullscreenPermitted(const HTMLMediaElement&) const;
- bool pageAllowsDataLoading(const HTMLMediaElement&) const;
- bool pageAllowsPlaybackAfterResuming(const HTMLMediaElement&) const;
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- void showPlaybackTargetPicker(const HTMLMediaElement&);
- bool hasWirelessPlaybackTargets(const HTMLMediaElement&) const;
-
- bool wirelessVideoPlaybackDisabled(const HTMLMediaElement&) const;
- void setWirelessVideoPlaybackDisabled(const HTMLMediaElement&, bool);
-
- void setHasPlaybackTargetAvailabilityListeners(const HTMLMediaElement&, bool);
-
- virtual bool canPlayToWirelessPlaybackTarget() const override;
- virtual bool isPlayingToWirelessPlaybackTarget() const override;
-
- void mediaStateDidChange(const HTMLMediaElement&, MediaProducer::MediaStateFlags);
-#endif
-
- bool requiresFullscreenForVideoPlayback(const HTMLMediaElement&) const;
- WEBCORE_EXPORT bool allowsPictureInPicture(const HTMLMediaElement&) const;
- MediaPlayer::Preload effectivePreloadForElement(const HTMLMediaElement&) const;
- bool allowsAutomaticMediaDataLoading(const HTMLMediaElement&) const;
-
- void mediaEngineUpdated(const HTMLMediaElement&);
-
- // Restrictions to modify default behaviors.
- enum BehaviorRestrictionFlags {
- NoRestrictions = 0,
- RequireUserGestureForLoad = 1 << 0,
- RequireUserGestureForRateChange = 1 << 1,
- RequireUserGestureForFullscreen = 1 << 2,
- RequirePageConsentToLoadMedia = 1 << 3,
- RequirePageConsentToResumeMedia = 1 << 4,
- RequireUserGestureForAudioRateChange = 1 << 5,
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- RequireUserGestureToShowPlaybackTargetPicker = 1 << 6,
- WirelessVideoPlaybackDisabled = 1 << 7,
- RequireUserGestureToAutoplayToExternalDevice = 1 << 8,
-#endif
- };
- typedef unsigned BehaviorRestrictions;
-
- WEBCORE_EXPORT BehaviorRestrictions behaviorRestrictions() const { return m_restrictions; }
- WEBCORE_EXPORT void addBehaviorRestriction(BehaviorRestrictions);
- WEBCORE_EXPORT void removeBehaviorRestriction(BehaviorRestrictions);
- bool hasBehaviorRestriction(BehaviorRestrictions restriction) const { return restriction & m_restrictions; }
-
-#if ENABLE(MEDIA_SOURCE)
- size_t maximumMediaSourceBufferSize(const SourceBuffer&) const;
-#endif
-
-private:
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- void targetAvailabilityChangedTimerFired();
-
- // MediaPlaybackTargetClient
- virtual void setPlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
- virtual void externalOutputDeviceAvailableDidChange(bool) override;
- virtual void setShouldPlayToPlaybackTarget(bool) override;
-#endif
-#if PLATFORM(IOS)
- bool requiresPlaybackTargetRouteMonitoring() const override;
-#endif
-
- BehaviorRestrictions m_restrictions;
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- mutable Timer m_targetAvailabilityChangedTimer;
- RefPtr<MediaPlaybackTarget> m_playbackTarget;
- bool m_shouldPlayToPlaybackTarget { false };
- mutable bool m_hasPlaybackTargets { false };
-#endif
-#if PLATFORM(IOS)
- bool m_hasPlaybackTargetAvailabilityListeners { false };
-#endif
-};
-
-}
-
-#endif // MediaElementSession_h
-
-#endif // ENABLE(VIDEO)
diff --git a/Source/WebCore/html/MediaError.h b/Source/WebCore/html/MediaError.h
index 9544e55e6..b0bf5f765 100644
--- a/Source/WebCore/html/MediaError.h
+++ b/Source/WebCore/html/MediaError.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -45,7 +45,7 @@ public:
#endif
};
- static Ref<MediaError> create(Code code) { return adoptRef(*new MediaError(code)); }
+ static PassRefPtr<MediaError> create(Code code) { return adoptRef(new MediaError(code)); }
Code code() const { return m_code; }
diff --git a/Source/WebCore/html/MediaError.idl b/Source/WebCore/html/MediaError.idl
index 5424b453a..5dfeda07b 100644
--- a/Source/WebCore/html/MediaError.idl
+++ b/Source/WebCore/html/MediaError.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/MediaFragmentURIParser.cpp b/Source/WebCore/html/MediaFragmentURIParser.cpp
index 723b53097..35046f9a2 100644
--- a/Source/WebCore/html/MediaFragmentURIParser.cpp
+++ b/Source/WebCore/html/MediaFragmentURIParser.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -42,7 +42,7 @@ namespace WebCore {
const int secondsPerHour = 3600;
const int secondsPerMinute = 60;
-const unsigned nptIdentifierLength = 4; // "npt:"
+const unsigned nptIdentiferLength = 4; // "npt:"
static String collectDigits(const LChar* input, unsigned length, unsigned& position)
{
@@ -70,27 +70,32 @@ static String collectFraction(const LChar* input, unsigned length, unsigned& pos
return digits.toString();
}
+double MediaFragmentURIParser::invalidTimeValue()
+{
+ return MediaPlayer::invalidTime();
+}
+
MediaFragmentURIParser::MediaFragmentURIParser(const URL& url)
: m_url(url)
, m_timeFormat(None)
- , m_startTime(MediaTime::invalidTime())
- , m_endTime(MediaTime::invalidTime())
+ , m_startTime(MediaPlayer::invalidTime())
+ , m_endTime(MediaPlayer::invalidTime())
{
}
-MediaTime MediaFragmentURIParser::startTime()
+double MediaFragmentURIParser::startTime()
{
if (!m_url.isValid())
- return MediaTime::invalidTime();
+ return MediaPlayer::invalidTime();
if (m_timeFormat == None)
parseTimeFragment();
return m_startTime;
}
-MediaTime MediaFragmentURIParser::endTime()
+double MediaFragmentURIParser::endTime()
{
if (!m_url.isValid())
- return MediaTime::invalidTime();
+ return MediaPlayer::invalidTime();
if (m_timeFormat == None)
parseTimeFragment();
return m_endTime;
@@ -179,8 +184,8 @@ void MediaFragmentURIParser::parseTimeFragment()
// in the same format. The format is specified by name, followed by a colon (:), with npt: being
// the default.
- MediaTime start = MediaTime::invalidTime();
- MediaTime end = MediaTime::invalidTime();
+ double start = MediaPlayer::invalidTime();
+ double end = MediaPlayer::invalidTime();
if (parseNPTFragment(fragment.second.characters8(), fragment.second.length(), start, end)) {
m_startTime = start;
m_endTime = end;
@@ -197,11 +202,11 @@ void MediaFragmentURIParser::parseTimeFragment()
m_fragments.clear();
}
-bool MediaFragmentURIParser::parseNPTFragment(const LChar* timeString, unsigned length, MediaTime& startTime, MediaTime& endTime)
+bool MediaFragmentURIParser::parseNPTFragment(const LChar* timeString, unsigned length, double& startTime, double& endTime)
{
unsigned offset = 0;
- if (length >= nptIdentifierLength && timeString[0] == 'n' && timeString[1] == 'p' && timeString[2] == 't' && timeString[3] == ':')
- offset += nptIdentifierLength;
+ if (length >= nptIdentiferLength && timeString[0] == 'n' && timeString[1] == 'p' && timeString[2] == 't' && timeString[3] == ':')
+ offset += nptIdentiferLength;
if (offset == length)
return false;
@@ -210,7 +215,7 @@ bool MediaFragmentURIParser::parseNPTFragment(const LChar* timeString, unsigned
// If a single number only is given, this corresponds to the begin time except if it is preceded
// by a comma that would in this case indicate the end time.
if (timeString[offset] == ',')
- startTime = MediaTime::zeroTime();
+ startTime = 0;
else {
if (!parseNPTTime(timeString, length, offset, startTime))
return false;
@@ -236,7 +241,7 @@ bool MediaFragmentURIParser::parseNPTFragment(const LChar* timeString, unsigned
return true;
}
-bool MediaFragmentURIParser::parseNPTTime(const LChar* timeString, unsigned length, unsigned& offset, MediaTime& time)
+bool MediaFragmentURIParser::parseNPTTime(const LChar* timeString, unsigned length, unsigned& offset, double& time)
{
enum Mode { minutes, hours };
Mode mode = minutes;
@@ -266,17 +271,17 @@ bool MediaFragmentURIParser::parseNPTTime(const LChar* timeString, unsigned leng
String digits1 = collectDigits(timeString, length, offset);
int value1 = digits1.toInt();
if (offset >= length || timeString[offset] == ',') {
- time = MediaTime::createWithDouble(value1);
+ time = value1;
return true;
}
- MediaTime fraction;
+ double fraction = 0;
if (timeString[offset] == '.') {
if (offset == length)
return true;
String digits = collectFraction(timeString, length, offset);
- fraction = MediaTime::createWithDouble(digits.toDouble());
- time = MediaTime::createWithDouble(value1) + fraction;
+ fraction = digits.toDouble();
+ time = value1 + fraction;
return true;
}
@@ -313,9 +318,9 @@ bool MediaFragmentURIParser::parseNPTTime(const LChar* timeString, unsigned leng
}
if (offset < length && timeString[offset] == '.')
- fraction = MediaTime::createWithDouble(collectFraction(timeString, length, offset).toDouble());
+ fraction = collectFraction(timeString, length, offset).toDouble();
- time = MediaTime::createWithDouble((value1 * secondsPerHour) + (value2 * secondsPerMinute) + value3) + fraction;
+ time = (value1 * secondsPerHour) + (value2 * secondsPerMinute) + value3 + fraction;
return true;
}
diff --git a/Source/WebCore/html/MediaFragmentURIParser.h b/Source/WebCore/html/MediaFragmentURIParser.h
index 06aceb92f..c276b7879 100644
--- a/Source/WebCore/html/MediaFragmentURIParser.h
+++ b/Source/WebCore/html/MediaFragmentURIParser.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -29,7 +29,6 @@
#if ENABLE(VIDEO)
#include "URL.h"
-#include <wtf/MediaTime.h>
#include <wtf/Vector.h>
namespace WebCore {
@@ -41,8 +40,10 @@ public:
MediaFragmentURIParser(const URL&);
- MediaTime startTime();
- MediaTime endTime();
+ double startTime();
+ double endTime();
+
+ static double invalidTimeValue();
private:
@@ -50,13 +51,13 @@ private:
enum TimeFormat { None, Invalid, NormalPlayTime, SMPTETimeCode, WallClockTimeCode };
void parseTimeFragment();
- bool parseNPTFragment(const LChar*, unsigned length, MediaTime& startTime, MediaTime& endTime);
- bool parseNPTTime(const LChar*, unsigned length, unsigned& offset, MediaTime&);
+ bool parseNPTFragment(const LChar*, unsigned length, double& startTime, double& endTime);
+ bool parseNPTTime(const LChar*, unsigned length, unsigned& offset, double& time);
URL m_url;
TimeFormat m_timeFormat;
- MediaTime m_startTime;
- MediaTime m_endTime;
+ double m_startTime;
+ double m_endTime;
Vector<std::pair<String, String>> m_fragments;
};
diff --git a/Source/WebCore/html/MediaKeyError.h b/Source/WebCore/html/MediaKeyError.h
index 115c96146..48eb26dff 100644
--- a/Source/WebCore/html/MediaKeyError.h
+++ b/Source/WebCore/html/MediaKeyError.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -46,7 +46,7 @@ public:
};
typedef unsigned short Code;
- static Ref<MediaKeyError> create(Code code, unsigned long systemCode = 0) { return adoptRef(*new MediaKeyError(code, systemCode)); }
+ static PassRefPtr<MediaKeyError> create(Code code, unsigned long systemCode = 0) { return adoptRef(new MediaKeyError(code, systemCode)); }
Code code() const { return m_code; }
unsigned long systemCode() { return m_systemCode; }
diff --git a/Source/WebCore/html/MediaKeyError.idl b/Source/WebCore/html/MediaKeyError.idl
index f0de57fa1..576164703 100644
--- a/Source/WebCore/html/MediaKeyError.idl
+++ b/Source/WebCore/html/MediaKeyError.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/MediaKeyEvent.cpp b/Source/WebCore/html/MediaKeyEvent.cpp
index 8d3d7c75f..1e8a63dcf 100644
--- a/Source/WebCore/html/MediaKeyEvent.cpp
+++ b/Source/WebCore/html/MediaKeyEvent.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/MediaKeyEvent.h b/Source/WebCore/html/MediaKeyEvent.h
index 774de30da..b9f058277 100644
--- a/Source/WebCore/html/MediaKeyEvent.h
+++ b/Source/WebCore/html/MediaKeyEvent.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -45,18 +45,18 @@ struct MediaKeyEventInit : public EventInit {
unsigned short systemCode;
};
-class MediaKeyEvent final : public Event {
+class MediaKeyEvent : public Event {
public:
virtual ~MediaKeyEvent();
- static Ref<MediaKeyEvent> create()
+ static PassRefPtr<MediaKeyEvent> create()
{
- return adoptRef(*new MediaKeyEvent);
+ return adoptRef(new MediaKeyEvent);
}
- static Ref<MediaKeyEvent> create(const AtomicString& type, const MediaKeyEventInit& initializer)
+ static PassRefPtr<MediaKeyEvent> create(const AtomicString& type, const MediaKeyEventInit& initializer)
{
- return adoptRef(*new MediaKeyEvent(type, initializer));
+ return adoptRef(new MediaKeyEvent(type, initializer));
}
virtual EventInterface eventInterface() const override;
diff --git a/Source/WebCore/html/MediaKeyEvent.idl b/Source/WebCore/html/MediaKeyEvent.idl
index b1e568306..ade288e46 100644
--- a/Source/WebCore/html/MediaKeyEvent.idl
+++ b/Source/WebCore/html/MediaKeyEvent.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/MonthInputType.cpp b/Source/WebCore/html/MonthInputType.cpp
index 472987274..a855ea0f0 100644
--- a/Source/WebCore/html/MonthInputType.cpp
+++ b/Source/WebCore/html/MonthInputType.cpp
@@ -47,6 +47,11 @@ static const int monthDefaultStep = 1;
static const int monthDefaultStepBase = 0;
static const int monthStepScaleFactor = 1;
+void MonthInputType::attach()
+{
+ observeFeatureIfVisible(FeatureObserver::InputTypeMonth);
+}
+
const AtomicString& MonthInputType::formControlType() const
{
return InputTypeNames::month();
@@ -90,7 +95,7 @@ Decimal MonthInputType::defaultValueForStepUp() const
StepRange MonthInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (monthDefaultStep, monthDefaultStepBase, monthStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger));
+ DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (monthDefaultStep, monthDefaultStepBase, monthStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger));
const Decimal stepBase = parseToNumber(element().fastGetAttribute(minAttr), Decimal::fromDouble(monthDefaultStepBase));
const Decimal minimum = parseToNumber(element().fastGetAttribute(minAttr), Decimal::fromDouble(DateComponents::minimumMonth()));
diff --git a/Source/WebCore/html/MonthInputType.h b/Source/WebCore/html/MonthInputType.h
index a4e25acd1..f31253394 100644
--- a/Source/WebCore/html/MonthInputType.h
+++ b/Source/WebCore/html/MonthInputType.h
@@ -36,11 +36,12 @@
namespace WebCore {
-class MonthInputType final : public BaseChooserOnlyDateAndTimeInputType {
+class MonthInputType : public BaseChooserOnlyDateAndTimeInputType {
public:
explicit MonthInputType(HTMLInputElement& element) : BaseChooserOnlyDateAndTimeInputType(element) { }
private:
+ virtual void attach() override;
virtual const AtomicString& formControlType() const override;
virtual DateComponents::Type dateType() const override;
virtual double valueAsDate() const override;
diff --git a/Source/WebCore/html/NumberInputType.cpp b/Source/WebCore/html/NumberInputType.cpp
index fd35bb832..588820809 100644
--- a/Source/WebCore/html/NumberInputType.cpp
+++ b/Source/WebCore/html/NumberInputType.cpp
@@ -92,6 +92,12 @@ static RealNumberRenderSize calculateRenderSize(const Decimal& value)
return RealNumberRenderSize(sizeOfSign + sizeOfZero , numberOfZeroAfterDecimalPoint + sizeOfDigits);
}
+void NumberInputType::attach()
+{
+ TextFieldInputType::attach();
+ observeFeatureIfVisible(FeatureObserver::InputTypeNumber);
+}
+
const AtomicString& NumberInputType::formControlType() const
{
return InputTypeNames::number();
@@ -152,7 +158,7 @@ bool NumberInputType::typeMismatch() const
StepRange NumberInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (numberDefaultStep, numberDefaultStepBase, numberStepScaleFactor));
+ DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (numberDefaultStep, numberDefaultStepBase, numberStepScaleFactor));
const Decimal stepBase = parseToDecimalForNumberType(element().fastGetAttribute(minAttr), numberDefaultStepBase);
// FIXME: We should use numeric_limits<double>::max for number input type.
const Decimal floatMax = Decimal::fromDouble(std::numeric_limits<float>::max());
@@ -273,6 +279,11 @@ String NumberInputType::badInputText() const
return validationMessageBadInputForNumberText();
}
+bool NumberInputType::shouldRespectSpeechAttribute()
+{
+ return true;
+}
+
bool NumberInputType::supportsPlaceholder() const
{
return true;
diff --git a/Source/WebCore/html/NumberInputType.h b/Source/WebCore/html/NumberInputType.h
index 9de9fb5aa..7aba7f9aa 100644
--- a/Source/WebCore/html/NumberInputType.h
+++ b/Source/WebCore/html/NumberInputType.h
@@ -35,11 +35,12 @@
namespace WebCore {
-class NumberInputType final : public TextFieldInputType {
+class NumberInputType : public TextFieldInputType {
public:
explicit NumberInputType(HTMLInputElement& element) : TextFieldInputType(element) { }
private:
+ virtual void attach() override;
virtual const AtomicString& formControlType() const override;
virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior) override;
virtual double valueAsDouble() const override;
@@ -60,6 +61,7 @@ private:
virtual String sanitizeValue(const String&) const override;
virtual bool hasBadInput() const override;
virtual String badInputText() const override;
+ virtual bool shouldRespectSpeechAttribute() override;
virtual bool supportsPlaceholder() const override;
virtual bool isNumberField() const override;
virtual void minOrMaxAttributeChanged() override;
diff --git a/Source/WebCore/html/PasswordInputType.cpp b/Source/WebCore/html/PasswordInputType.cpp
index af2e38cf3..7f7e0f9fc 100644
--- a/Source/WebCore/html/PasswordInputType.cpp
+++ b/Source/WebCore/html/PasswordInputType.cpp
@@ -79,6 +79,11 @@ bool PasswordInputType::shouldRespectListAttribute()
return false;
}
+bool PasswordInputType::shouldRespectSpeechAttribute()
+{
+ return true;
+}
+
bool PasswordInputType::isPasswordField() const
{
return true;
diff --git a/Source/WebCore/html/PasswordInputType.h b/Source/WebCore/html/PasswordInputType.h
index f8046db1d..001fd27c6 100644
--- a/Source/WebCore/html/PasswordInputType.h
+++ b/Source/WebCore/html/PasswordInputType.h
@@ -35,7 +35,7 @@
namespace WebCore {
-class PasswordInputType final : public BaseTextInputType {
+class PasswordInputType : public BaseTextInputType {
public:
explicit PasswordInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
@@ -47,6 +47,7 @@ private:
virtual bool shouldUseInputMethod() const override;
virtual bool shouldResetOnDocumentActivation() override;
virtual bool shouldRespectListAttribute() override;
+ virtual bool shouldRespectSpeechAttribute() override;
virtual bool isPasswordField() const override;
};
diff --git a/Source/WebCore/html/PluginDocument.cpp b/Source/WebCore/html/PluginDocument.cpp
index e9677090f..51ea4674d 100644
--- a/Source/WebCore/html/PluginDocument.cpp
+++ b/Source/WebCore/html/PluginDocument.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
@@ -46,9 +46,9 @@ using namespace HTMLNames;
// FIXME: Share more code with MediaDocumentParser.
class PluginDocumentParser final : public RawDataDocumentParser {
public:
- static Ref<PluginDocumentParser> create(PluginDocument& document)
+ static PassRefPtr<PluginDocumentParser> create(PluginDocument& document)
{
- return adoptRef(*new PluginDocumentParser(document));
+ return adoptRef(new PluginDocumentParser(document));
}
private:
@@ -69,7 +69,7 @@ void PluginDocumentParser::createDocumentStructure()
{
RefPtr<Element> rootElement = document()->createElement(htmlTag, false);
document()->appendChild(rootElement, IGNORE_EXCEPTION);
- downcast<HTMLHtmlElement>(*rootElement).insertedByParser();
+ toHTMLHtmlElement(rootElement.get())->insertedByParser();
if (document()->frame())
document()->frame()->injectUserScripts(InjectAtDocumentStart);
@@ -92,7 +92,7 @@ void PluginDocumentParser::createDocumentStructure()
RefPtr<Element> embedElement = document()->createElement(embedTag, false);
- m_embedElement = downcast<HTMLEmbedElement>(embedElement.get());
+ m_embedElement = toHTMLEmbedElement(embedElement.get());
m_embedElement->setAttribute(widthAttr, "100%");
m_embedElement->setAttribute(heightAttr, "100%");
@@ -104,7 +104,7 @@ void PluginDocumentParser::createDocumentStructure()
if (loader)
m_embedElement->setAttribute(typeAttr, loader->writer().mimeType());
- downcast<PluginDocument>(*document()).setPluginElement(m_embedElement);
+ toPluginDocument(document())->setPluginElement(m_embedElement);
body->appendChild(embedElement, IGNORE_EXCEPTION);
}
@@ -144,20 +144,22 @@ PluginDocument::PluginDocument(Frame* frame, const URL& url)
: HTMLDocument(frame, url, PluginDocumentClass)
, m_shouldLoadPluginManually(true)
{
- setCompatibilityMode(DocumentCompatibilityMode::QuirksMode);
+ setCompatibilityMode(QuirksMode);
lockCompatibilityMode();
}
-Ref<DocumentParser> PluginDocument::createParser()
+PassRefPtr<DocumentParser> PluginDocument::createParser()
{
return PluginDocumentParser::create(*this);
}
Widget* PluginDocument::pluginWidget()
{
- if (m_pluginElement && m_pluginElement->renderer())
- return downcast<RenderEmbeddedObject>(*m_pluginElement->renderer()).widget();
- return nullptr;
+ if (m_pluginElement && m_pluginElement->renderer()) {
+ ASSERT(m_pluginElement->renderer()->isEmbeddedObject());
+ return toRenderEmbeddedObject(m_pluginElement->renderer())->widget();
+ }
+ return 0;
}
void PluginDocument::setPluginElement(PassRefPtr<HTMLPlugInElement> element)
@@ -168,8 +170,8 @@ void PluginDocument::setPluginElement(PassRefPtr<HTMLPlugInElement> element)
void PluginDocument::detachFromPluginElement()
{
// Release the plugin Element so that we don't have a circular reference.
- m_pluginElement = nullptr;
- frame()->loader().client().redirectDataToPlugin(nullptr);
+ m_pluginElement = 0;
+ frame()->loader().client().redirectDataToPlugin(0);
}
void PluginDocument::cancelManualPluginLoad()
diff --git a/Source/WebCore/html/PluginDocument.h b/Source/WebCore/html/PluginDocument.h
index ae2379d5d..e6bf5bd3a 100644
--- a/Source/WebCore/html/PluginDocument.h
+++ b/Source/WebCore/html/PluginDocument.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
@@ -34,14 +34,14 @@ class Widget;
class PluginDocument final : public HTMLDocument {
public:
- static Ref<PluginDocument> create(Frame* frame, const URL& url)
+ static PassRefPtr<PluginDocument> create(Frame* frame, const URL& url)
{
- return adoptRef(*new PluginDocument(frame, url));
+ return adoptRef(new PluginDocument(frame, url));
}
void setPluginElement(PassRefPtr<HTMLPlugInElement>);
- WEBCORE_EXPORT Widget* pluginWidget();
+ Widget* pluginWidget();
HTMLPlugInElement* pluginElement() { return m_pluginElement.get(); }
void detachFromPluginElement();
@@ -53,7 +53,7 @@ public:
private:
PluginDocument(Frame*, const URL&);
- virtual Ref<DocumentParser> createParser() override;
+ virtual PassRefPtr<DocumentParser> createParser() override;
void setShouldLoadPluginManually(bool loadManually) { m_shouldLoadPluginManually = loadManually; }
@@ -61,11 +61,11 @@ private:
RefPtr<HTMLPlugInElement> m_pluginElement;
};
-} // namespace WebCore
+inline bool isPluginDocument(const Document& document) { return document.isPluginDocument(); }
+void isPluginDocument(const PluginDocument&); // Catch unnecessary runtime check of type known at compile time.
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::PluginDocument)
- static bool isType(const WebCore::Document& document) { return document.isPluginDocument(); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::Document>(node) && isType(downcast<WebCore::Document>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+DOCUMENT_TYPE_CASTS(PluginDocument)
+
+}
#endif // PluginDocument_h
diff --git a/Source/WebCore/html/PublicURLManager.cpp b/Source/WebCore/html/PublicURLManager.cpp
index cd3c462c6..2bf7d70cf 100644
--- a/Source/WebCore/html/PublicURLManager.cpp
+++ b/Source/WebCore/html/PublicURLManager.cpp
@@ -26,30 +26,17 @@
#include "config.h"
#include "PublicURLManager.h"
+
+#if ENABLE(BLOB)
+
#include "URL.h"
#include "URLRegistry.h"
#include <wtf/text/StringHash.h>
namespace WebCore {
-std::unique_ptr<PublicURLManager> PublicURLManager::create(ScriptExecutionContext* context)
-{
- auto publicURLManager = std::make_unique<PublicURLManager>(context);
- publicURLManager->suspendIfNeeded();
- return publicURLManager;
-}
-
-PublicURLManager::PublicURLManager(ScriptExecutionContext* context)
- : ActiveDOMObject(context)
- , m_isStopped(false)
-{
-}
-
void PublicURLManager::registerURL(SecurityOrigin* origin, const URL& url, URLRegistrable* registrable)
{
- if (m_isStopped)
- return;
-
RegistryURLMap::iterator found = m_registryToURL.add(&registrable->registry(), URLSet()).iterator;
found->key->registerURL(origin, url, registrable);
found->value.add(url.string());
@@ -66,12 +53,8 @@ void PublicURLManager::revoke(const URL& url)
}
}
-void PublicURLManager::stop()
+void PublicURLManager::contextDestroyed()
{
- if (m_isStopped)
- return;
-
- m_isStopped = true;
for (RegistryURLMap::iterator i = m_registryToURL.begin(); i != m_registryToURL.end(); ++i) {
for (URLSet::iterator j = i->value.begin(); j != i->value.end(); ++j)
i->key->unregisterURL(URL(ParsedURLString, *j));
@@ -80,15 +63,6 @@ void PublicURLManager::stop()
m_registryToURL.clear();
}
-bool PublicURLManager::canSuspendForPageCache() const
-{
- // Suspending an PublicURLManager is safe as it does not cause any JS to be executed.
- return true;
-}
-
-const char* PublicURLManager::activeDOMObjectName() const
-{
- return "PublicURLManager";
}
-} // namespace WebCore
+#endif // ENABLE(BLOB)
diff --git a/Source/WebCore/html/PublicURLManager.h b/Source/WebCore/html/PublicURLManager.h
index 500054e30..9ad01bd45 100644
--- a/Source/WebCore/html/PublicURLManager.h
+++ b/Source/WebCore/html/PublicURLManager.h
@@ -26,10 +26,11 @@
#ifndef PublicURLManager_h
#define PublicURLManager_h
-#include "ActiveDOMObject.h"
-#include <memory>
+#if ENABLE(BLOB)
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -40,28 +41,22 @@ class SecurityOrigin;
class URLRegistry;
class URLRegistrable;
-class PublicURLManager final : public ActiveDOMObject {
+class PublicURLManager {
WTF_MAKE_FAST_ALLOCATED;
public:
- explicit PublicURLManager(ScriptExecutionContext*);
-
- static std::unique_ptr<PublicURLManager> create(ScriptExecutionContext*);
+ static OwnPtr<PublicURLManager> create() { return adoptPtr(new PublicURLManager); }
void registerURL(SecurityOrigin*, const URL&, URLRegistrable*);
void revoke(const URL&);
+ void contextDestroyed();
private:
- // ActiveDOMObject API.
- void stop() override;
- bool canSuspendForPageCache() const override;
- const char* activeDOMObjectName() const override;
-
typedef HashSet<String> URLSet;
typedef HashMap<URLRegistry*, URLSet > RegistryURLMap;
RegistryURLMap m_registryToURL;
- bool m_isStopped;
};
} // namespace WebCore
+#endif // BLOB
#endif // PUBLICURLMANAGER_h
diff --git a/Source/WebCore/html/RadioInputType.cpp b/Source/WebCore/html/RadioInputType.cpp
index 8f276e786..239a9ce60 100644
--- a/Source/WebCore/html/RadioInputType.cpp
+++ b/Source/WebCore/html/RadioInputType.cpp
@@ -79,14 +79,14 @@ void RadioInputType::handleKeydownEvent(KeyboardEvent* event)
// We can only stay within the form's children if the form hasn't been demoted to a leaf because
// of malformed HTML.
Node* node = &element();
- while ((node = (forward ? NodeTraversal::next(*node) : NodeTraversal::previous(*node)))) {
+ while ((node = (forward ? NodeTraversal::next(node) : NodeTraversal::previous(node)))) {
// Once we encounter a form element, we know we're through.
- if (is<HTMLFormElement>(*node))
+ if (isHTMLFormElement(node))
break;
// Look for more radio buttons.
- if (!is<HTMLInputElement>(*node))
+ if (!isHTMLInputElement(node))
continue;
- RefPtr<HTMLInputElement> inputElement = downcast<HTMLInputElement>(node);
+ RefPtr<HTMLInputElement> inputElement = toHTMLInputElement(node);
if (inputElement->form() != element().form())
break;
if (inputElement->isRadioButton() && inputElement->name() == element().name() && inputElement->isFocusable()) {
@@ -122,9 +122,9 @@ bool RadioInputType::isKeyboardFocusable(KeyboardEvent* event) const
// Never allow keyboard tabbing to leave you in the same radio group. Always
// skip any other elements in the group.
Element* currentFocusedNode = element().document().focusedElement();
- if (is<HTMLInputElement>(currentFocusedNode)) {
- HTMLInputElement& focusedInput = downcast<HTMLInputElement>(*currentFocusedNode);
- if (focusedInput.isRadioButton() && focusedInput.form() == element().form() && focusedInput.name() == element().name())
+ if (currentFocusedNode && isHTMLInputElement(currentFocusedNode)) {
+ HTMLInputElement* focusedInput = toHTMLInputElement(currentFocusedNode);
+ if (focusedInput->isRadioButton() && focusedInput->form() == element().form() && focusedInput->name() == element().name())
return false;
}
diff --git a/Source/WebCore/html/RadioInputType.h b/Source/WebCore/html/RadioInputType.h
index 796a2f088..39104747f 100644
--- a/Source/WebCore/html/RadioInputType.h
+++ b/Source/WebCore/html/RadioInputType.h
@@ -35,7 +35,7 @@
namespace WebCore {
-class RadioInputType final : public BaseCheckableInputType {
+class RadioInputType : public BaseCheckableInputType {
public:
explicit RadioInputType(HTMLInputElement& element) : BaseCheckableInputType(element) { }
diff --git a/Source/WebCore/html/RadioNodeList.cpp b/Source/WebCore/html/RadioNodeList.cpp
index 5e4025ecc..ad7dc7601 100644
--- a/Source/WebCore/html/RadioNodeList.cpp
+++ b/Source/WebCore/html/RadioNodeList.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (c) 2012 Motorola Mobility, Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,9 +38,8 @@ namespace WebCore {
using namespace HTMLNames;
RadioNodeList::RadioNodeList(ContainerNode& rootNode, const AtomicString& name)
- : CachedLiveNodeList(rootNode, InvalidateForFormControls)
+ : LiveNodeList(rootNode, RadioNodeListType, InvalidateForFormControls, isHTMLFormElement(rootNode) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode)
, m_name(name)
- , m_isRootedAtDocument(is<HTMLFormElement>(ownerNode()))
{
}
@@ -83,28 +81,28 @@ void RadioNodeList::setValue(const String& value)
}
}
-bool RadioNodeList::checkElementMatchesRadioNodeListFilter(const Element& testElement) const
+bool RadioNodeList::checkElementMatchesRadioNodeListFilter(Element* testElement) const
{
- ASSERT(is<HTMLObjectElement>(testElement) || is<HTMLFormControlElement>(testElement));
- if (is<HTMLFormElement>(ownerNode())) {
- HTMLFormElement* formElement = nullptr;
- if (testElement.hasTagName(objectTag))
- formElement = downcast<HTMLObjectElement>(testElement).form();
+ ASSERT(testElement->hasTagName(objectTag) || testElement->isFormControlElement());
+ if (isHTMLFormElement(ownerNode())) {
+ HTMLFormElement* formElement = 0;
+ if (testElement->hasTagName(objectTag))
+ formElement = toHTMLObjectElement(testElement)->form();
else
- formElement = downcast<HTMLFormControlElement>(testElement).form();
+ formElement = toHTMLFormControlElement(testElement)->form();
if (!formElement || formElement != &ownerNode())
return false;
}
- return testElement.getIdAttribute() == m_name || testElement.getNameAttribute() == m_name;
+ return testElement->getIdAttribute() == m_name || testElement->getNameAttribute() == m_name;
}
-bool RadioNodeList::elementMatches(Element& testElement) const
+bool RadioNodeList::nodeMatches(Element* testElement) const
{
- if (!is<HTMLObjectElement>(testElement) && !is<HTMLFormControlElement>(testElement))
+ if (!testElement->hasTagName(objectTag) && !testElement->isFormControlElement())
return false;
- if (HTMLInputElement* inputElement = testElement.toInputElement()) {
+ if (HTMLInputElement* inputElement = testElement->toInputElement()) {
if (inputElement->isImageButton())
return false;
}
diff --git a/Source/WebCore/html/RadioNodeList.h b/Source/WebCore/html/RadioNodeList.h
index 3fcc97082..f82264ed4 100644
--- a/Source/WebCore/html/RadioNodeList.h
+++ b/Source/WebCore/html/RadioNodeList.h
@@ -1,6 +1,5 @@
/*
* Copyright (c) 2012 Motorola Mobility, Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,11 +32,12 @@
namespace WebCore {
-class RadioNodeList final : public CachedLiveNodeList<RadioNodeList> {
+class RadioNodeList : public LiveNodeList {
public:
- static Ref<RadioNodeList> create(ContainerNode& rootNode, const AtomicString& name)
+ static PassRefPtr<RadioNodeList> create(ContainerNode& rootNode, Type type, const AtomicString& name)
{
- return adoptRef(*new RadioNodeList(rootNode, name));
+ ASSERT_UNUSED(type, type == RadioNodeListType);
+ return adoptRef(new RadioNodeList(rootNode, name));
}
~RadioNodeList();
@@ -45,15 +45,14 @@ public:
String value() const;
void setValue(const String&);
- virtual bool elementMatches(Element&) const override;
- virtual bool isRootedAtDocument() const override { return m_isRootedAtDocument; }
+protected:
+ virtual bool nodeMatches(Element*) const override;
private:
RadioNodeList(ContainerNode&, const AtomicString& name);
- bool checkElementMatchesRadioNodeListFilter(const Element&) const;
+ bool checkElementMatchesRadioNodeListFilter(Element*) const;
AtomicString m_name;
- bool m_isRootedAtDocument;
};
} // namepsace
diff --git a/Source/WebCore/html/RangeInputType.cpp b/Source/WebCore/html/RangeInputType.cpp
index b5b9e7941..1c5857603 100644
--- a/Source/WebCore/html/RangeInputType.cpp
+++ b/Source/WebCore/html/RangeInputType.cpp
@@ -81,6 +81,11 @@ RangeInputType::RangeInputType(HTMLInputElement& element)
{
}
+void RangeInputType::attach()
+{
+ observeFeatureIfVisible(FeatureObserver::InputTypeRange);
+}
+
bool RangeInputType::isRangeControl() const
{
return true;
@@ -113,7 +118,7 @@ bool RangeInputType::supportsRequired() const
StepRange RangeInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (rangeDefaultStep, rangeDefaultStepBase, rangeStepScaleFactor));
+ DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (rangeDefaultStep, rangeDefaultStepBase, rangeStepScaleFactor));
const Decimal minimum = parseToNumber(element().fastGetAttribute(minAttr), rangeDefaultMinimum);
const Decimal maximum = ensureMaximum(parseToNumber(element().fastGetAttribute(maxAttr), rangeDefaultMaximum), minimum, rangeDefaultMaximum);
@@ -171,8 +176,6 @@ void RangeInputType::handleTouchEvent(TouchEvent* event)
typedSliderThumbElement().setPositionFromPoint(touches->item(0)->absoluteLocation());
event->setDefaultHandled();
}
-#else
- UNUSED_PARAM(event);
#endif
}
@@ -239,10 +242,12 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent* event)
if (newValue != current) {
EventQueueScope scope;
- setValueAsDecimal(newValue, DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
+ TextFieldEventBehavior eventBehavior = DispatchChangeEvent;
+ setValueAsDecimal(newValue, eventBehavior, IGNORE_EXCEPTION);
if (AXObjectCache* cache = element().document().existingAXObjectCache())
cache->postNotification(&element(), AXObjectCache::AXValueChanged);
+ element().dispatchFormControlChangeEvent();
}
event->setDefaultHandled();
@@ -268,7 +273,7 @@ HTMLElement* RangeInputType::sliderTrackElement() const
ASSERT(element().userAgentShadowRoot()->firstChild()->isHTMLElement());
ASSERT(element().userAgentShadowRoot()->firstChild()->firstChild()); // track
- return downcast<HTMLElement>(element().userAgentShadowRoot()->firstChild()->firstChild());
+ return &toHTMLElement(*element().userAgentShadowRoot()->firstChild()->firstChild());
}
SliderThumbElement& RangeInputType::typedSliderThumbElement() const
@@ -284,9 +289,9 @@ HTMLElement* RangeInputType::sliderThumbElement() const
return &typedSliderThumbElement();
}
-RenderPtr<RenderElement> RangeInputType::createInputRenderer(Ref<RenderStyle>&& style)
+RenderPtr<RenderElement> RangeInputType::createInputRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderSlider>(element(), WTF::move(style));
+ return createRenderer<RenderSlider>(element(), std::move(style));
}
Decimal RangeInputType::parseToNumber(const String& src, const Decimal& defaultValue) const
@@ -327,9 +332,6 @@ void RangeInputType::setValue(const String& value, bool valueChanged, TextFieldE
if (!valueChanged)
return;
- if (eventBehavior == DispatchNoEvent)
- element().setTextAsOfLastFormControlChangeEvent(value);
-
typedSliderThumbElement().setPositionFromValue();
}
@@ -368,12 +370,12 @@ void RangeInputType::updateTickMarkValues()
HTMLDataListElement* dataList = element().dataList();
if (!dataList)
return;
- Ref<HTMLCollection> options = dataList->options();
+ RefPtr<HTMLCollection> options = dataList->options();
m_tickMarkValues.reserveCapacity(options->length());
for (unsigned i = 0; i < options->length(); ++i) {
Node* node = options->item(i);
- HTMLOptionElement& optionElement = downcast<HTMLOptionElement>(*node);
- String optionValue = optionElement.value();
+ HTMLOptionElement* optionElement = toHTMLOptionElement(node);
+ String optionValue = optionElement->value();
if (!element().isValidValue(optionValue))
continue;
m_tickMarkValues.append(parseToNumber(optionValue, Decimal::nan()));
diff --git a/Source/WebCore/html/RangeInputType.h b/Source/WebCore/html/RangeInputType.h
index 9d9153779..f56ca262d 100644
--- a/Source/WebCore/html/RangeInputType.h
+++ b/Source/WebCore/html/RangeInputType.h
@@ -42,6 +42,7 @@ public:
explicit RangeInputType(HTMLInputElement&);
private:
+ virtual void attach() override;
virtual bool isRangeControl() const override;
virtual const AtomicString& formControlType() const override;
virtual double valueAsDouble() const override;
@@ -54,7 +55,7 @@ private:
virtual void handleMouseDownEvent(MouseEvent*) override;
#endif
virtual void handleKeydownEvent(KeyboardEvent*) override;
- virtual RenderPtr<RenderElement> createInputRenderer(Ref<RenderStyle>&&) override;
+ virtual RenderPtr<RenderElement> createInputRenderer(PassRef<RenderStyle>) override;
virtual void createShadowSubtree() override;
virtual Decimal parseToNumber(const String&, const Decimal&) const override;
virtual String serialize(const Decimal&) const override;
diff --git a/Source/WebCore/html/RelList.cpp b/Source/WebCore/html/RelList.cpp
deleted file mode 100644
index eb3f4bb59..000000000
--- a/Source/WebCore/html/RelList.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2014 Dhi Aurrahman <diorahman@rockybars.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "RelList.h"
-
-#include "Element.h"
-#include "HTMLNames.h"
-
-namespace WebCore {
-
-RelList::RelList(Element& element)
- : m_element(element)
- , m_relAttributeValue(SpaceSplitString(element.fastGetAttribute(HTMLNames::relAttr), false))
-{
-}
-
-void RelList::ref()
-{
- m_element.ref();
-}
-
-void RelList::deref()
-{
- m_element.deref();
-}
-
-unsigned RelList::length() const
-{
- return m_relAttributeValue.size();
-}
-
-const AtomicString RelList::item(unsigned index) const
-{
- if (index >= length())
- return nullAtom;
- return m_relAttributeValue[index];
-}
-
-Element* RelList::element() const
-{
- return &m_element;
-}
-
-void RelList::updateRelAttribute(const AtomicString& value)
-{
- m_relAttributeValue.set(value, false);
-}
-
-bool RelList::containsInternal(const AtomicString& token) const
-{
- return m_relAttributeValue.contains(token);
-}
-
-AtomicString RelList::value() const
-{
- return m_element.fastGetAttribute(HTMLNames::relAttr);
-}
-
-void RelList::setValue(const AtomicString& value)
-{
- m_element.setAttribute(HTMLNames::relAttr, value);
-}
-
-} // namespace WebCore
-
diff --git a/Source/WebCore/html/RelList.h b/Source/WebCore/html/RelList.h
deleted file mode 100644
index 9743ccf5d..000000000
--- a/Source/WebCore/html/RelList.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2014 Dhi Aurrahman <diorahman@rockybars.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RelList_h
-#define RelList_h
-
-#include "DOMTokenList.h"
-#include "SpaceSplitString.h"
-
-namespace WebCore {
-
-class Element;
-
-class RelList final : public DOMTokenList {
-public:
- RelList(Element&);
- void updateRelAttribute(const AtomicString&);
-
-private:
- virtual void ref() override;
- virtual void deref() override;
- virtual unsigned length() const override;
- virtual const AtomicString item(unsigned index) const override;
- virtual Element* element() const override;
- virtual bool containsInternal(const AtomicString&) const override;
- virtual AtomicString value() const override;
- virtual void setValue(const AtomicString&) override;
-
- Element& m_element;
- mutable SpaceSplitString m_relAttributeValue;
-};
-
-} // namespace WebCore
-
-#endif // RelList_h
-
diff --git a/Source/WebCore/html/ResetInputType.h b/Source/WebCore/html/ResetInputType.h
index 05e35395e..7c0266b5e 100644
--- a/Source/WebCore/html/ResetInputType.h
+++ b/Source/WebCore/html/ResetInputType.h
@@ -35,7 +35,7 @@
namespace WebCore {
-class ResetInputType final : public BaseButtonInputType {
+class ResetInputType : public BaseButtonInputType {
public:
explicit ResetInputType(HTMLInputElement& element) : BaseButtonInputType(element) { }
diff --git a/Source/WebCore/html/RubyElement.cpp b/Source/WebCore/html/RubyElement.cpp
deleted file mode 100644
index 0957893b5..000000000
--- a/Source/WebCore/html/RubyElement.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "RubyElement.h"
-
-#include "RenderRuby.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-RubyElement::RubyElement(const QualifiedName& tagName, Document& document)
- : HTMLElement(tagName, document)
-{
- ASSERT(hasTagName(rubyTag));
-}
-
-Ref<RubyElement> RubyElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(*new RubyElement(tagName, document));
-}
-
-RenderPtr<RenderElement> RubyElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition& insertionPosition)
-{
- if (style->display() == INLINE)
- return createRenderer<RenderRubyAsInline>(*this, WTF::move(style));
- if (style->display() == BLOCK || style.get().display() == INLINE_BLOCK)
- return createRenderer<RenderRubyAsBlock>(*this, WTF::move(style));
- return HTMLElement::createElementRenderer(WTF::move(style), insertionPosition);
-}
-
-}
diff --git a/Source/WebCore/html/RubyElement.h b/Source/WebCore/html/RubyElement.h
deleted file mode 100644
index d5b02ed62..000000000
--- a/Source/WebCore/html/RubyElement.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RubyElement_h
-#define RubyElement_h
-
-#include "HTMLElement.h"
-
-namespace WebCore {
-
-class RubyElement final : public HTMLElement {
-public:
- static Ref<RubyElement> create(const QualifiedName&, Document&);
-
-private:
- RubyElement(const QualifiedName&, Document&);
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
-};
-
-}
-
-#endif
diff --git a/Source/WebCore/html/RubyTextElement.cpp b/Source/WebCore/html/RubyTextElement.cpp
deleted file mode 100644
index c878b211c..000000000
--- a/Source/WebCore/html/RubyTextElement.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "RubyTextElement.h"
-
-#include "RenderRuby.h"
-#include "RenderRubyText.h"
-#include "RenderTreePosition.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-RubyTextElement::RubyTextElement(const QualifiedName& tagName, Document& document)
- : HTMLElement(tagName, document)
-{
- ASSERT(hasTagName(rtTag));
-}
-
-Ref<RubyTextElement> RubyTextElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(*new RubyTextElement(tagName, document));
-}
-
-RenderPtr<RenderElement> RubyTextElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition& insertionPosition)
-{
- // RenderRubyText requires its parent to be RenderRubyRun.
- if (isRuby(insertionPosition.parent()) && style->display() == BLOCK)
- return createRenderer<RenderRubyText>(*this, WTF::move(style));
- return HTMLElement::createElementRenderer(WTF::move(style), insertionPosition);
-}
-
-}
diff --git a/Source/WebCore/html/RubyTextElement.h b/Source/WebCore/html/RubyTextElement.h
deleted file mode 100644
index bfb6bc5e5..000000000
--- a/Source/WebCore/html/RubyTextElement.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RubyTextElement_h
-#define RubyTextElement_h
-
-#include "HTMLElement.h"
-
-namespace WebCore {
-
-class RubyTextElement final : public HTMLElement {
-public:
- static Ref<RubyTextElement> create(const QualifiedName&, Document&);
-
-private:
- RubyTextElement(const QualifiedName&, Document&);
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
-};
-
-}
-
-#endif
diff --git a/Source/WebCore/html/SearchInputType.cpp b/Source/WebCore/html/SearchInputType.cpp
index de43db580..2d95f37c2 100644
--- a/Source/WebCore/html/SearchInputType.cpp
+++ b/Source/WebCore/html/SearchInputType.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -46,44 +45,39 @@ using namespace HTMLNames;
SearchInputType::SearchInputType(HTMLInputElement& element)
: BaseTextInputType(element)
- , m_resultsButton(nullptr)
- , m_cancelButton(nullptr)
- , m_searchEventTimer(*this, &SearchInputType::searchEventTimerFired)
+ , m_resultsButton(0)
+ , m_cancelButton(0)
+ , m_searchEventTimer(this, &SearchInputType::searchEventTimerFired)
{
}
-void SearchInputType::addSearchResult()
+void SearchInputType::attach()
{
-#if !PLATFORM(IOS)
- if (auto* renderer = element().renderer())
- downcast<RenderSearchField>(*renderer).addSearchResult();
-#endif
+ TextFieldInputType::attach();
+ observeFeatureIfVisible(FeatureObserver::InputTypeSearch);
}
-static void updateResultButtonPseudoType(SearchFieldResultsButtonElement& resultButton, int maxResults)
+void SearchInputType::addSearchResult()
{
- if (!maxResults)
- resultButton.setPseudo(AtomicString("-webkit-search-results-decoration", AtomicString::ConstructFromLiteral));
- else if (maxResults < 0)
- resultButton.setPseudo(AtomicString("-webkit-search-decoration", AtomicString::ConstructFromLiteral));
- else if (maxResults > 0)
- resultButton.setPseudo(AtomicString("-webkit-search-results-button", AtomicString::ConstructFromLiteral));
+#if !PLATFORM(IOS)
+ if (RenderObject* renderer = element().renderer())
+ toRenderSearchField(renderer)->addSearchResult();
+#endif
}
-void SearchInputType::maxResultsAttributeChanged()
+RenderPtr<RenderElement> SearchInputType::createInputRenderer(PassRef<RenderStyle> style)
{
- if (m_resultsButton)
- updateResultButtonPseudoType(*m_resultsButton, element().maxResults());
+ return createRenderer<RenderSearchField>(element(), std::move(style));
}
-RenderPtr<RenderElement> SearchInputType::createInputRenderer(Ref<RenderStyle>&& style)
+const AtomicString& SearchInputType::formControlType() const
{
- return createRenderer<RenderSearchField>(element(), WTF::move(style));
+ return InputTypeNames::search();
}
-const AtomicString& SearchInputType::formControlType() const
+bool SearchInputType::shouldRespectSpeechAttribute()
{
- return InputTypeNames::search();
+ return true;
}
bool SearchInputType::isSearchField() const
@@ -109,7 +103,6 @@ void SearchInputType::createShadowSubtree()
RefPtr<SearchFieldResultsButtonElement> resultsButton = SearchFieldResultsButtonElement::create(element().document());
m_resultsButton = resultsButton.get();
- updateResultButtonPseudoType(*m_resultsButton, element().maxResults());
container->insertBefore(m_resultsButton, textWrapper, IGNORE_EXCEPTION);
RefPtr<SearchFieldCancelButtonElement> cancelButton = SearchFieldCancelButtonElement::create(element().document());
@@ -148,8 +141,8 @@ void SearchInputType::handleKeydownEvent(KeyboardEvent* event)
void SearchInputType::destroyShadowSubtree()
{
TextFieldInputType::destroyShadowSubtree();
- m_resultsButton = nullptr;
- m_cancelButton = nullptr;
+ m_resultsButton = 0;
+ m_cancelButton = 0;
}
void SearchInputType::startSearchEventTimer()
@@ -173,26 +166,26 @@ void SearchInputType::stopSearchEventTimer()
m_searchEventTimer.stop();
}
-void SearchInputType::searchEventTimerFired()
+void SearchInputType::searchEventTimerFired(Timer<SearchInputType>*)
{
element().onSearch();
}
bool SearchInputType::searchEventsShouldBeDispatched() const
{
- return element().fastHasAttribute(incrementalAttr);
+ return element().hasAttribute(incrementalAttr);
}
-void SearchInputType::didSetValueByUserEdit()
+void SearchInputType::didSetValueByUserEdit(ValueChangeState state)
{
if (m_cancelButton && element().renderer())
- downcast<RenderSearchField>(*element().renderer()).updateCancelButtonVisibility();
+ toRenderSearchField(element().renderer())->updateCancelButtonVisibility();
// If the incremental attribute is set, then dispatch the search event
if (searchEventsShouldBeDispatched())
startSearchEventTimer();
- TextFieldInputType::didSetValueByUserEdit();
+ TextFieldInputType::didSetValueByUserEdit(state);
}
bool SearchInputType::sizeShouldIncludeDecoration(int, int& preferredSize) const
diff --git a/Source/WebCore/html/SearchInputType.h b/Source/WebCore/html/SearchInputType.h
index 9da079d5f..14760f250 100644
--- a/Source/WebCore/html/SearchInputType.h
+++ b/Source/WebCore/html/SearchInputType.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -37,19 +36,21 @@
namespace WebCore {
+class SearchFieldCancelButtonElement;
class SearchFieldResultsButtonElement;
-class SearchInputType final : public BaseTextInputType {
+class SearchInputType : public BaseTextInputType {
public:
explicit SearchInputType(HTMLInputElement&);
void stopSearchEventTimer();
private:
+ virtual void attach() override;
virtual void addSearchResult() override;
- virtual void maxResultsAttributeChanged() override;
- virtual RenderPtr<RenderElement> createInputRenderer(Ref<RenderStyle>&&) override;
+ virtual RenderPtr<RenderElement> createInputRenderer(PassRef<RenderStyle>) override;
virtual const AtomicString& formControlType() const override;
+ virtual bool shouldRespectSpeechAttribute() override;
virtual bool isSearchField() const override;
virtual bool needsContainer() const override;
virtual void createShadowSubtree() override;
@@ -57,17 +58,17 @@ private:
virtual HTMLElement* resultsButtonElement() const override;
virtual HTMLElement* cancelButtonElement() const override;
virtual void handleKeydownEvent(KeyboardEvent*) override;
- virtual void didSetValueByUserEdit() override;
+ virtual void didSetValueByUserEdit(ValueChangeState) override;
virtual bool sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const override;
virtual float decorationWidth() const override;
- void searchEventTimerFired();
+ void searchEventTimerFired(Timer<SearchInputType>*);
bool searchEventsShouldBeDispatched() const;
void startSearchEventTimer();
- SearchFieldResultsButtonElement* m_resultsButton;
+ HTMLElement* m_resultsButton;
HTMLElement* m_cancelButton;
- Timer m_searchEventTimer;
+ Timer<SearchInputType> m_searchEventTimer;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/StepRange.cpp b/Source/WebCore/html/StepRange.cpp
index c47718a0c..e7e548445 100644
--- a/Source/WebCore/html/StepRange.cpp
+++ b/Source/WebCore/html/StepRange.cpp
@@ -65,13 +65,13 @@ StepRange::StepRange(const Decimal& stepBase, const Decimal& minimum, const Deci
Decimal StepRange::acceptableError() const
{
// FIXME: We should use DBL_MANT_DIG instead of FLT_MANT_DIG regarding to HTML5 specification.
- DEPRECATED_DEFINE_STATIC_LOCAL(const Decimal, twoPowerOfFloatMantissaBits, (Decimal::Positive, 0, UINT64_C(1) << FLT_MANT_DIG));
+ DEFINE_STATIC_LOCAL(const Decimal, twoPowerOfFloatMantissaBits, (Decimal::Positive, 0, UINT64_C(1) << FLT_MANT_DIG));
return m_stepDescription.stepValueShouldBe == StepValueShouldBeReal ? m_step / twoPowerOfFloatMantissaBits : Decimal(0);
}
Decimal StepRange::alignValueForStep(const Decimal& currentValue, const Decimal& newValue) const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const Decimal, tenPowerOf21, (Decimal::Positive, 21, 1));
+ DEFINE_STATIC_LOCAL(const Decimal, tenPowerOf21, (Decimal::Positive, 21, 1));
if (newValue >= tenPowerOf21)
return newValue;
@@ -150,7 +150,7 @@ bool StepRange::stepMismatch(const Decimal& valueForCheck) const
// Decimal's fractional part size is DBL_MAN_DIG-bit. If the current value
// is greater than step*2^DBL_MANT_DIG, the following computation for
// remainder makes no sense.
- DEPRECATED_DEFINE_STATIC_LOCAL(const Decimal, twoPowerOfDoubleMantissaBits, (Decimal::Positive, 0, UINT64_C(1) << DBL_MANT_DIG));
+ DEFINE_STATIC_LOCAL(const Decimal, twoPowerOfDoubleMantissaBits, (Decimal::Positive, 0, UINT64_C(1) << DBL_MANT_DIG));
if (value / twoPowerOfDoubleMantissaBits > m_step)
return false;
// The computation follows HTML5 4.10.7.2.10 `The step attribute' :
diff --git a/Source/WebCore/html/SubmitInputType.h b/Source/WebCore/html/SubmitInputType.h
index 68f78b663..c5da55518 100644
--- a/Source/WebCore/html/SubmitInputType.h
+++ b/Source/WebCore/html/SubmitInputType.h
@@ -35,7 +35,7 @@
namespace WebCore {
-class SubmitInputType final : public BaseButtonInputType {
+class SubmitInputType : public BaseButtonInputType {
public:
explicit SubmitInputType(HTMLInputElement& element) : BaseButtonInputType(element) { }
diff --git a/Source/WebCore/html/TelephoneInputType.cpp b/Source/WebCore/html/TelephoneInputType.cpp
index c6fb41152..77fd0e0a4 100644
--- a/Source/WebCore/html/TelephoneInputType.cpp
+++ b/Source/WebCore/html/TelephoneInputType.cpp
@@ -36,11 +36,22 @@
namespace WebCore {
+void TelephoneInputType::attach()
+{
+ TextFieldInputType::attach();
+ observeFeatureIfVisible(FeatureObserver::InputTypeTel);
+}
+
const AtomicString& TelephoneInputType::formControlType() const
{
return InputTypeNames::telephone();
}
+bool TelephoneInputType::shouldRespectSpeechAttribute()
+{
+ return true;
+}
+
bool TelephoneInputType::isTelephoneField() const
{
return true;
diff --git a/Source/WebCore/html/TelephoneInputType.h b/Source/WebCore/html/TelephoneInputType.h
index c56467146..5804f9b67 100644
--- a/Source/WebCore/html/TelephoneInputType.h
+++ b/Source/WebCore/html/TelephoneInputType.h
@@ -35,12 +35,14 @@
namespace WebCore {
-class TelephoneInputType final : public BaseTextInputType {
+class TelephoneInputType : public BaseTextInputType {
public:
explicit TelephoneInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
private:
+ virtual void attach() override;
virtual const AtomicString& formControlType() const override;
+ virtual bool shouldRespectSpeechAttribute() override;
virtual bool isTelephoneField() const override;
};
diff --git a/Source/WebCore/html/TextDocument.cpp b/Source/WebCore/html/TextDocument.cpp
index 71b3ef9e0..1fc166e3c 100644
--- a/Source/WebCore/html/TextDocument.cpp
+++ b/Source/WebCore/html/TextDocument.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
@@ -30,13 +30,13 @@
namespace WebCore {
TextDocument::TextDocument(Frame* frame, const URL& url)
- : HTMLDocument(frame, url, TextDocumentClass)
+ : HTMLDocument(frame, url)
{
- setCompatibilityMode(DocumentCompatibilityMode::QuirksMode);
+ setCompatibilityMode(QuirksMode);
lockCompatibilityMode();
}
-Ref<DocumentParser> TextDocument::createParser()
+PassRefPtr<DocumentParser> TextDocument::createParser()
{
return TextDocumentParser::create(*this);
}
diff --git a/Source/WebCore/html/TextDocument.h b/Source/WebCore/html/TextDocument.h
index d947d7554..911a23762 100644
--- a/Source/WebCore/html/TextDocument.h
+++ b/Source/WebCore/html/TextDocument.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
@@ -31,15 +31,15 @@ namespace WebCore {
class TextDocument final : public HTMLDocument {
public:
- static Ref<TextDocument> create(Frame* frame, const URL& url)
+ static PassRefPtr<TextDocument> create(Frame* frame, const URL& url)
{
- return adoptRef(*new TextDocument(frame, url));
+ return adoptRef(new TextDocument(frame, url));
}
private:
TextDocument(Frame*, const URL&);
- virtual Ref<DocumentParser> createParser() override;
+ virtual PassRefPtr<DocumentParser> createParser() override;
};
}
diff --git a/Source/WebCore/html/TextFieldInputType.cpp b/Source/WebCore/html/TextFieldInputType.cpp
index eae3db29e..9381d99cb 100644
--- a/Source/WebCore/html/TextFieldInputType.cpp
+++ b/Source/WebCore/html/TextFieldInputType.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
- * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -34,7 +34,6 @@
#include "BeforeTextInsertedEvent.h"
#include "Chrome.h"
-#include "ChromeClient.h"
#include "Editor.h"
#include "FormDataList.h"
#include "Frame.h"
@@ -44,7 +43,6 @@
#include "KeyboardEvent.h"
#include "NodeRenderStyle.h"
#include "Page.h"
-#include "PlatformKeyboardEvent.h"
#include "RenderLayer.h"
#include "RenderTextControlSingleLine.h"
#include "RenderTheme.h"
@@ -53,7 +51,6 @@
#include "TextControlInnerElements.h"
#include "TextEvent.h"
#include "TextIterator.h"
-#include "TextNodeTraversal.h"
#include "WheelEvent.h"
namespace WebCore {
@@ -90,21 +87,14 @@ bool TextFieldInputType::isTextField() const
return true;
}
-bool TextFieldInputType::isEmptyValue() const
+bool TextFieldInputType::valueMissing(const String& value) const
{
- TextControlInnerTextElement* innerText = innerTextElement();
- ASSERT(innerText);
-
- for (Text* text = TextNodeTraversal::firstWithin(*innerText); text; text = TextNodeTraversal::next(*text, innerText)) {
- if (text->length())
- return false;
- }
- return true;
+ return element().isRequired() && value.isEmpty();
}
-bool TextFieldInputType::valueMissing(const String& value) const
+bool TextFieldInputType::canSetSuggestedValue()
{
- return element().isRequired() && value.isEmpty();
+ return true;
}
void TextFieldInputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior)
@@ -186,40 +176,24 @@ void TextFieldInputType::forwardEvent(Event* event)
return;
}
- if (event->isMouseEvent()
- || event->isDragEvent()
- || event->eventInterface() == WheelEventInterfaceType
- || event->type() == eventNames().blurEvent
- || event->type() == eventNames().focusEvent)
- {
- element().document().updateStyleIfNeeded();
-
- if (element().renderer()) {
- RenderTextControlSingleLine& renderTextControl = downcast<RenderTextControlSingleLine>(*element().renderer());
- if (event->type() == eventNames().blurEvent) {
- if (RenderTextControlInnerBlock* innerTextRenderer = innerTextElement()->renderer()) {
- if (RenderLayer* innerLayer = innerTextRenderer->layer()) {
- IntSize scrollOffset(!renderTextControl.style().isLeftToRightDirection() ? innerLayer->scrollWidth() : 0, 0);
- innerLayer->scrollToOffset(scrollOffset, RenderLayer::ScrollOffsetClamped);
- }
+ if (element().renderer() && (event->isMouseEvent() || event->isDragEvent() || event->eventInterface() == WheelEventInterfaceType || event->type() == eventNames().blurEvent || event->type() == eventNames().focusEvent)) {
+ RenderTextControlSingleLine* renderTextControl = toRenderTextControlSingleLine(element().renderer());
+ if (event->type() == eventNames().blurEvent) {
+ if (RenderTextControlInnerBlock* innerTextRenderer = innerTextElement()->renderer()) {
+ if (RenderLayer* innerLayer = innerTextRenderer->layer()) {
+ IntSize scrollOffset(!renderTextControl->style().isLeftToRightDirection() ? innerLayer->scrollWidth() : 0, 0);
+ innerLayer->scrollToOffset(scrollOffset, RenderLayer::ScrollOffsetClamped);
}
+ }
- capsLockStateMayHaveChanged();
- } else if (event->type() == eventNames().focusEvent)
- capsLockStateMayHaveChanged();
+ renderTextControl->capsLockStateMayHaveChanged();
+ } else if (event->type() == eventNames().focusEvent)
+ renderTextControl->capsLockStateMayHaveChanged();
- element().forwardEvent(event);
- }
+ element().forwardEvent(event);
}
}
-void TextFieldInputType::handleFocusEvent(Node* oldFocusedNode, FocusDirection)
-{
- ASSERT_UNUSED(oldFocusedNode, oldFocusedNode != &element());
- if (Frame* frame = element().document().frame())
- frame->editor().textFieldDidBeginEditing(&element());
-}
-
void TextFieldInputType::handleBlurEvent()
{
InputType::handleBlurEvent();
@@ -228,32 +202,28 @@ void TextFieldInputType::handleBlurEvent()
bool TextFieldInputType::shouldSubmitImplicitly(Event* event)
{
- return (event->type() == eventNames().textInputEvent && is<TextEvent>(*event) && downcast<TextEvent>(*event).data() == "\n")
- || InputType::shouldSubmitImplicitly(event);
+ return (event->type() == eventNames().textInputEvent && event->eventInterface() == TextEventInterfaceType && static_cast<TextEvent*>(event)->data() == "\n") || InputType::shouldSubmitImplicitly(event);
}
-RenderPtr<RenderElement> TextFieldInputType::createInputRenderer(Ref<RenderStyle>&& style)
+RenderPtr<RenderElement> TextFieldInputType::createInputRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderTextControlSingleLine>(element(), WTF::move(style));
+ return createRenderer<RenderTextControlSingleLine>(element(), std::move(style));
}
bool TextFieldInputType::needsContainer() const
{
+#if ENABLE(INPUT_SPEECH)
+ return element().isSpeechEnabled();
+#else
return false;
+#endif
}
bool TextFieldInputType::shouldHaveSpinButton() const
{
Document& document = element().document();
RefPtr<RenderTheme> theme = document.page() ? &document.page()->theme() : RenderTheme::defaultTheme();
- return theme->shouldHaveSpinButton(element());
-}
-
-bool TextFieldInputType::shouldHaveCapsLockIndicator() const
-{
- Document& document = element().document();
- RefPtr<RenderTheme> theme = document.page() ? &document.page()->theme() : RenderTheme::defaultTheme();
- return theme->shouldHaveCapsLockIndicator(element());
+ return theme->shouldHaveSpinButton(&element());
}
void TextFieldInputType::createShadowSubtree()
@@ -263,41 +233,38 @@ void TextFieldInputType::createShadowSubtree()
ASSERT(!m_innerText);
ASSERT(!m_innerBlock);
ASSERT(!m_innerSpinButton);
- ASSERT(!m_capsLockIndicator);
- ASSERT(!m_autoFillButton);
Document& document = element().document();
bool shouldHaveSpinButton = this->shouldHaveSpinButton();
- bool shouldHaveCapsLockIndicator = this->shouldHaveCapsLockIndicator();
- bool createsContainer = shouldHaveSpinButton || shouldHaveCapsLockIndicator || needsContainer();
+ bool createsContainer = shouldHaveSpinButton || needsContainer();
m_innerText = TextControlInnerTextElement::create(document);
-
if (!createsContainer) {
element().userAgentShadowRoot()->appendChild(m_innerText, IGNORE_EXCEPTION);
- updatePlaceholderText();
return;
}
- createContainer();
- updatePlaceholderText();
+ ShadowRoot* shadowRoot = element().userAgentShadowRoot();
+ m_container = TextControlInnerContainer::create(document);
+ m_container->setPseudo(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
+ shadowRoot->appendChild(m_container, IGNORE_EXCEPTION);
+
+ m_innerBlock = TextControlInnerElement::create(document);
+ m_innerBlock->appendChild(m_innerText, IGNORE_EXCEPTION);
+ m_container->appendChild(m_innerBlock, IGNORE_EXCEPTION);
+
+#if ENABLE(INPUT_SPEECH)
+ ASSERT(!m_speechButton);
+ if (element().isSpeechEnabled()) {
+ m_speechButton = InputFieldSpeechButtonElement::create(document);
+ m_container->appendChild(m_speechButton, IGNORE_EXCEPTION);
+ }
+#endif
if (shouldHaveSpinButton) {
m_innerSpinButton = SpinButtonElement::create(document, *this);
m_container->appendChild(m_innerSpinButton, IGNORE_EXCEPTION);
}
-
- if (shouldHaveCapsLockIndicator) {
- m_capsLockIndicator = HTMLDivElement::create(document);
- m_capsLockIndicator->setPseudo(AtomicString("-webkit-caps-lock-indicator", AtomicString::ConstructFromLiteral));
-
- bool shouldDrawCapsLockIndicator = this->shouldDrawCapsLockIndicator();
- m_capsLockIndicator->setInlineStyleProperty(CSSPropertyDisplay, shouldDrawCapsLockIndicator ? CSSValueBlock : CSSValueNone, true);
-
- m_container->appendChild(m_capsLockIndicator, IGNORE_EXCEPTION);
- }
-
- updateAutoFillButton();
}
HTMLElement* TextFieldInputType::containerElement() const
@@ -321,15 +288,12 @@ HTMLElement* TextFieldInputType::innerSpinButtonElement() const
return m_innerSpinButton.get();
}
-HTMLElement* TextFieldInputType::capsLockIndicatorElement() const
+#if ENABLE(INPUT_SPEECH)
+HTMLElement* TextFieldInputType::speechButtonElement() const
{
- return m_capsLockIndicator.get();
-}
-
-HTMLElement* TextFieldInputType::autoFillButtonElement() const
-{
- return m_autoFillButton.get();
+ return m_speechButton.get();
}
+#endif
HTMLElement* TextFieldInputType::placeholderElement() const
{
@@ -339,15 +303,16 @@ HTMLElement* TextFieldInputType::placeholderElement() const
void TextFieldInputType::destroyShadowSubtree()
{
InputType::destroyShadowSubtree();
- m_innerText = nullptr;
- m_placeholder = nullptr;
- m_innerBlock = nullptr;
+ m_innerText.clear();
+ m_placeholder.clear();
+ m_innerBlock.clear();
+#if ENABLE(INPUT_SPEECH)
+ m_speechButton.clear();
+#endif
if (m_innerSpinButton)
m_innerSpinButton->removeSpinButtonOwner();
- m_innerSpinButton = nullptr;
- m_capsLockIndicator = nullptr;
- m_autoFillButton = nullptr;
- m_container = nullptr;
+ m_innerSpinButton.clear();
+ m_container.clear();
}
void TextFieldInputType::attributeChanged()
@@ -361,16 +326,12 @@ void TextFieldInputType::disabledAttributeChanged()
{
if (m_innerSpinButton)
m_innerSpinButton->releaseCapture();
- capsLockStateMayHaveChanged();
- updateAutoFillButton();
}
void TextFieldInputType::readonlyAttributeChanged()
{
if (m_innerSpinButton)
m_innerSpinButton->releaseCapture();
- capsLockStateMayHaveChanged();
- updateAutoFillButton();
}
bool TextFieldInputType::supportsReadOnly() const
@@ -413,22 +374,14 @@ void TextFieldInputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*
// We use RenderTextControlSingleLine::text() instead of InputElement::value()
// because they can be mismatched by sanitizeValue() in
// HTMLInputElement::subtreeHasChanged() in some cases.
- String innerText = element().innerTextValue();
- unsigned oldLength = numGraphemeClusters(innerText);
+ unsigned oldLength = numGraphemeClusters(element().innerTextValue());
// selectionLength represents the selection length of this text field to be
// removed by this insertion.
// If the text field has no focus, we don't need to take account of the
// selection length. The selection is the source of text drag-and-drop in
// that case, and nothing in the text field will be removed.
- unsigned selectionLength = 0;
- if (element().focused()) {
- ASSERT(enclosingTextFormControl(element().document().frame()->selection().selection().start()) == &element());
- int selectionStart = element().selectionStart();
- ASSERT(selectionStart <= element().selectionEnd());
- int selectionCodeUnitCount = element().selectionEnd() - selectionStart;
- selectionLength = selectionCodeUnitCount ? numGraphemeClusters(innerText.substring(selectionStart, selectionCodeUnitCount)) : 0;
- }
+ unsigned selectionLength = element().focused() ? numGraphemeClusters(plainText(element().document().frame()->selection().selection().toNormalizedRange().get())) : 0;
ASSERT(oldLength >= selectionLength);
// Selected characters will be removed by the next text event.
@@ -462,16 +415,14 @@ void TextFieldInputType::updatePlaceholderText()
if (placeholderText.isEmpty()) {
if (m_placeholder) {
m_placeholder->parentNode()->removeChild(m_placeholder.get(), ASSERT_NO_EXCEPTION);
- m_placeholder = nullptr;
+ m_placeholder.clear();
}
return;
}
if (!m_placeholder) {
m_placeholder = HTMLDivElement::create(element().document());
m_placeholder->setPseudo(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
- m_placeholder->setInlineStyleProperty(CSSPropertyDisplay, element().isPlaceholderVisible() ? CSSValueBlock : CSSValueNone, true);
element().userAgentShadowRoot()->insertBefore(m_placeholder, m_container ? m_container.get() : innerTextElement(), ASSERT_NO_EXCEPTION);
-
}
m_placeholder->setInnerText(placeholderText, ASSERT_NO_EXCEPTION);
}
@@ -492,6 +443,9 @@ String TextFieldInputType::convertFromVisibleValue(const String& visibleValue) c
void TextFieldInputType::subtreeHasChanged()
{
+ ASSERT(element().renderer());
+
+ bool wasChanged = element().wasChangedSinceLastFormControlChangeEvent();
element().setChangedSinceLastFormControlChangeEvent(true);
// We don't need to call sanitizeUserInputValue() function here because
@@ -499,19 +453,22 @@ void TextFieldInputType::subtreeHasChanged()
// sanitizeUserInputValue().
// sanitizeValue() is needed because IME input doesn't dispatch BeforeTextInsertedEvent.
element().setValueFromRenderer(sanitizeValue(convertFromVisibleValue(element().innerTextValue())));
- element().updatePlaceholderVisibility();
+ element().updatePlaceholderVisibility(false);
// Recalc for :invalid change.
element().setNeedsStyleRecalc();
- didSetValueByUserEdit();
+ didSetValueByUserEdit(wasChanged ? ValueChangeStateChanged : ValueChangeStateNone);
}
-void TextFieldInputType::didSetValueByUserEdit()
+void TextFieldInputType::didSetValueByUserEdit(ValueChangeState state)
{
if (!element().focused())
return;
- if (Frame* frame = element().document().frame())
+ if (Frame* frame = element().document().frame()) {
+ if (state == ValueChangeStateNone)
+ frame->editor().textFieldDidBeginEditing(&element());
frame->editor().textDidChangeInTextField(&element());
+ }
}
void TextFieldInputType::spinButtonStepDown()
@@ -526,11 +483,14 @@ void TextFieldInputType::spinButtonStepUp()
void TextFieldInputType::updateInnerTextValue()
{
- if (!element().formControlValueMatchesRenderer()) {
+ if (!element().suggestedValue().isNull()) {
+ element().setInnerTextValue(element().suggestedValue());
+ element().updatePlaceholderVisibility(false);
+ } else if (!element().formControlValueMatchesRenderer()) {
// Update the renderer value if the formControlValueMatchesRenderer() flag is false.
// It protects an unacceptable renderer value from being overwritten with the DOM value.
element().setInnerTextValue(visibleValue());
- element().updatePlaceholderVisibility();
+ element().updatePlaceholderVisibility(false);
}
}
@@ -551,85 +511,4 @@ bool TextFieldInputType::shouldSpinButtonRespondToWheelEvents()
return shouldSpinButtonRespondToMouseEvents() && element().focused();
}
-bool TextFieldInputType::shouldDrawCapsLockIndicator() const
-{
- if (element().document().focusedElement() != &element())
- return false;
-
- if (element().isDisabledOrReadOnly())
- return false;
-
- Frame* frame = element().document().frame();
- if (!frame)
- return false;
-
- if (!frame->selection().isFocusedAndActive())
- return false;
-
- return PlatformKeyboardEvent::currentCapsLockState();
-}
-
-void TextFieldInputType::capsLockStateMayHaveChanged()
-{
- if (!m_capsLockIndicator)
- return;
-
- bool shouldDrawCapsLockIndicator = this->shouldDrawCapsLockIndicator();
- m_capsLockIndicator->setInlineStyleProperty(CSSPropertyDisplay, shouldDrawCapsLockIndicator ? CSSValueBlock : CSSValueNone, true);
-}
-
-bool TextFieldInputType::shouldDrawAutoFillButton() const
-{
- return !element().isDisabledOrReadOnly() && element().showAutoFillButton();
-}
-
-void TextFieldInputType::autoFillButtonElementWasClicked()
-{
- Page* page = element().document().page();
- if (!page)
- return;
-
- page->chrome().client().handleAutoFillButtonClick(element());
-}
-
-void TextFieldInputType::createContainer()
-{
- ASSERT(!m_container);
-
- m_container = TextControlInnerContainer::create(element().document());
- m_container->setPseudo(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
-
- m_innerBlock = TextControlInnerElement::create(element().document());
- m_innerBlock->appendChild(m_innerText, IGNORE_EXCEPTION);
- m_container->appendChild(m_innerBlock, IGNORE_EXCEPTION);
-
- element().userAgentShadowRoot()->appendChild(m_container, IGNORE_EXCEPTION);
-}
-
-void TextFieldInputType::createAutoFillButton()
-{
- ASSERT(!m_autoFillButton);
-
- m_autoFillButton = AutoFillButtonElement::create(element().document(), *this);
- m_autoFillButton->setPseudo(AtomicString("-webkit-auto-fill-button", AtomicString::ConstructFromLiteral));
- m_container->appendChild(m_autoFillButton, IGNORE_EXCEPTION);
-}
-
-void TextFieldInputType::updateAutoFillButton()
-{
- if (shouldDrawAutoFillButton()) {
- if (!m_container)
- createContainer();
-
- if (!m_autoFillButton)
- createAutoFillButton();
-
- m_autoFillButton->setInlineStyleProperty(CSSPropertyDisplay, CSSValueBlock, true);
- return;
- }
-
- if (m_autoFillButton)
- m_autoFillButton->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone, true);
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/html/TextFieldInputType.h b/Source/WebCore/html/TextFieldInputType.h
index 985c3ea9b..620ba5550 100644
--- a/Source/WebCore/html/TextFieldInputType.h
+++ b/Source/WebCore/html/TextFieldInputType.h
@@ -31,7 +31,6 @@
#ifndef TextFieldInputType_h
#define TextFieldInputType_h
-#include "AutoFillButtonElement.h"
#include "InputType.h"
#include "SpinButtonElement.h"
@@ -42,86 +41,79 @@ class TextControlInnerTextElement;
// The class represents types of which UI contain text fields.
// It supports not only the types for BaseTextInputType but also type=number.
-class TextFieldInputType : public InputType, protected SpinButtonElement::SpinButtonOwner, protected AutoFillButtonElement::AutoFillButtonOwner {
+class TextFieldInputType : public InputType, protected SpinButtonElement::SpinButtonOwner {
protected:
explicit TextFieldInputType(HTMLInputElement&);
virtual ~TextFieldInputType();
+ virtual bool canSetSuggestedValue() override;
virtual void handleKeydownEvent(KeyboardEvent*) override;
void handleKeydownEventForSpinButton(KeyboardEvent*);
- virtual HTMLElement* containerElement() const override final;
- virtual HTMLElement* innerBlockElement() const override final;
- virtual TextControlInnerTextElement* innerTextElement() const override final;
- virtual HTMLElement* innerSpinButtonElement() const override final;
- virtual HTMLElement* capsLockIndicatorElement() const override final;
- virtual HTMLElement* autoFillButtonElement() const override final;
+ virtual HTMLElement* containerElement() const override;
+ virtual HTMLElement* innerBlockElement() const override;
+ virtual TextControlInnerTextElement* innerTextElement() const override;
+ virtual HTMLElement* innerSpinButtonElement() const override;
+#if ENABLE(INPUT_SPEECH)
+ virtual HTMLElement* speechButtonElement() const override;
+#endif
protected:
virtual bool needsContainer() const;
+ virtual bool shouldHaveSpinButton() const;
virtual void createShadowSubtree() override;
virtual void destroyShadowSubtree() override;
- virtual void attributeChanged() override final;
- virtual void disabledAttributeChanged() override final;
- virtual void readonlyAttributeChanged() override final;
- virtual bool supportsReadOnly() const override final;
- void handleFocusEvent(Node* oldFocusedNode, FocusDirection) override final;
- virtual void handleBlurEvent() override final;
+ virtual void attributeChanged() override;
+ virtual void disabledAttributeChanged() override;
+ virtual void readonlyAttributeChanged() override;
+ virtual bool supportsReadOnly() const override;
+ virtual void handleBlurEvent() override;
virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior) override;
- virtual void updateInnerTextValue() override final;
+ virtual void updateInnerTextValue() override;
#if PLATFORM(IOS)
virtual String sanitizeValue(const String&) const override;
#endif
virtual String convertFromVisibleValue(const String&) const;
- virtual void didSetValueByUserEdit();
+ enum ValueChangeState {
+ ValueChangeStateNone,
+ ValueChangeStateChanged
+ };
+ virtual void didSetValueByUserEdit(ValueChangeState);
private:
- virtual bool isKeyboardFocusable(KeyboardEvent*) const override final;
- virtual bool isMouseFocusable() const override final;
- virtual bool isTextField() const override final;
- virtual bool isEmptyValue() const override final;
- virtual bool valueMissing(const String&) const override final;
- virtual void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) override final;
- virtual void forwardEvent(Event*) override final;
- virtual bool shouldSubmitImplicitly(Event*) override final;
- virtual RenderPtr<RenderElement> createInputRenderer(Ref<RenderStyle>&&) override;
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const override;
+ virtual bool isMouseFocusable() const override;
+ virtual bool isTextField() const override;
+ virtual bool valueMissing(const String&) const override;
+ virtual void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) override;
+ virtual void forwardEvent(Event*) override;
+ virtual bool shouldSubmitImplicitly(Event*) override;
+ virtual RenderPtr<RenderElement> createInputRenderer(PassRef<RenderStyle>) override;
virtual bool shouldUseInputMethod() const override;
#if !PLATFORM(IOS)
virtual String sanitizeValue(const String&) const override;
#endif
virtual bool shouldRespectListAttribute() override;
- virtual HTMLElement* placeholderElement() const override final;
- virtual void updatePlaceholderText() override final;
- virtual bool appendFormData(FormDataList&, bool multipart) const override final;
- virtual void subtreeHasChanged() override final;
- virtual void capsLockStateMayHaveChanged() override final;
- virtual void updateAutoFillButton() override final;
+ virtual HTMLElement* placeholderElement() const override;
+ virtual void updatePlaceholderText() override;
+ virtual bool appendFormData(FormDataList&, bool multipart) const override;
+ virtual void subtreeHasChanged() override;
// SpinButtonElement::SpinButtonOwner functions.
- virtual void focusAndSelectSpinButtonOwner() override final;
- virtual bool shouldSpinButtonRespondToMouseEvents() override final;
- virtual bool shouldSpinButtonRespondToWheelEvents() override final;
- virtual void spinButtonStepDown() override final;
- virtual void spinButtonStepUp() override final;
-
- // AutoFillButtonElement::AutoFillButtonOwner
- virtual void autoFillButtonElementWasClicked() override final;
-
- bool shouldHaveSpinButton() const;
- bool shouldHaveCapsLockIndicator() const;
- bool shouldDrawCapsLockIndicator() const;
- bool shouldDrawAutoFillButton() const;
-
- void createContainer();
- void createAutoFillButton();
+ virtual void focusAndSelectSpinButtonOwner() override;
+ virtual bool shouldSpinButtonRespondToMouseEvents() override;
+ virtual bool shouldSpinButtonRespondToWheelEvents() override;
+ virtual void spinButtonStepDown() override;
+ virtual void spinButtonStepUp() override;
RefPtr<HTMLElement> m_container;
RefPtr<HTMLElement> m_innerBlock;
RefPtr<TextControlInnerTextElement> m_innerText;
RefPtr<HTMLElement> m_placeholder;
RefPtr<SpinButtonElement> m_innerSpinButton;
- RefPtr<HTMLElement> m_capsLockIndicator;
- RefPtr<HTMLElement> m_autoFillButton;
+#if ENABLE(INPUT_SPEECH)
+ RefPtr<HTMLElement> m_speechButton;
+#endif
};
} // namespace WebCore
diff --git a/Source/WebCore/html/TextInputType.cpp b/Source/WebCore/html/TextInputType.cpp
index b54e9b2e7..aa0804e1c 100644
--- a/Source/WebCore/html/TextInputType.cpp
+++ b/Source/WebCore/html/TextInputType.cpp
@@ -39,9 +39,24 @@ namespace WebCore {
using namespace HTMLNames;
+void TextInputType::attach()
+{
+ TextFieldInputType::attach();
+ const AtomicString& type = element().fastGetAttribute(typeAttr);
+ if (equalIgnoringCase(type, InputTypeNames::datetime()))
+ observeFeatureIfVisible(FeatureObserver::InputTypeDateTimeFallback);
+ else if (equalIgnoringCase(type, InputTypeNames::week()))
+ observeFeatureIfVisible(FeatureObserver::InputTypeWeekFallback);
+}
+
const AtomicString& TextInputType::formControlType() const
{
return InputTypeNames::text();
}
+bool TextInputType::shouldRespectSpeechAttribute()
+{
+ return true;
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/html/TextInputType.h b/Source/WebCore/html/TextInputType.h
index abc5f48a8..34905a2b5 100644
--- a/Source/WebCore/html/TextInputType.h
+++ b/Source/WebCore/html/TextInputType.h
@@ -35,12 +35,14 @@
namespace WebCore {
-class TextInputType final : public BaseTextInputType {
+class TextInputType : public BaseTextInputType {
public:
explicit TextInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
private:
+ virtual void attach() override;
virtual const AtomicString& formControlType() const override;
+ virtual bool shouldRespectSpeechAttribute() override;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/TextMetrics.h b/Source/WebCore/html/TextMetrics.h
index 7702b92c0..b272ef664 100644
--- a/Source/WebCore/html/TextMetrics.h
+++ b/Source/WebCore/html/TextMetrics.h
@@ -26,14 +26,14 @@
#ifndef TextMetrics_h
#define TextMetrics_h
-#include <wtf/Ref.h>
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
class TextMetrics : public RefCounted<TextMetrics> {
public:
- static Ref<TextMetrics> create() { return adoptRef(*new TextMetrics); }
+ static PassRefPtr<TextMetrics> create() { return adoptRef(new TextMetrics); }
float width() const { return m_width; }
void setWidth(float w) { m_width = w; }
diff --git a/Source/WebCore/html/TextMetrics.idl b/Source/WebCore/html/TextMetrics.idl
index b57099965..7677784d3 100644
--- a/Source/WebCore/html/TextMetrics.idl
+++ b/Source/WebCore/html/TextMetrics.idl
@@ -25,6 +25,6 @@
[
ImplementationLacksVTable,
] interface TextMetrics {
- readonly attribute unrestricted float width;
+ readonly attribute float width;
};
diff --git a/Source/WebCore/html/TimeInputType.cpp b/Source/WebCore/html/TimeInputType.cpp
index c09041901..9db586dd1 100644
--- a/Source/WebCore/html/TimeInputType.cpp
+++ b/Source/WebCore/html/TimeInputType.cpp
@@ -52,6 +52,11 @@ TimeInputType::TimeInputType(HTMLInputElement& element)
{
}
+void TimeInputType::attach()
+{
+ observeFeatureIfVisible(FeatureObserver::InputTypeTime);
+}
+
const AtomicString& TimeInputType::formControlType() const
{
return InputTypeNames::time();
@@ -77,7 +82,7 @@ Decimal TimeInputType::defaultValueForStepUp() const
StepRange TimeInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (timeDefaultStep, timeDefaultStepBase, timeStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
+ DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (timeDefaultStep, timeDefaultStepBase, timeStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
const Decimal stepBase = parseToNumber(element().fastGetAttribute(minAttr), 0);
const Decimal minimum = parseToNumber(element().fastGetAttribute(minAttr), Decimal::fromDouble(DateComponents::minimumTime()));
diff --git a/Source/WebCore/html/TimeInputType.h b/Source/WebCore/html/TimeInputType.h
index 1f1462af9..2c55bdfff 100644
--- a/Source/WebCore/html/TimeInputType.h
+++ b/Source/WebCore/html/TimeInputType.h
@@ -36,11 +36,12 @@
namespace WebCore {
-class TimeInputType final : public BaseChooserOnlyDateAndTimeInputType {
+class TimeInputType : public BaseChooserOnlyDateAndTimeInputType {
public:
explicit TimeInputType(HTMLInputElement&);
private:
+ virtual void attach() override;
virtual const AtomicString& formControlType() const override;
virtual DateComponents::Type dateType() const override;
virtual Decimal defaultValueForStepUp() const override;
diff --git a/Source/WebCore/html/TimeRanges.cpp b/Source/WebCore/html/TimeRanges.cpp
index e74f92d7e..34b70a3ca 100644
--- a/Source/WebCore/html/TimeRanges.cpp
+++ b/Source/WebCore/html/TimeRanges.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -29,110 +29,180 @@
#include "ExceptionCode.h"
#include "ExceptionCodePlaceholder.h"
+#include <math.h>
namespace WebCore {
-Ref<TimeRanges> TimeRanges::create()
+TimeRanges::TimeRanges(double start, double end)
{
- return adoptRef(*new TimeRanges);
+ add(start, end);
}
-Ref<TimeRanges> TimeRanges::create(double start, double end)
+PassRefPtr<TimeRanges> TimeRanges::copy() const
{
- return adoptRef(*new TimeRanges(start, end));
+ RefPtr<TimeRanges> newSession = TimeRanges::create();
+
+ unsigned size = m_ranges.size();
+ for (unsigned i = 0; i < size; i++)
+ newSession->add(m_ranges[i].m_start, m_ranges[i].m_end);
+
+ return newSession.release();
}
-Ref<TimeRanges> TimeRanges::create(const PlatformTimeRanges& other)
+void TimeRanges::invert()
{
- return adoptRef(*new TimeRanges(other));
-}
+ RefPtr<TimeRanges> inverted = TimeRanges::create();
+ double posInf = std::numeric_limits<double>::infinity();
+ double negInf = -std::numeric_limits<double>::infinity();
-TimeRanges::TimeRanges()
-{
-}
+ if (!m_ranges.size())
+ inverted->add(negInf, posInf);
+ else {
+ double start = m_ranges.first().m_start;
+ if (start != negInf)
+ inverted->add(negInf, start);
-TimeRanges::TimeRanges(double start, double end)
- : m_ranges(PlatformTimeRanges(MediaTime::createWithDouble(start), MediaTime::createWithDouble(end)))
-{
+ for (size_t index = 0; index + 1 < m_ranges.size(); ++index)
+ inverted->add(m_ranges[index].m_end, m_ranges[index + 1].m_start);
+
+ double end = m_ranges.last().m_end;
+ if (end != posInf)
+ inverted->add(end, posInf);
+ }
+
+ m_ranges.swap(inverted->m_ranges);
}
-TimeRanges::TimeRanges(const PlatformTimeRanges& other)
- : m_ranges(other)
+void TimeRanges::intersectWith(const TimeRanges* other)
{
+ ASSERT(other);
+
+ if (other == this)
+ return;
+
+ RefPtr<TimeRanges> invertedOther = other->copy();
+ invertedOther->invert();
+
+ invert();
+ unionWith(invertedOther.get());
+ invert();
}
-double TimeRanges::start(unsigned index, ExceptionCode& ec) const
+void TimeRanges::unionWith(const TimeRanges* other)
{
- bool valid;
- MediaTime result = m_ranges.start(index, valid);
+ ASSERT(other);
+ RefPtr<TimeRanges> unioned = copy();
+ for (size_t index = 0; index < other->m_ranges.size(); ++index) {
+ const Range& range = other->m_ranges[index];
+ unioned->add(range.m_start, range.m_end);
+ }
+
+ m_ranges.swap(unioned->m_ranges);
+}
- if (!valid) {
+double TimeRanges::start(unsigned index, ExceptionCode& ec) const
+{
+ if (index >= length()) {
ec = INDEX_SIZE_ERR;
return 0;
}
- return result.toDouble();
+ return m_ranges[index].m_start;
}
double TimeRanges::end(unsigned index, ExceptionCode& ec) const
{
- bool valid;
- MediaTime result = m_ranges.end(index, valid);
-
- if (!valid) {
+ if (index >= length()) {
ec = INDEX_SIZE_ERR;
return 0;
}
- return result.toDouble();
-}
-
-void TimeRanges::invert()
-{
- m_ranges.invert();
-}
-
-PassRefPtr<TimeRanges> TimeRanges::copy() const
-{
- return TimeRanges::create(m_ranges);
-}
-
-void TimeRanges::intersectWith(const TimeRanges& other)
-{
- m_ranges.intersectWith(other.ranges());
-}
-
-void TimeRanges::unionWith(const TimeRanges& other)
-{
- m_ranges.unionWith(other.ranges());
-}
-
-unsigned TimeRanges::length() const
-{
- return m_ranges.length();
-}
+ return m_ranges[index].m_end;
+}
+
+void TimeRanges::add(double start, double end)
+{
+ ASSERT(start <= end);
+ unsigned int overlappingArcIndex;
+ Range addedRange(start, end);
+
+ // For each present range check if we need to:
+ // - merge with the added range, in case we are overlapping or contiguous
+ // - Need to insert in place, we we are completely, not overlapping and not contiguous
+ // in between two ranges.
+ //
+ // TODO: Given that we assume that ranges are correctly ordered, this could be optimized.
+
+ for (overlappingArcIndex = 0; overlappingArcIndex < m_ranges.size(); overlappingArcIndex++) {
+ if (addedRange.isOverlappingRange(m_ranges[overlappingArcIndex])
+ || addedRange.isContiguousWithRange(m_ranges[overlappingArcIndex])) {
+ // We need to merge the addedRange and that range.
+ addedRange = addedRange.unionWithOverlappingOrContiguousRange(m_ranges[overlappingArcIndex]);
+ m_ranges.remove(overlappingArcIndex);
+ overlappingArcIndex--;
+ } else {
+ // Check the case for which there is no more to do
+ if (!overlappingArcIndex) {
+ if (addedRange.isBeforeRange(m_ranges[0])) {
+ // First index, and we are completely before that range (and not contiguous, nor overlapping).
+ // We just need to be inserted here.
+ break;
+ }
+ } else {
+ if (m_ranges[overlappingArcIndex - 1].isBeforeRange(addedRange)
+ && addedRange.isBeforeRange(m_ranges[overlappingArcIndex])) {
+ // We are exactly after the current previous range, and before the current range, while
+ // not overlapping with none of them. Insert here.
+ break;
+ }
+ }
+ }
+ }
-void TimeRanges::add(double start, double end)
-{
- m_ranges.add(MediaTime::createWithDouble(start), MediaTime::createWithDouble(end));
+ // Now that we are sure we don't overlap with any range, just add it.
+ m_ranges.insert(overlappingArcIndex, addedRange);
}
bool TimeRanges::contain(double time) const
{
- return m_ranges.contain(MediaTime::createWithDouble(time));
+ return find(time) != notFound;
}
size_t TimeRanges::find(double time) const
{
- return m_ranges.find(MediaTime::createWithDouble(time));
+ for (unsigned n = 0; n < length(); n++) {
+ if (time >= start(n, IGNORE_EXCEPTION) && time <= end(n, IGNORE_EXCEPTION))
+ return n;
+ }
+ return notFound;
}
double TimeRanges::nearest(double time) const
{
- return m_ranges.nearest(MediaTime::createWithDouble(time)).toDouble();
+ double closestDelta = std::numeric_limits<double>::infinity();
+ double closestTime = 0;
+ unsigned count = length();
+ for (unsigned ndx = 0; ndx < count; ndx++) {
+ double startTime = start(ndx, IGNORE_EXCEPTION);
+ double endTime = end(ndx, IGNORE_EXCEPTION);
+ if (time >= startTime && time <= endTime)
+ return time;
+ if (fabs(startTime - time) < closestDelta) {
+ closestTime = startTime;
+ closestDelta = fabsf(startTime - time);
+ }
+ if (fabs(endTime - time) < closestDelta) {
+ closestTime = endTime;
+ closestDelta = fabsf(endTime - time);
+ }
+ }
+ return closestTime;
}
double TimeRanges::totalDuration() const
{
- return m_ranges.totalDuration().toDouble();
+ double total = 0;
+ for (unsigned n = 0; n < length(); n++)
+ total += fabs(end(n, IGNORE_EXCEPTION) - start(n, IGNORE_EXCEPTION));
+ return total;
}
}
diff --git a/Source/WebCore/html/TimeRanges.h b/Source/WebCore/html/TimeRanges.h
index 20b2edf64..72233be83 100644
--- a/Source/WebCore/html/TimeRanges.h
+++ b/Source/WebCore/html/TimeRanges.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,7 +26,6 @@
#ifndef TimeRanges_h
#define TimeRanges_h
-#include "PlatformTimeRanges.h"
#include <algorithm>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -38,37 +37,82 @@ typedef int ExceptionCode;
class TimeRanges : public RefCounted<TimeRanges> {
public:
- WEBCORE_EXPORT static Ref<TimeRanges> create();
- WEBCORE_EXPORT static Ref<TimeRanges> create(double start, double end);
- static Ref<TimeRanges> create(const PlatformTimeRanges&);
+ static PassRefPtr<TimeRanges> create()
+ {
+ return adoptRef(new TimeRanges);
+ }
+ static PassRefPtr<TimeRanges> create(double start, double end)
+ {
+ return adoptRef(new TimeRanges(start, end));
+ }
- WEBCORE_EXPORT double start(unsigned index, ExceptionCode&) const;
- WEBCORE_EXPORT double end(unsigned index, ExceptionCode&) const;
-
- WEBCORE_EXPORT PassRefPtr<TimeRanges> copy() const;
+ PassRefPtr<TimeRanges> copy() const;
void invert();
- WEBCORE_EXPORT void intersectWith(const TimeRanges&);
- void unionWith(const TimeRanges&);
-
- WEBCORE_EXPORT unsigned length() const;
+ void intersectWith(const TimeRanges*);
+ void unionWith(const TimeRanges*);
- WEBCORE_EXPORT void add(double start, double end);
- bool contain(double time) const;
+ unsigned length() const { return m_ranges.size(); }
+ double start(unsigned index, ExceptionCode&) const;
+ double end(unsigned index, ExceptionCode&) const;
+
+ void add(double start, double end);
+ bool contain(double time) const;
+
size_t find(double time) const;
- WEBCORE_EXPORT double nearest(double time) const;
- double totalDuration() const;
+
+ double nearest(double time) const;
- const PlatformTimeRanges& ranges() const { return m_ranges; }
- PlatformTimeRanges& ranges() { return m_ranges; }
+ double totalDuration() const;
private:
- WEBCORE_EXPORT explicit TimeRanges();
- WEBCORE_EXPORT TimeRanges(double start, double end);
- TimeRanges(const PlatformTimeRanges&);
+ TimeRanges() { }
+ TimeRanges(double start, double end);
+ TimeRanges(const TimeRanges&);
+
+ // We consider all the Ranges to be semi-bounded as follow: [start, end[
+ struct Range {
+ Range() { }
+ Range(double start, double end)
+ {
+ m_start = start;
+ m_end = end;
+ }
+ double m_start;
+ double m_end;
+
+ inline bool isPointInRange(double point) const
+ {
+ return m_start <= point && point < m_end;
+ }
+
+ inline bool isOverlappingRange(const Range& range) const
+ {
+ return isPointInRange(range.m_start) || isPointInRange(range.m_end) || range.isPointInRange(m_start);
+ }
+ inline bool isContiguousWithRange(const Range& range) const
+ {
+ return range.m_start == m_end || range.m_end == m_start;
+ }
+
+ inline Range unionWithOverlappingOrContiguousRange(const Range& range) const
+ {
+ Range ret;
- PlatformTimeRanges m_ranges;
+ ret.m_start = std::min(m_start, range.m_start);
+ ret.m_end = std::max(m_end, range.m_end);
+
+ return ret;
+ }
+
+ inline bool isBeforeRange(const Range& range) const
+ {
+ return range.m_start >= m_end;
+ }
+ };
+
+ Vector<Range> m_ranges;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/TimeRanges.idl b/Source/WebCore/html/TimeRanges.idl
index 2da1febf1..3168d1135 100644
--- a/Source/WebCore/html/TimeRanges.idl
+++ b/Source/WebCore/html/TimeRanges.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,7 +28,7 @@
ImplementationLacksVTable,
] interface TimeRanges {
readonly attribute unsigned long length;
- [RaisesException] unrestricted double start(unsigned long index);
- [RaisesException] unrestricted double end(unsigned long index);
+ [RaisesException] double start(unsigned long index);
+ [RaisesException] double end(unsigned long index);
};
diff --git a/Source/WebCore/html/URLInputType.cpp b/Source/WebCore/html/URLInputType.cpp
index f3229ec49..cba29ec50 100644
--- a/Source/WebCore/html/URLInputType.cpp
+++ b/Source/WebCore/html/URLInputType.cpp
@@ -38,6 +38,12 @@
namespace WebCore {
+void URLInputType::attach()
+{
+ TextFieldInputType::attach();
+ observeFeatureIfVisible(FeatureObserver::InputTypeURL);
+}
+
const AtomicString& URLInputType::formControlType() const
{
return InputTypeNames::url();
diff --git a/Source/WebCore/html/URLInputType.h b/Source/WebCore/html/URLInputType.h
index 6b9b86423..396056ffc 100644
--- a/Source/WebCore/html/URLInputType.h
+++ b/Source/WebCore/html/URLInputType.h
@@ -35,11 +35,12 @@
namespace WebCore {
-class URLInputType final : public BaseTextInputType {
+class URLInputType : public BaseTextInputType {
public:
explicit URLInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
private:
+ virtual void attach() override;
virtual const AtomicString& formControlType() const override;
virtual bool typeMismatchFor(const String&) const override;
virtual bool typeMismatch() const override;
diff --git a/Source/WebCore/html/URLUtils.h b/Source/WebCore/html/URLUtils.h
deleted file mode 100644
index 21b9f4779..000000000
--- a/Source/WebCore/html/URLUtils.h
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef URLUtils_h
-#define URLUtils_h
-
-#include "SecurityOrigin.h"
-
-namespace WebCore {
-
-template <typename T>
-class URLUtils {
-public:
- URL href() const { return static_cast<const T*>(this)->href(); }
- void setHref(const String& url) { static_cast<T*>(this)->setHref(url); }
-
- String toString() const;
-
- String origin() const;
-
- String protocol() const;
- void setProtocol(const String&);
-
- String username() const;
- void setUsername(const String&);
-
- String password() const;
- void setPassword(const String&);
-
- String host() const;
- void setHost(const String&);
-
- String hostname() const;
- void setHostname(const String&);
-
- String port() const;
- void setPort(const String&);
-
- String pathname() const;
- void setPathname(const String&);
-
- String search() const;
- void setSearch(const String&);
-
- String hash() const;
- void setHash(const String&);
-};
-
-template <typename T>
-String URLUtils<T>::toString() const
-{
- return href().string();
-}
-
-template <typename T>
-String URLUtils<T>::origin() const
-{
- RefPtr<SecurityOrigin> origin = SecurityOrigin::create(href());
- return origin->toString();
-}
-
-template <typename T>
-String URLUtils<T>::protocol() const
-{
- return href().protocol() + ':';
-}
-
-template <typename T>
-void URLUtils<T>::setProtocol(const String& value)
-{
- URL url = href();
- url.setProtocol(value);
- setHref(url.string());
-}
-
-template <typename T>
-String URLUtils<T>::username() const
-{
- return href().encodedUser();
-}
-
-template <typename T>
-void URLUtils<T>::setUsername(const String& user)
-{
- URL url = href();
- url.setUser(user);
- setHref(url);
-}
-
-template <typename T>
-String URLUtils<T>::password() const
-{
- return href().encodedPass();
-}
-
-template <typename T>
-void URLUtils<T>::setPassword(const String& pass)
-{
- URL url = href();
- url.setPass(pass);
- setHref(url);
-}
-
-template <typename T>
-String URLUtils<T>::host() const
-{
- const URL& url = href();
- if (url.hostEnd() == url.pathStart())
- return url.host();
- if (isDefaultPortForProtocol(url.port(), url.protocol()))
- return url.host();
- return url.host() + ':' + String::number(url.port());
-}
-
-// This function does not allow leading spaces before the port number.
-static inline unsigned parsePortFromStringPosition(const String& value, unsigned portStart, unsigned& portEnd)
-{
- portEnd = portStart;
- while (isASCIIDigit(value[portEnd]))
- ++portEnd;
- return value.substring(portStart, portEnd - portStart).toUInt();
-}
-
-template <typename T>
-void URLUtils<T>::setHost(const String& value)
-{
- if (value.isEmpty())
- return;
- URL url = href();
- if (!url.canSetHostOrPort())
- return;
-
- size_t separator = value.find(':');
- if (!separator)
- return;
-
- if (separator == notFound)
- url.setHostAndPort(value);
- else {
- unsigned portEnd;
- unsigned port = parsePortFromStringPosition(value, separator + 1, portEnd);
- if (!port) {
- // http://dev.w3.org/html5/spec/infrastructure.html#url-decomposition-idl-attributes
- // specifically goes against RFC 3986 (p3.2) and
- // requires setting the port to "0" if it is set to empty string.
- url.setHostAndPort(value.substring(0, separator + 1) + '0');
- } else {
- if (isDefaultPortForProtocol(port, url.protocol()))
- url.setHostAndPort(value.substring(0, separator));
- else
- url.setHostAndPort(value.substring(0, portEnd));
- }
- }
- setHref(url.string());
-}
-
-template <typename T>
-String URLUtils<T>::hostname() const
-{
- return href().host();
-}
-
-template <typename T>
-void URLUtils<T>::setHostname(const String& value)
-{
- // Before setting new value:
- // Remove all leading U+002F SOLIDUS ("/") characters.
- unsigned i = 0;
- unsigned hostLength = value.length();
- while (value[i] == '/')
- i++;
-
- if (i == hostLength)
- return;
-
- URL url = href();
- if (!url.canSetHostOrPort())
- return;
-
- url.setHost(value.substring(i));
- setHref(url.string());
-}
-
-template <typename T>
-String URLUtils<T>::port() const
-{
- if (href().hasPort())
- return String::number(href().port());
-
- return emptyString();
-}
-
-template <typename T>
-void URLUtils<T>::setPort(const String& value)
-{
- URL url = href();
- if (!url.canSetHostOrPort())
- return;
-
- // http://dev.w3.org/html5/spec/infrastructure.html#url-decomposition-idl-attributes
- // specifically goes against RFC 3986 (p3.2) and
- // requires setting the port to "0" if it is set to empty string.
- // FIXME: http://url.spec.whatwg.org/ doesn't appear to require this; test what browsers do
- unsigned port = value.toUInt();
- if (isDefaultPortForProtocol(port, url.protocol()))
- url.removePort();
- else
- url.setPort(port);
-
- setHref(url.string());
-}
-
-template <typename T>
-String URLUtils<T>::pathname() const
-{
- return href().path();
-}
-
-template <typename T>
-void URLUtils<T>::setPathname(const String& value)
-{
- URL url = href();
- if (!url.canSetPathname())
- return;
-
- if (value[0] == '/')
- url.setPath(value);
- else
- url.setPath("/" + value);
-
- setHref(url.string());
-}
-
-template <typename T>
-String URLUtils<T>::search() const
-{
- String query = href().query();
- return query.isEmpty() ? emptyString() : "?" + query;
-}
-
-template <typename T>
-void URLUtils<T>::setSearch(const String& value)
-{
- URL url = href();
- String newSearch = (value[0] == '?') ? value.substring(1) : value;
- // Make sure that '#' in the query does not leak to the hash.
- url.setQuery(newSearch.replaceWithLiteral('#', "%23"));
-
- setHref(url.string());
-}
-
-template <typename T>
-String URLUtils<T>::hash() const
-{
- String fragmentIdentifier = href().fragmentIdentifier();
- if (fragmentIdentifier.isEmpty())
- return emptyString();
- return AtomicString(String("#" + fragmentIdentifier));
-}
-
-template <typename T>
-void URLUtils<T>::setHash(const String& value)
-{
- URL url = href();
- if (value[0] == '#')
- url.setFragmentIdentifier(value.substring(1));
- else
- url.setFragmentIdentifier(value);
- setHref(url.string());
-}
-
-} // namespace WebCore
-
-#endif // URLUtils_h
diff --git a/Source/WebCore/html/URLUtils.idl b/Source/WebCore/html/URLUtils.idl
deleted file mode 100644
index f8bac71ce..000000000
--- a/Source/WebCore/html/URLUtils.idl
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[NoInterfaceObject]
-interface URLUtils {
- [SetterRaisesException, URL] attribute DOMString href;
-#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
- [NotEnumerable] DOMString toString();
-#endif
-
- readonly attribute DOMString origin;
-
- [TreatNullAs=NullString] attribute DOMString protocol;
- [TreatNullAs=NullString] attribute DOMString username;
- [TreatNullAs=NullString] attribute DOMString password;
- [TreatNullAs=NullString] attribute DOMString host;
- [TreatNullAs=NullString] attribute DOMString hostname;
- [TreatNullAs=NullString] attribute DOMString port;
- [TreatNullAs=NullString] attribute DOMString pathname;
- [TreatNullAs=NullString] attribute DOMString search;
- // attribute URLSearchParams? searchParams;
- [TreatNullAs=NullString] attribute DOMString hash;
-};
diff --git a/Source/WebCore/html/ValidationMessage.cpp b/Source/WebCore/html/ValidationMessage.cpp
index f61e1b5ef..e00b19544 100644
--- a/Source/WebCore/html/ValidationMessage.cpp
+++ b/Source/WebCore/html/ValidationMessage.cpp
@@ -46,12 +46,13 @@
#include "StyleResolver.h"
#include "Text.h"
#include "ValidationMessageClient.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
using namespace HTMLNames;
-ValidationMessage::ValidationMessage(HTMLFormControlElement* element)
+ALWAYS_INLINE ValidationMessage::ValidationMessage(HTMLFormControlElement* element)
: m_element(element)
{
ASSERT(m_element);
@@ -67,6 +68,11 @@ ValidationMessage::~ValidationMessage()
deleteBubbleTree();
}
+OwnPtr<ValidationMessage> ValidationMessage::create(HTMLFormControlElement* element)
+{
+ return adoptPtr(new ValidationMessage(element));
+}
+
ValidationMessageClient* ValidationMessage::validationMessageClient() const
{
if (Page* page = m_element->document().page())
@@ -81,10 +87,10 @@ void ValidationMessage::updateValidationMessage(const String& message)
// HTML5 specification doesn't ask UA to show the title attribute value
// with the validationMessage. However, this behavior is same as Opera
// and the specification describes such behavior as an example.
- if (!updatedMessage.isEmpty()) {
- const AtomicString& title = m_element->fastGetAttribute(titleAttr);
- if (!title.isEmpty())
- updatedMessage = updatedMessage + '\n' + title;
+ const AtomicString& title = m_element->fastGetAttribute(titleAttr);
+ if (!updatedMessage.isEmpty() && !title.isEmpty()) {
+ updatedMessage.append('\n');
+ updatedMessage.append(title);
}
}
@@ -107,13 +113,13 @@ void ValidationMessage::setMessage(const String& message)
ASSERT(!message.isEmpty());
m_message = message;
if (!m_bubble)
- m_timer = std::make_unique<Timer>(*this, &ValidationMessage::buildBubbleTree);
+ m_timer = adoptPtr(new Timer<ValidationMessage>(this, &ValidationMessage::buildBubbleTree));
else
- m_timer = std::make_unique<Timer>(*this, &ValidationMessage::setMessageDOMAndStartTimer);
+ m_timer = adoptPtr(new Timer<ValidationMessage>(this, &ValidationMessage::setMessageDOMAndStartTimer));
m_timer->startOneShot(0);
}
-void ValidationMessage::setMessageDOMAndStartTimer()
+void ValidationMessage::setMessageDOMAndStartTimer(Timer<ValidationMessage>*)
{
ASSERT(!validationMessageClient());
ASSERT(m_messageHeading);
@@ -134,9 +140,9 @@ void ValidationMessage::setMessageDOMAndStartTimer()
int magnification = document.page() ? document.page()->settings().validationMessageTimerMagnification() : -1;
if (magnification <= 0)
- m_timer = nullptr;
+ m_timer.clear();
else {
- m_timer = std::make_unique<Timer>(*this, &ValidationMessage::deleteBubbleTree);
+ m_timer = adoptPtr(new Timer<ValidationMessage>(this, &ValidationMessage::deleteBubbleTree));
m_timer->startOneShot(std::max(5.0, static_cast<double>(m_message.length()) * magnification / 1000));
}
}
@@ -165,13 +171,9 @@ static void adjustBubblePosition(const LayoutRect& hostRect, HTMLElement* bubble
bubble->setInlineStyleProperty(CSSPropertyLeft, bubbleX, CSSPrimitiveValue::CSS_PX);
}
-void ValidationMessage::buildBubbleTree()
+void ValidationMessage::buildBubbleTree(Timer<ValidationMessage>*)
{
ASSERT(!validationMessageClient());
-
- if (!m_element->renderer())
- return;
-
ShadowRoot& shadowRoot = m_element->ensureUserAgentShadowRoot();
Document& document = m_element->document();
@@ -182,7 +184,7 @@ void ValidationMessage::buildBubbleTree()
m_bubble->setInlineStyleProperty(CSSPropertyPosition, CSSValueAbsolute);
shadowRoot.appendChild(m_bubble.get(), ASSERT_NO_EXCEPTION);
document.updateLayout();
- adjustBubblePosition(m_element->renderer()->absoluteBoundingBoxRect(), m_bubble.get());
+ adjustBubblePosition(m_element->boundingBox(), m_bubble.get());
RefPtr<HTMLDivElement> clipper = HTMLDivElement::create(document);
clipper->setPseudo(AtomicString("-webkit-validation-bubble-arrow-clipper", AtomicString::ConstructFromLiteral));
@@ -220,7 +222,7 @@ void ValidationMessage::requestToHideMessage()
}
// We must not modify the DOM tree in this context by the same reason as setMessage().
- m_timer = std::make_unique<Timer>(*this, &ValidationMessage::deleteBubbleTree);
+ m_timer = adoptPtr(new Timer<ValidationMessage>(this, &ValidationMessage::deleteBubbleTree));
m_timer->startOneShot(0);
}
@@ -231,14 +233,14 @@ bool ValidationMessage::shadowTreeContains(const Node& node) const
return &m_bubble->treeScope() == &node.treeScope();
}
-void ValidationMessage::deleteBubbleTree()
+void ValidationMessage::deleteBubbleTree(Timer<ValidationMessage>*)
{
ASSERT(!validationMessageClient());
if (m_bubble) {
- m_messageHeading = nullptr;
- m_messageBody = nullptr;
+ m_messageHeading = 0;
+ m_messageBody = 0;
m_element->userAgentShadowRoot()->removeChild(m_bubble.get(), ASSERT_NO_EXCEPTION);
- m_bubble = nullptr;
+ m_bubble = 0;
}
m_message = String();
}
diff --git a/Source/WebCore/html/ValidationMessage.h b/Source/WebCore/html/ValidationMessage.h
index 2820b2f9c..6aec40d23 100644
--- a/Source/WebCore/html/ValidationMessage.h
+++ b/Source/WebCore/html/ValidationMessage.h
@@ -32,8 +32,8 @@
#define ValidationMessage_h
#include "Timer.h"
-#include <memory>
#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/text/WTFString.h>
@@ -49,24 +49,24 @@ class ValidationMessageClient;
class ValidationMessage {
WTF_MAKE_NONCOPYABLE(ValidationMessage); WTF_MAKE_FAST_ALLOCATED;
public:
- explicit ValidationMessage(HTMLFormControlElement*);
+ static OwnPtr<ValidationMessage> create(HTMLFormControlElement*);
~ValidationMessage();
-
void updateValidationMessage(const String&);
void requestToHideMessage();
bool isVisible() const;
bool shadowTreeContains(const Node&) const;
private:
+ explicit ValidationMessage(HTMLFormControlElement*);
ValidationMessageClient* validationMessageClient() const;
void setMessage(const String&);
- void setMessageDOMAndStartTimer();
- void buildBubbleTree();
- void deleteBubbleTree();
+ void setMessageDOMAndStartTimer(Timer<ValidationMessage>* = 0);
+ void buildBubbleTree(Timer<ValidationMessage>*);
+ void deleteBubbleTree(Timer<ValidationMessage>* = 0);
HTMLFormControlElement* m_element;
String m_message;
- std::unique_ptr<Timer> m_timer;
+ OwnPtr<Timer<ValidationMessage>> m_timer;
RefPtr<HTMLElement> m_bubble;
RefPtr<HTMLElement> m_messageHeading;
RefPtr<HTMLElement> m_messageBody;
diff --git a/Source/WebCore/html/VoidCallback.h b/Source/WebCore/html/VoidCallback.h
index d5edc833d..3ee383f0f 100644
--- a/Source/WebCore/html/VoidCallback.h
+++ b/Source/WebCore/html/VoidCallback.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/VoidCallback.idl b/Source/WebCore/html/VoidCallback.idl
index 55fa18257..577fcf591 100644
--- a/Source/WebCore/html/VoidCallback.idl
+++ b/Source/WebCore/html/VoidCallback.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/WeekInputType.cpp b/Source/WebCore/html/WeekInputType.cpp
index 84ca988fb..5bee921d0 100644
--- a/Source/WebCore/html/WeekInputType.cpp
+++ b/Source/WebCore/html/WeekInputType.cpp
@@ -44,6 +44,11 @@ static const int weekDefaultStepBase = -259200000; // The first day of 1970-W01.
static const int weekDefaultStep = 1;
static const int weekStepScaleFactor = 604800000;
+void WeekInputType::attach()
+{
+ observeFeatureIfVisible(FeatureObserver::InputTypeWeek);
+}
+
const AtomicString& WeekInputType::formControlType() const
{
return InputTypeNames::week();
@@ -56,7 +61,7 @@ DateComponents::Type WeekInputType::dateType() const
StepRange WeekInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (weekDefaultStep, weekDefaultStepBase, weekStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger));
+ DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (weekDefaultStep, weekDefaultStepBase, weekStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger));
const Decimal stepBase = parseToNumber(element().fastGetAttribute(minAttr), weekDefaultStepBase);
const Decimal minimum = parseToNumber(element().fastGetAttribute(minAttr), Decimal::fromDouble(DateComponents::minimumWeek()));
diff --git a/Source/WebCore/html/WeekInputType.h b/Source/WebCore/html/WeekInputType.h
index 4ea6c56cb..8831f6d89 100644
--- a/Source/WebCore/html/WeekInputType.h
+++ b/Source/WebCore/html/WeekInputType.h
@@ -36,11 +36,12 @@
namespace WebCore {
-class WeekInputType final : public BaseChooserOnlyDateAndTimeInputType {
+class WeekInputType : public BaseChooserOnlyDateAndTimeInputType {
public:
explicit WeekInputType(HTMLInputElement& element) : BaseChooserOnlyDateAndTimeInputType(element) { }
private:
+ virtual void attach() override;
virtual const AtomicString& formControlType() const override;
virtual DateComponents::Type dateType() const override;
virtual StepRange createStepRange(AnyStepHandling) const override;
diff --git a/Source/WebCore/html/canvas/ANGLEInstancedArrays.cpp b/Source/WebCore/html/canvas/ANGLEInstancedArrays.cpp
index 45905e611..a0e573a5f 100644
--- a/Source/WebCore/html/canvas/ANGLEInstancedArrays.cpp
+++ b/Source/WebCore/html/canvas/ANGLEInstancedArrays.cpp
@@ -28,13 +28,9 @@
#if ENABLE(WEBGL)
#include "ANGLEInstancedArrays.h"
-#if PLATFORM(GTK)
-#include "Extensions3D.h"
-#endif
-
namespace WebCore {
-ANGLEInstancedArrays::ANGLEInstancedArrays(WebGLRenderingContextBase* context)
+ANGLEInstancedArrays::ANGLEInstancedArrays(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -48,16 +44,16 @@ WebGLExtension::ExtensionName ANGLEInstancedArrays::getName() const
return ANGLEInstancedArraysName;
}
-bool ANGLEInstancedArrays::supported(WebGLRenderingContextBase* context)
+OwnPtr<ANGLEInstancedArrays> ANGLEInstancedArrays::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new ANGLEInstancedArrays(context));
+}
+
+bool ANGLEInstancedArrays::supported(WebGLRenderingContext*)
{
-#if PLATFORM(COCOA)
- UNUSED_PARAM(context);
+#if PLATFORM(IOS) || PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
return true;
-#elif PLATFORM(GTK)
- Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
- return extensions->supports("GL_ANGLE_instanced_arrays");
#else
- UNUSED_PARAM(context);
return false;
#endif
}
diff --git a/Source/WebCore/html/canvas/ANGLEInstancedArrays.h b/Source/WebCore/html/canvas/ANGLEInstancedArrays.h
index 39bd2383c..f87126fbb 100644
--- a/Source/WebCore/html/canvas/ANGLEInstancedArrays.h
+++ b/Source/WebCore/html/canvas/ANGLEInstancedArrays.h
@@ -27,23 +27,26 @@
#define ANGLEInstancedArrays_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLRenderingContextBase;
+class WebGLRenderingContext;
-class ANGLEInstancedArrays final : public WebGLExtension {
+class ANGLEInstancedArrays : public WebGLExtension {
public:
- explicit ANGLEInstancedArrays(WebGLRenderingContextBase*);
+ static OwnPtr<ANGLEInstancedArrays> create(WebGLRenderingContext*);
virtual ~ANGLEInstancedArrays();
-
virtual ExtensionName getName() const;
- static bool supported(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContext*);
void drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
void drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount);
void vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor);
+
+private:
+ ANGLEInstancedArrays(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasGradient.cpp b/Source/WebCore/html/canvas/CanvasGradient.cpp
index 43adf3617..8a7ace0cf 100644
--- a/Source/WebCore/html/canvas/CanvasGradient.cpp
+++ b/Source/WebCore/html/canvas/CanvasGradient.cpp
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/CanvasGradient.h b/Source/WebCore/html/canvas/CanvasGradient.h
index 157a4ef0e..8529d584d 100644
--- a/Source/WebCore/html/canvas/CanvasGradient.h
+++ b/Source/WebCore/html/canvas/CanvasGradient.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -29,6 +29,7 @@
#include "Gradient.h"
#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -37,17 +38,16 @@ namespace WebCore {
class CanvasGradient : public RefCounted<CanvasGradient> {
public:
- static Ref<CanvasGradient> create(const FloatPoint& p0, const FloatPoint& p1)
+ static PassRefPtr<CanvasGradient> create(const FloatPoint& p0, const FloatPoint& p1)
{
- return adoptRef(*new CanvasGradient(p0, p1));
+ return adoptRef(new CanvasGradient(p0, p1));
}
- static Ref<CanvasGradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1)
+ static PassRefPtr<CanvasGradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1)
{
- return adoptRef(*new CanvasGradient(p0, r0, p1, r1));
+ return adoptRef(new CanvasGradient(p0, r0, p1, r1));
}
- Gradient& gradient() { return m_gradient; }
- const Gradient& gradient() const { return m_gradient; }
+ Gradient* gradient() const { return m_gradient.get(); }
void addColorStop(float value, const String& color, ExceptionCode&);
@@ -59,7 +59,7 @@ namespace WebCore {
CanvasGradient(const FloatPoint& p0, const FloatPoint& p1);
CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1);
- Ref<Gradient> m_gradient;
+ RefPtr<Gradient> m_gradient;
#if ENABLE(DASHBOARD_SUPPORT)
bool m_dashbardCompatibilityMode;
#endif
diff --git a/Source/WebCore/html/canvas/CanvasGradient.idl b/Source/WebCore/html/canvas/CanvasGradient.idl
index cd586679a..793be9275 100644
--- a/Source/WebCore/html/canvas/CanvasGradient.idl
+++ b/Source/WebCore/html/canvas/CanvasGradient.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/CanvasPathMethods.cpp b/Source/WebCore/html/canvas/CanvasPathMethods.cpp
index 28455dd3a..9332700e7 100644
--- a/Source/WebCore/html/canvas/CanvasPathMethods.cpp
+++ b/Source/WebCore/html/canvas/CanvasPathMethods.cpp
@@ -35,7 +35,6 @@
#include "config.h"
#include "CanvasPathMethods.h"
-#include "AffineTransform.h"
#include "ExceptionCode.h"
#include "FloatRect.h"
#include <wtf/MathExtras.h>
@@ -61,11 +60,6 @@ void CanvasPathMethods::moveTo(float x, float y)
m_path.moveTo(FloatPoint(x, y));
}
-void CanvasPathMethods::lineTo(FloatPoint point)
-{
- lineTo(point.x(), point.y());
-}
-
void CanvasPathMethods::lineTo(float x, float y)
{
if (!std::isfinite(x) || !std::isfinite(y))
@@ -136,91 +130,37 @@ void CanvasPathMethods::arcTo(float x1, float y1, float x2, float y2, float r, E
m_path.addArcTo(p1, p2, r);
}
-static void normalizeAngles(float& startAngle, float& endAngle, bool anticlockwise)
+void CanvasPathMethods::arc(float x, float y, float r, float sa, float ea, bool anticlockwise, ExceptionCode& ec)
{
- float newStartAngle = startAngle;
- if (newStartAngle < 0)
- newStartAngle = (2 * piFloat) + fmodf(newStartAngle, -(2 * piFloat));
- else
- newStartAngle = fmodf(newStartAngle, 2 * piFloat);
-
- float delta = newStartAngle - startAngle;
- startAngle = newStartAngle;
- endAngle = endAngle + delta;
- ASSERT(newStartAngle >= 0 && newStartAngle < 2 * piFloat);
-
- if (anticlockwise && startAngle - endAngle >= 2 * piFloat)
- endAngle = startAngle - 2 * piFloat;
- else if (!anticlockwise && endAngle - startAngle >= 2 * piFloat)
- endAngle = startAngle + 2 * piFloat;
-}
-
-void CanvasPathMethods::arc(float x, float y, float radius, float startAngle, float endAngle, bool anticlockwise, ExceptionCode& ec)
-{
- if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(radius) || !std::isfinite(startAngle) || !std::isfinite(endAngle))
+ ec = 0;
+ if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(r) || !std::isfinite(sa) || !std::isfinite(ea))
return;
- if (radius < 0) {
+ if (r < 0) {
ec = INDEX_SIZE_ERR;
return;
}
- if (!hasInvertibleTransform())
- return;
-
- normalizeAngles(startAngle, endAngle, anticlockwise);
-
- if (!radius || startAngle == endAngle) {
+ if (!r || sa == ea) {
// The arc is empty but we still need to draw the connecting line.
- lineTo(x + radius * cosf(startAngle), y + radius * sinf(startAngle));
- return;
- }
-
- m_path.addArc(FloatPoint(x, y), radius, startAngle, endAngle, anticlockwise);
-}
-
-void CanvasPathMethods::ellipse(float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, bool anticlockwise, ExceptionCode& ec)
-{
- if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(radiusX) || !std::isfinite(radiusY) || !std::isfinite(rotation) || !std::isfinite(startAngle) || !std::isfinite(endAngle))
- return;
-
- if (radiusX < 0 || radiusY < 0) {
- ec = INDEX_SIZE_ERR;
+ lineTo(x + r * cosf(sa), y + r * sinf(sa));
return;
}
if (!hasInvertibleTransform())
return;
- normalizeAngles(startAngle, endAngle, anticlockwise);
-
- if ((!radiusX && !radiusY) || startAngle == endAngle) {
- AffineTransform transform;
- transform.translate(x, y).rotate(rad2deg(rotation));
-
- lineTo(transform.mapPoint(FloatPoint(radiusX * cosf(startAngle), radiusY * sinf(startAngle))));
+ // If 'sa' and 'ea' differ by more than 2Pi, just add a circle starting/ending at 'sa'.
+ if (anticlockwise && sa - ea >= 2 * piFloat) {
+ m_path.addArc(FloatPoint(x, y), r, sa, sa - 2 * piFloat, anticlockwise);
return;
}
-
- if (!radiusX || !radiusY) {
- AffineTransform transform;
- transform.translate(x, y).rotate(rad2deg(rotation));
-
- lineTo(transform.mapPoint(FloatPoint(radiusX * cosf(startAngle), radiusY * sinf(startAngle))));
-
- if (!anticlockwise) {
- for (float angle = startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat; angle < endAngle; angle += piOverTwoFloat)
- lineTo(transform.mapPoint(FloatPoint(radiusX * cosf(angle), radiusY * sinf(angle))));
- } else {
- for (float angle = startAngle - fmodf(startAngle, piOverTwoFloat); angle > endAngle; angle -= piOverTwoFloat)
- lineTo(transform.mapPoint(FloatPoint(radiusX * cosf(angle), radiusY * sinf(angle))));
- }
-
- lineTo(transform.mapPoint(FloatPoint(radiusX * cosf(endAngle), radiusY * sinf(endAngle))));
+ if (!anticlockwise && ea - sa >= 2 * piFloat) {
+ m_path.addArc(FloatPoint(x, y), r, sa, sa + 2 * piFloat, anticlockwise);
return;
}
- m_path.addEllipse(FloatPoint(x, y), radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);
+ m_path.addArc(FloatPoint(x, y), r, sa, ea, anticlockwise);
}
void CanvasPathMethods::rect(float x, float y, float width, float height)
diff --git a/Source/WebCore/html/canvas/CanvasPathMethods.h b/Source/WebCore/html/canvas/CanvasPathMethods.h
index 88fc0cd36..041808df1 100644
--- a/Source/WebCore/html/canvas/CanvasPathMethods.h
+++ b/Source/WebCore/html/canvas/CanvasPathMethods.h
@@ -48,7 +48,6 @@ public:
void bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
void arcTo(float x0, float y0, float x1, float y1, float radius, ExceptionCode&);
void arc(float x, float y, float r, float sa, float ea, bool anticlockwise, ExceptionCode&);
- void ellipse(float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngled, bool anticlockwise, ExceptionCode&);
void rect(float x, float y, float width, float height);
protected:
@@ -57,8 +56,6 @@ protected:
virtual bool hasInvertibleTransform() const { return true; }
- void lineTo(FloatPoint);
-
Path m_path;
};
diff --git a/Source/WebCore/html/canvas/CanvasPattern.cpp b/Source/WebCore/html/canvas/CanvasPattern.cpp
index 77cdeb279..a4557418e 100644
--- a/Source/WebCore/html/canvas/CanvasPattern.cpp
+++ b/Source/WebCore/html/canvas/CanvasPattern.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -33,9 +33,9 @@
namespace WebCore {
-Ref<CanvasPattern> CanvasPattern::create(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
+PassRefPtr<CanvasPattern> CanvasPattern::create(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
{
- return adoptRef(*new CanvasPattern(image, repeatX, repeatY, originClean));
+ return adoptRef(new CanvasPattern(image, repeatX, repeatY, originClean));
}
CanvasPattern::CanvasPattern(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
diff --git a/Source/WebCore/html/canvas/CanvasPattern.h b/Source/WebCore/html/canvas/CanvasPattern.h
index c2a4c287c..9fed5759a 100644
--- a/Source/WebCore/html/canvas/CanvasPattern.h
+++ b/Source/WebCore/html/canvas/CanvasPattern.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,8 +28,8 @@
#include <wtf/Forward.h>
#include <wtf/PassRefPtr.h>
-#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
namespace WebCore {
@@ -40,20 +40,19 @@ typedef int ExceptionCode;
class CanvasPattern : public RefCounted<CanvasPattern> {
public:
- static Ref<CanvasPattern> create(PassRefPtr<Image>, bool repeatX, bool repeatY, bool originClean);
+ static PassRefPtr<CanvasPattern> create(PassRefPtr<Image>, bool repeatX, bool repeatY, bool originClean);
~CanvasPattern();
static void parseRepetitionType(const String&, bool& repeatX, bool& repeatY, ExceptionCode&);
- Pattern& pattern() { return m_pattern; }
- const Pattern& pattern() const { return m_pattern; }
+ Pattern* pattern() const { return m_pattern.get(); }
bool originClean() const { return m_originClean; }
private:
CanvasPattern(PassRefPtr<Image>, bool repeatX, bool repeatY, bool originClean);
- Ref<Pattern> m_pattern;
+ RefPtr<Pattern> m_pattern;
bool m_originClean;
};
diff --git a/Source/WebCore/html/canvas/CanvasPattern.idl b/Source/WebCore/html/canvas/CanvasPattern.idl
index 733d5511f..4ded936d7 100644
--- a/Source/WebCore/html/canvas/CanvasPattern.idl
+++ b/Source/WebCore/html/canvas/CanvasPattern.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/CanvasProxy.cpp b/Source/WebCore/html/canvas/CanvasProxy.cpp
index baf0a0846..3006ed65e 100644
--- a/Source/WebCore/html/canvas/CanvasProxy.cpp
+++ b/Source/WebCore/html/canvas/CanvasProxy.cpp
@@ -32,9 +32,9 @@
namespace WebCore {
-Ref<CanvasProxy> CanvasProxy::create()
+PassRefPtr<CanvasProxy> CanvasProxy::create()
{
- return adoptRef(*new CanvasProxy());
+ return adoptRef(new CanvasProxy());
}
CanvasProxy::CanvasProxy()
diff --git a/Source/WebCore/html/canvas/CanvasProxy.h b/Source/WebCore/html/canvas/CanvasProxy.h
index cbc4e7ff4..2591f0eb0 100644
--- a/Source/WebCore/html/canvas/CanvasProxy.h
+++ b/Source/WebCore/html/canvas/CanvasProxy.h
@@ -34,7 +34,7 @@ namespace WebCore {
class CanvasProxy : public RefCounted<CanvasProxy> {
public:
- static Ref<CanvasProxy> create();
+ static PassRefPtr<CanvasProxy> create();
virtual ~CanvasProxy();
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
index 2e588d2cb..e8bf03a90 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -64,7 +64,7 @@ bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* image)
if (!cachedImage->image()->hasSingleSecurityOrigin())
return true;
- return wouldTaintOrigin(cachedImage->responseForSameOriginPolicyChecks().url()) && !cachedImage->passesAccessControlCheck(*canvas()->securityOrigin());
+ return wouldTaintOrigin(cachedImage->response().url()) && !cachedImage->passesAccessControlCheck(canvas()->securityOrigin());
}
bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
@@ -92,7 +92,7 @@ bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
bool CanvasRenderingContext::wouldTaintOrigin(const URL& url)
{
- if (!canvas()->originClean())
+ if (!canvas()->originClean() || m_cleanURLs.contains(url.string()))
return false;
if (canvas()->securityOrigin()->taintsCanvas(url))
@@ -101,6 +101,7 @@ bool CanvasRenderingContext::wouldTaintOrigin(const URL& url)
if (url.protocolIsData())
return false;
+ m_cleanURLs.add(url.string());
return false;
}
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.h b/Source/WebCore/html/canvas/CanvasRenderingContext.h
index 51a21fe56..b5b2781f7 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.h
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -52,13 +52,14 @@ public:
HTMLCanvasElement* canvas() const { return m_canvas; }
virtual bool is2d() const { return false; }
- virtual bool isWebGL1() const { return false; }
- virtual bool isWebGL2() const { return false; }
- bool is3d() const { return isWebGL1() || isWebGL1(); }
+ virtual bool is3d() const { return false; }
virtual bool isAccelerated() const { return false; }
virtual void paintRenderingResultsToCanvas() {}
+
+#if USE(ACCELERATED_COMPOSITING)
virtual PlatformLayer* platformLayer() const { return 0; }
+#endif
protected:
CanvasRenderingContext(HTMLCanvasElement*);
@@ -77,6 +78,7 @@ protected:
private:
HTMLCanvasElement* m_canvas;
+ HashSet<String> m_cleanURLs;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.idl b/Source/WebCore/html/canvas/CanvasRenderingContext.idl
index 55cadc74e..6a68509cc 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.idl
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index 85a1faddd..18a87f4af 100644..100755
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -6,7 +6,7 @@
* Copyright (C) 2008 Dirk Schulze <krit@webkit.org>
* Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
* Copyright (C) 2012 Intel Corporation. All rights reserved.
- * Copyright (C) 2013, 2014 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -17,10 +17,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -42,14 +42,12 @@
#include "DOMPath.h"
#include "ExceptionCodePlaceholder.h"
#include "FloatQuad.h"
+#include "FontCache.h"
#include "GraphicsContext.h"
#include "HTMLImageElement.h"
#include "HTMLVideoElement.h"
#include "ImageData.h"
#include "RenderElement.h"
-#include "RenderImage.h"
-#include "RenderLayer.h"
-#include "RenderTheme.h"
#include "SecurityOrigin.h"
#include "StrokeStyleApplier.h"
#include "StyleProperties.h"
@@ -57,6 +55,10 @@
#include "TextMetrics.h"
#include "TextRun.h"
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayer.h"
+#endif
+
#include <wtf/CheckedArithmetic.h>
#include <wtf/MathExtras.h>
#include <wtf/text/StringBuilder.h>
@@ -175,13 +177,14 @@ CanvasRenderingContext2D::State::State()
, m_imageSmoothingEnabled(true)
, m_textAlign(StartTextAlign)
, m_textBaseline(AlphabeticTextBaseline)
- , m_direction(Direction::Inherit)
, m_unparsedFont(defaultFont)
+ , m_realizedFont(false)
{
}
CanvasRenderingContext2D::State::State(const State& other)
- : m_unparsedStrokeColor(other.m_unparsedStrokeColor)
+ : FontSelectorClient()
+ , m_unparsedStrokeColor(other.m_unparsedStrokeColor)
, m_unparsedFillColor(other.m_unparsedFillColor)
, m_strokeStyle(other.m_strokeStyle)
, m_fillStyle(other.m_fillStyle)
@@ -201,10 +204,12 @@ CanvasRenderingContext2D::State::State(const State& other)
, m_imageSmoothingEnabled(other.m_imageSmoothingEnabled)
, m_textAlign(other.m_textAlign)
, m_textBaseline(other.m_textBaseline)
- , m_direction(other.m_direction)
, m_unparsedFont(other.m_unparsedFont)
, m_font(other.m_font)
+ , m_realizedFont(other.m_realizedFont)
{
+ if (m_realizedFont)
+ m_font.fontSelector()->registerForInvalidationCallbacks(this);
}
CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(const State& other)
@@ -212,6 +217,9 @@ CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons
if (this == &other)
return *this;
+ if (m_realizedFont)
+ m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
+
m_unparsedStrokeColor = other.m_unparsedStrokeColor;
m_unparsedFillColor = other.m_unparsedFillColor;
m_strokeStyle = other.m_strokeStyle;
@@ -231,88 +239,28 @@ CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons
m_imageSmoothingEnabled = other.m_imageSmoothingEnabled;
m_textAlign = other.m_textAlign;
m_textBaseline = other.m_textBaseline;
- m_direction = other.m_direction;
m_unparsedFont = other.m_unparsedFont;
m_font = other.m_font;
+ m_realizedFont = other.m_realizedFont;
- return *this;
-}
-
-CanvasRenderingContext2D::FontProxy::~FontProxy()
-{
- if (realized())
- m_font.fontSelector()->unregisterForInvalidationCallbacks(*this);
-}
-
-CanvasRenderingContext2D::FontProxy::FontProxy(const FontProxy& other)
- : m_font(other.m_font)
-{
- if (realized())
- m_font.fontSelector()->registerForInvalidationCallbacks(*this);
-}
-
-auto CanvasRenderingContext2D::FontProxy::operator=(const FontProxy& other) -> FontProxy&
-{
- if (realized())
- m_font.fontSelector()->unregisterForInvalidationCallbacks(*this);
-
- m_font = other.m_font;
-
- if (realized())
- m_font.fontSelector()->registerForInvalidationCallbacks(*this);
+ if (m_realizedFont)
+ m_font.fontSelector()->registerForInvalidationCallbacks(this);
return *this;
}
-inline void CanvasRenderingContext2D::FontProxy::update(FontSelector& selector)
-{
- ASSERT(&selector == m_font.fontSelector()); // This is an invariant. We should only ever be registered for callbacks on m_font.m_fonts.m_fontSelector.
- if (realized())
- m_font.fontSelector()->unregisterForInvalidationCallbacks(*this);
- m_font.update(&selector);
- if (realized())
- m_font.fontSelector()->registerForInvalidationCallbacks(*this);
- ASSERT(&selector == m_font.fontSelector());
-}
-
-void CanvasRenderingContext2D::FontProxy::fontsNeedUpdate(FontSelector& selector)
-{
- ASSERT_ARG(selector, &selector == m_font.fontSelector());
- ASSERT(realized());
-
- update(selector);
-}
-
-inline void CanvasRenderingContext2D::FontProxy::initialize(FontSelector& fontSelector, RenderStyle& newStyle)
+CanvasRenderingContext2D::State::~State()
{
- // Beware! m_font.fontSelector() might not point to document.fontSelector()!
- ASSERT(newStyle.fontCascade().fontSelector() == &fontSelector);
- if (realized())
- m_font.fontSelector()->unregisterForInvalidationCallbacks(*this);
- m_font = newStyle.fontCascade();
- m_font.update(&fontSelector);
- ASSERT(&fontSelector == m_font.fontSelector());
- m_font.fontSelector()->registerForInvalidationCallbacks(*this);
+ if (m_realizedFont)
+ m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
}
-inline FontMetrics CanvasRenderingContext2D::FontProxy::fontMetrics() const
+void CanvasRenderingContext2D::State::fontsNeedUpdate(FontSelector* fontSelector)
{
- return m_font.fontMetrics();
-}
+ ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector());
+ ASSERT(m_realizedFont);
-inline const FontDescription& CanvasRenderingContext2D::FontProxy::fontDescription() const
-{
- return m_font.fontDescription();
-}
-
-inline float CanvasRenderingContext2D::FontProxy::width(const TextRun& textRun) const
-{
- return m_font.width(textRun);
-}
-
-inline void CanvasRenderingContext2D::FontProxy::drawBidiText(GraphicsContext& context, const TextRun& run, const FloatPoint& point, FontCascade::CustomFontNotReadyAction action) const
-{
- context.drawBidiText(m_font, run, point, action);
+ m_font.update(fontSelector);
}
void CanvasRenderingContext2D::realizeSavesLoop()
@@ -881,6 +829,22 @@ void CanvasRenderingContext2D::beginPath()
m_path.clear();
}
+#if ENABLE(CANVAS_PATH)
+
+PassRefPtr<DOMPath> CanvasRenderingContext2D::currentPath()
+{
+ return DOMPath::create(m_path);
+}
+
+void CanvasRenderingContext2D::setCurrentPath(DOMPath* path)
+{
+ if (!path)
+ return;
+ m_path = path->path();
+}
+
+#endif
+
static bool validateRectForCanvas(float& x, float& y, float& width, float& height)
{
if (!std::isfinite(x) | !std::isfinite(y) | !std::isfinite(width) | !std::isfinite(height))
@@ -932,48 +896,6 @@ static bool parseWinding(const String& windingRuleString, WindRule& windRule)
void CanvasRenderingContext2D::fill(const String& windingRuleString)
{
- fillInternal(m_path, windingRuleString);
-
-#if ENABLE(DASHBOARD_SUPPORT)
- clearPathForDashboardBackwardCompatibilityMode();
-#endif
-}
-
-void CanvasRenderingContext2D::stroke()
-{
- strokeInternal(m_path);
-
-#if ENABLE(DASHBOARD_SUPPORT)
- clearPathForDashboardBackwardCompatibilityMode();
-#endif
-}
-
-void CanvasRenderingContext2D::clip(const String& windingRuleString)
-{
- clipInternal(m_path, windingRuleString);
-
-#if ENABLE(DASHBOARD_SUPPORT)
- clearPathForDashboardBackwardCompatibilityMode();
-#endif
-}
-
-void CanvasRenderingContext2D::fill(DOMPath* path, const String& windingRuleString)
-{
- fillInternal(path->path(), windingRuleString);
-}
-
-void CanvasRenderingContext2D::stroke(DOMPath* path)
-{
- strokeInternal(path->path());
-}
-
-void CanvasRenderingContext2D::clip(DOMPath* path, const String& windingRuleString)
-{
- clipInternal(path->path(), windingRuleString);
-}
-
-void CanvasRenderingContext2D::fillInternal(const Path& path, const String& windingRuleString)
-{
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -985,7 +907,7 @@ void CanvasRenderingContext2D::fillInternal(const Path& path, const String& wind
if (gradient && gradient->isZeroSize())
return;
- if (!path.isEmpty()) {
+ if (!m_path.isEmpty()) {
WindRule windRule = c->fillRule();
WindRule newWindRule = RULE_NONZERO;
if (!parseWinding(windingRuleString, newWindRule))
@@ -993,24 +915,26 @@ void CanvasRenderingContext2D::fillInternal(const Path& path, const String& wind
c->setFillRule(newWindRule);
if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- beginCompositeLayer();
- c->fillPath(path);
- endCompositeLayer();
+ fullCanvasCompositedFill(m_path);
didDrawEntireCanvas();
} else if (state().m_globalComposite == CompositeCopy) {
clearCanvas();
- c->fillPath(path);
+ c->fillPath(m_path);
didDrawEntireCanvas();
} else {
- c->fillPath(path);
- didDraw(path.fastBoundingRect());
+ c->fillPath(m_path);
+ didDraw(m_path.fastBoundingRect());
}
c->setFillRule(windRule);
}
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ clearPathForDashboardBackwardCompatibilityMode();
+#endif
}
-void CanvasRenderingContext2D::strokeInternal(const Path& path)
+void CanvasRenderingContext2D::stroke()
{
GraphicsContext* c = drawingContext();
if (!c)
@@ -1023,26 +947,20 @@ void CanvasRenderingContext2D::strokeInternal(const Path& path)
if (gradient && gradient->isZeroSize())
return;
- if (!path.isEmpty()) {
- if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- beginCompositeLayer();
- c->strokePath(path);
- endCompositeLayer();
- didDrawEntireCanvas();
- } else if (state().m_globalComposite == CompositeCopy) {
- clearCanvas();
- c->strokePath(path);
- didDrawEntireCanvas();
- } else {
- FloatRect dirtyRect = path.fastBoundingRect();
- inflateStrokeRect(dirtyRect);
- c->strokePath(path);
- didDraw(dirtyRect);
- }
+ if (!m_path.isEmpty()) {
+ FloatRect dirtyRect = m_path.fastBoundingRect();
+ inflateStrokeRect(dirtyRect);
+
+ c->strokePath(m_path);
+ didDraw(dirtyRect);
}
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ clearPathForDashboardBackwardCompatibilityMode();
+#endif
}
-void CanvasRenderingContext2D::clipInternal(const Path& path, const String& windingRuleString)
+void CanvasRenderingContext2D::clip(const String& windingRuleString)
{
GraphicsContext* c = drawingContext();
if (!c)
@@ -1055,45 +973,15 @@ void CanvasRenderingContext2D::clipInternal(const Path& path, const String& wind
return;
realizeSaves();
- c->canvasClip(path, newWindRule);
-}
-
-inline void CanvasRenderingContext2D::beginCompositeLayer()
-{
-#if !USE(CAIRO)
- drawingContext()->beginTransparencyLayer(1);
-#endif
-}
-
-inline void CanvasRenderingContext2D::endCompositeLayer()
-{
-#if !USE(CAIRO)
- drawingContext()->endTransparencyLayer();
+ c->canvasClip(m_path, newWindRule);
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ clearPathForDashboardBackwardCompatibilityMode();
#endif
}
bool CanvasRenderingContext2D::isPointInPath(const float x, const float y, const String& windingRuleString)
{
- return isPointInPathInternal(m_path, x, y, windingRuleString);
-}
-
-bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y)
-{
- return isPointInStrokeInternal(m_path, x, y);
-}
-
-bool CanvasRenderingContext2D::isPointInPath(DOMPath* path, const float x, const float y, const String& windingRuleString)
-{
- return isPointInPathInternal(path->path(), x, y, windingRuleString);
-}
-
-bool CanvasRenderingContext2D::isPointInStroke(DOMPath* path, const float x, const float y)
-{
- return isPointInStrokeInternal(path->path(), x, y);
-}
-
-bool CanvasRenderingContext2D::isPointInPathInternal(const Path& path, float x, float y, const String& windingRuleString)
-{
GraphicsContext* c = drawingContext();
if (!c)
return false;
@@ -1110,10 +998,11 @@ bool CanvasRenderingContext2D::isPointInPathInternal(const Path& path, float x,
if (!parseWinding(windingRuleString, windRule))
return false;
- return path.contains(transformedPoint, windRule);
+ return m_path.contains(transformedPoint, windRule);
}
-bool CanvasRenderingContext2D::isPointInStrokeInternal(const Path& path, float x, float y)
+
+bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y)
{
GraphicsContext* c = drawingContext();
if (!c)
@@ -1128,7 +1017,7 @@ bool CanvasRenderingContext2D::isPointInStrokeInternal(const Path& path, float x
return false;
CanvasStrokeStyleApplier applier(this);
- return path.strokeContains(&applier, transformedPoint);
+ return m_path.strokeContains(&applier, transformedPoint);
}
void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height)
@@ -1192,9 +1081,7 @@ void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei
c->fillRect(rect);
didDrawEntireCanvas();
} else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- beginCompositeLayer();
- c->fillRect(rect);
- endCompositeLayer();
+ fullCanvasCompositedFill(rect);
didDrawEntireCanvas();
} else if (state().m_globalComposite == CompositeCopy) {
clearCanvas();
@@ -1225,21 +1112,12 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
return;
FloatRect rect(x, y, width, height);
- if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- beginCompositeLayer();
- c->strokeRect(rect, state().m_lineWidth);
- endCompositeLayer();
- didDrawEntireCanvas();
- } else if (state().m_globalComposite == CompositeCopy) {
- clearCanvas();
- c->strokeRect(rect, state().m_lineWidth);
- didDrawEntireCanvas();
- } else {
- FloatRect boundingRect = rect;
- boundingRect.inflate(state().m_lineWidth / 2);
- c->strokeRect(rect, state().m_lineWidth);
- didDraw(boundingRect);
- }
+
+ FloatRect boundingRect = rect;
+ boundingRect.inflate(state().m_lineWidth / 2);
+
+ c->strokeRect(rect, state().m_lineWidth);
+ didDraw(boundingRect);
}
void CanvasRenderingContext2D::setShadow(float width, float height, float blur)
@@ -1321,29 +1199,19 @@ bool CanvasRenderingContext2D::shouldDrawShadows() const
return alphaChannel(state().m_shadowColor) && (state().m_shadowBlur || !state().m_shadowOffset.isZero());
}
-enum ImageSizeType {
- ImageSizeAfterDevicePixelRatio,
- ImageSizeBeforeDevicePixelRatio
-};
-
-static LayoutSize size(HTMLImageElement* image, ImageSizeType sizeType)
+static LayoutSize size(HTMLImageElement* image)
{
- LayoutSize size;
- if (CachedImage* cachedImage = image->cachedImage()) {
- size = cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FIXME: Not sure about this.
-
- if (sizeType == ImageSizeAfterDevicePixelRatio && is<RenderImage>(image->renderer()) && cachedImage->image() && !cachedImage->image()->hasRelativeWidth())
- size.scale(downcast<RenderImage>(*image->renderer()).imageDevicePixelRatio());
- }
- return size;
+ if (CachedImage* cachedImage = image->cachedImage())
+ return cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FIXME: Not sure about this.
+ return IntSize();
}
#if ENABLE(VIDEO)
-static FloatSize size(HTMLVideoElement* video)
+static IntSize size(HTMLVideoElement* video)
{
if (MediaPlayer* player = video->player())
return player->naturalSize();
- return FloatSize();
+ return IntSize();
}
#endif
@@ -1361,8 +1229,8 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float
ec = TYPE_MISMATCH_ERR;
return;
}
- LayoutSize destRectSize = size(image, ImageSizeAfterDevicePixelRatio);
- drawImage(image, x, y, destRectSize.width(), destRectSize.height(), ec);
+ LayoutSize s = size(image);
+ drawImage(image, x, y, s.width(), s.height(), ec);
}
void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
@@ -1372,8 +1240,8 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
ec = TYPE_MISMATCH_ERR;
return;
}
- LayoutSize sourceRectSize = size(image, ImageSizeBeforeDevicePixelRatio);
- drawImage(image, FloatRect(0, 0, sourceRectSize.width(), sourceRectSize.height()), FloatRect(x, y, width, height), ec);
+ LayoutSize s = size(image);
+ drawImage(image, FloatRect(0, 0, s.width(), s.height()), FloatRect(x, y, width, height), ec);
}
void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
@@ -1410,7 +1278,7 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec
FloatRect normalizedSrcRect = normalizeRect(srcRect);
FloatRect normalizedDstRect = normalizeRect(dstRect);
- FloatRect imageRect = FloatRect(FloatPoint(), size(image, ImageSizeBeforeDevicePixelRatio));
+ FloatRect imageRect = FloatRect(FloatPoint(), size(image));
if (!srcRect.width() || !srcRect.height()) {
ec = INDEX_SIZE_ERR;
return;
@@ -1428,22 +1296,22 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec
if (!cachedImage)
return;
+ checkOrigin(image);
+
if (rectContainsCanvas(normalizedDstRect)) {
- c->drawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, ImagePaintingOptions(op, blendMode));
+ c->drawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, op, blendMode, ImageOrientationDescription());
didDrawEntireCanvas();
} else if (isFullCanvasCompositeMode(op)) {
fullCanvasCompositedDrawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, op);
didDrawEntireCanvas();
} else if (op == CompositeCopy) {
clearCanvas();
- c->drawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, ImagePaintingOptions(op, blendMode));
+ c->drawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, op, blendMode, ImageOrientationDescription());
didDrawEntireCanvas();
} else {
- c->drawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, ImagePaintingOptions(op, blendMode));
+ c->drawImage(cachedImage->imageForRenderer(image->renderer()), ColorSpaceDeviceRGB, normalizedDstRect, normalizedSrcRect, op, blendMode, ImageOrientationDescription());
didDraw(normalizedDstRect);
}
-
- checkOrigin(image);
}
void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, float x, float y, ExceptionCode& ec)
@@ -1514,17 +1382,17 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const
#endif
if (rectContainsCanvas(dstRect)) {
- c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, ImagePaintingOptions(state().m_globalComposite, state().m_globalBlend));
+ c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend);
didDrawEntireCanvas();
} else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
fullCanvasCompositedDrawImage(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, state().m_globalComposite);
didDrawEntireCanvas();
} else if (state().m_globalComposite == CompositeCopy) {
clearCanvas();
- c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, ImagePaintingOptions(state().m_globalComposite, state().m_globalBlend));
+ c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend);
didDrawEntireCanvas();
} else {
- c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, ImagePaintingOptions(state().m_globalComposite, state().m_globalBlend));
+ c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, dstRect, srcRect, state().m_globalComposite, state().m_globalBlend);
didDraw(dstRect);
}
}
@@ -1536,8 +1404,8 @@ void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, float x, float
ec = TYPE_MISMATCH_ERR;
return;
}
- FloatSize videoSize = size(video);
- drawImage(video, x, y, videoSize.width(), videoSize.height(), ec);
+ IntSize s = size(video);
+ drawImage(video, x, y, s.width(), s.height(), ec);
}
void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
@@ -1547,8 +1415,8 @@ void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
ec = TYPE_MISMATCH_ERR;
return;
}
- FloatSize videoSize = size(video);
- drawImage(video, FloatRect(0, 0, videoSize.width(), videoSize.height()), FloatRect(x, y, width, height), ec);
+ IntSize s = size(video);
+ drawImage(video, FloatRect(0, 0, s.width(), s.height()), FloatRect(x, y, width, height), ec);
}
void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
@@ -1605,7 +1473,7 @@ void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRec
c->translate(dstRect.x(), dstRect.y());
c->scale(FloatSize(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height()));
c->translate(-srcRect.x(), -srcRect.y());
- video->paintCurrentFrameInContext(c, FloatRect(FloatPoint(), size(video)));
+ video->paintCurrentFrameInContext(c, IntRect(IntPoint(), size(video)));
stateSaver.restore();
didDraw(dstRect);
}
@@ -1684,7 +1552,8 @@ template<class T> IntRect CanvasRenderingContext2D::calculateCompositingBufferRe
std::unique_ptr<ImageBuffer> CanvasRenderingContext2D::createCompositingBuffer(const IntRect& bufferRect)
{
- return ImageBuffer::create(bufferRect.size(), isAccelerated() ? Accelerated : Unaccelerated);
+ RenderingMode renderMode = isAccelerated() ? Accelerated : Unaccelerated;
+ return ImageBuffer::create(bufferRect.size(), 1, ColorSpaceDeviceRGB, renderMode);
}
void CanvasRenderingContext2D::compositeBuffer(ImageBuffer* buffer, const IntRect& bufferRect, CompositeOperator op)
@@ -1704,13 +1573,14 @@ void CanvasRenderingContext2D::compositeBuffer(ImageBuffer* buffer, const IntRec
c->clipOut(bufferRect);
c->clearRect(canvasRect);
c->restore();
+
c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, bufferRect.location(), state().m_globalComposite);
c->restore();
}
static void drawImageToContext(Image* image, GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
{
- context->drawImage(image, styleColorSpace, dest, src, op);
+ context->drawImage(image, styleColorSpace, dest, src, op, ImageOrientationDescription());
}
static void drawImageToContext(ImageBuffer* imageBuffer, GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
@@ -1749,92 +1619,110 @@ template<class T> void CanvasRenderingContext2D::fullCanvasCompositedDrawImage(
compositeBuffer(buffer.get(), bufferRect, op);
}
-void CanvasRenderingContext2D::prepareGradientForDashboard(CanvasGradient& gradient) const
+template<class T> void CanvasRenderingContext2D::fullCanvasCompositedFill(const T& area)
+{
+ ASSERT(isFullCanvasCompositeMode(state().m_globalComposite));
+
+ IntRect bufferRect = calculateCompositingBufferRect(area, 0);
+ if (bufferRect.isEmpty()) {
+ clearCanvas();
+ return;
+ }
+
+ std::unique_ptr<ImageBuffer> buffer = createCompositingBuffer(bufferRect);
+ if (!buffer)
+ return;
+
+ Path path = transformAreaToDevice(area);
+ path.translate(FloatSize(-bufferRect.x(), -bufferRect.y()));
+
+ buffer->context()->setCompositeOperation(CompositeSourceOver);
+ modifiableState().m_fillStyle.applyFillColor(buffer->context());
+ buffer->context()->fillPath(path);
+
+ compositeBuffer(buffer.get(), bufferRect, state().m_globalComposite);
+}
+
+void CanvasRenderingContext2D::prepareGradientForDashboard(CanvasGradient* gradient) const
{
#if ENABLE(DASHBOARD_SUPPORT)
if (m_usesDashboardCompatibilityMode)
- gradient.setDashboardCompatibilityMode();
+ gradient->setDashboardCompatibilityMode();
#else
UNUSED_PARAM(gradient);
#endif
}
-RefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode& ec)
+PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode& ec)
{
if (!std::isfinite(x0) || !std::isfinite(y0) || !std::isfinite(x1) || !std::isfinite(y1)) {
ec = NOT_SUPPORTED_ERR;
- return nullptr;
+ return 0;
}
- Ref<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
+ RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
prepareGradientForDashboard(gradient.get());
- return WTF::move(gradient);
+ return gradient.release();
}
-RefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode& ec)
+PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode& ec)
{
if (!std::isfinite(x0) || !std::isfinite(y0) || !std::isfinite(r0) || !std::isfinite(x1) || !std::isfinite(y1) || !std::isfinite(r1)) {
ec = NOT_SUPPORTED_ERR;
- return nullptr;
+ return 0;
}
if (r0 < 0 || r1 < 0) {
ec = INDEX_SIZE_ERR;
- return nullptr;
+ return 0;
}
- Ref<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
+ RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
prepareGradientForDashboard(gradient.get());
- return WTF::move(gradient);
+ return gradient.release();
}
-RefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageElement* image,
+PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageElement* image,
const String& repetitionType, ExceptionCode& ec)
{
if (!image) {
ec = TYPE_MISMATCH_ERR;
- return nullptr;
+ return 0;
}
bool repeatX, repeatY;
ec = 0;
CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, ec);
if (ec)
- return nullptr;
+ return 0;
- CachedImage* cachedImage = image->cachedImage();
- // If the image loading hasn't started or the image is not complete, it is not fully decodable.
- if (!cachedImage || !image->complete())
- return nullptr;
-
- if (cachedImage->status() == CachedResource::LoadError) {
- ec = INVALID_STATE_ERR;
- return nullptr;
- }
+ if (!image->complete())
+ return 0;
- if (!image->cachedImage()->imageForRenderer(image->renderer()))
+ CachedImage* cachedImage = image->cachedImage();
+ if (!cachedImage || !image->cachedImage()->imageForRenderer(image->renderer()))
return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
bool originClean = cachedImage->isOriginClean(canvas()->securityOrigin());
return CanvasPattern::create(cachedImage->imageForRenderer(image->renderer()), repeatX, repeatY, originClean);
}
-RefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElement* canvas,
+PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElement* canvas,
const String& repetitionType, ExceptionCode& ec)
{
if (!canvas) {
ec = TYPE_MISMATCH_ERR;
- return nullptr;
+ return 0;
}
- if (!canvas->width() || !canvas->height() || !canvas->buffer()) {
+ if (!canvas->width() || !canvas->height()) {
ec = INVALID_STATE_ERR;
- return nullptr;
+ return 0;
}
bool repeatX, repeatY;
ec = 0;
CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, ec);
if (ec)
- return nullptr;
+ return 0;
return CanvasPattern::create(canvas->copiedImage(), repeatX, repeatY, canvas->originClean());
}
@@ -1851,7 +1739,7 @@ void CanvasRenderingContext2D::didDraw(const FloatRect& r, unsigned options)
if (!state().m_hasInvertibleTransform)
return;
-#if ENABLE(ACCELERATED_2D_CANVAS)
+#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
// If we are drawing to hardware and we have a composited layer, just call contentChanged().
if (isAccelerated()) {
RenderBox* renderBox = canvas()->renderBox();
@@ -1892,41 +1780,53 @@ GraphicsContext* CanvasRenderingContext2D::drawingContext() const
return canvas()->drawingContext();
}
-static RefPtr<ImageData> createEmptyImageData(const IntSize& size)
+static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size)
{
- if (RefPtr<ImageData> data = ImageData::create(size)) {
- data->data()->zeroFill();
- return data;
- }
+ Checked<int, RecordOverflow> dataSize = 4;
+ dataSize *= size.width();
+ dataSize *= size.height();
+ if (dataSize.hasOverflowed())
+ return 0;
- return nullptr;
+ RefPtr<ImageData> data = ImageData::create(size);
+ data->data()->zeroFill();
+ return data.release();
}
-RefPtr<ImageData> CanvasRenderingContext2D::createImageData(RefPtr<ImageData>&& imageData, ExceptionCode& ec) const
+PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(PassRefPtr<ImageData> imageData, ExceptionCode& ec) const
{
if (!imageData) {
ec = NOT_SUPPORTED_ERR;
- return nullptr;
+ return 0;
}
return createEmptyImageData(imageData->size());
}
-RefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh, ExceptionCode& ec) const
+PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh, ExceptionCode& ec) const
{
ec = 0;
if (!sw || !sh) {
ec = INDEX_SIZE_ERR;
- return nullptr;
+ return 0;
}
if (!std::isfinite(sw) || !std::isfinite(sh)) {
- ec = TypeError;
- return nullptr;
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+
+#if PLATFORM(IOS)
+ // If the canvas element was created before Document had a Frame,
+ // then no maximumDecodedImageSize was set.
+ if (!canvas()->maximumDecodedImageSize()) {
+ if (Settings* settings = canvas()->document().settings())
+ canvas()->setMaximumDecodedImageSize(settings->maximumDecodedImageSize());
}
+#endif
FloatSize logicalSize(fabs(sw), fabs(sh));
if (!logicalSize.isExpressibleAsIntSize())
- return nullptr;
+ return 0;
IntSize size = expandedIntSize(logicalSize);
if (size.width() < 1)
@@ -1937,32 +1837,32 @@ RefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh,
return createEmptyImageData(size);
}
-RefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh, ExceptionCode& ec) const
+PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh, ExceptionCode& ec) const
{
return getImageData(ImageBuffer::LogicalCoordinateSystem, sx, sy, sw, sh, ec);
}
-RefPtr<ImageData> CanvasRenderingContext2D::webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionCode& ec) const
+PassRefPtr<ImageData> CanvasRenderingContext2D::webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionCode& ec) const
{
return getImageData(ImageBuffer::BackingStoreCoordinateSystem, sx, sy, sw, sh, ec);
}
-RefPtr<ImageData> CanvasRenderingContext2D::getImageData(ImageBuffer::CoordinateSystem coordinateSystem, float sx, float sy, float sw, float sh, ExceptionCode& ec) const
+PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(ImageBuffer::CoordinateSystem coordinateSystem, float sx, float sy, float sw, float sh, ExceptionCode& ec) const
{
if (!canvas()->originClean()) {
- DEPRECATED_DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Unable to get image data from canvas because the canvas has been tainted by cross-origin data.")));
- canvas()->document().addConsoleMessage(MessageSource::Security, MessageLevel::Error, consoleMessage);
+ DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Unable to get image data from canvas because the canvas has been tainted by cross-origin data.")));
+ canvas()->document().addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, consoleMessage);
ec = SECURITY_ERR;
- return nullptr;
+ return 0;
}
if (!sw || !sh) {
ec = INDEX_SIZE_ERR;
- return nullptr;
+ return 0;
}
if (!std::isfinite(sx) || !std::isfinite(sy) || !std::isfinite(sw) || !std::isfinite(sh)) {
ec = NOT_SUPPORTED_ERR;
- return nullptr;
+ return 0;
}
if (sw < 0) {
@@ -1974,13 +1874,22 @@ RefPtr<ImageData> CanvasRenderingContext2D::getImageData(ImageBuffer::Coordinate
sh = -sh;
}
+#if PLATFORM(IOS)
+ // If the canvas element was created before Document had a Frame,
+ // then no maximumDecodedImageSize was set.
+ if (!canvas()->maximumDecodedImageSize()) {
+ if (Settings* settings = canvas()->document().settings())
+ canvas()->setMaximumDecodedImageSize(settings->maximumDecodedImageSize());
+ }
+#endif
+
FloatRect logicalRect(sx, sy, sw, sh);
if (logicalRect.width() < 1)
logicalRect.setWidth(1);
if (logicalRect.height() < 1)
logicalRect.setHeight(1);
if (!logicalRect.isExpressibleAsIntRect())
- return nullptr;
+ return 0;
IntRect imageDataRect = enclosingIntRect(logicalRect);
ImageBuffer* buffer = canvas()->buffer();
@@ -1989,7 +1898,7 @@ RefPtr<ImageData> CanvasRenderingContext2D::getImageData(ImageBuffer::Coordinate
RefPtr<Uint8ClampedArray> byteArray = buffer->getUnmultipliedImageData(imageDataRect, coordinateSystem);
if (!byteArray)
- return nullptr;
+ return 0;
return ImageData::create(imageDataRect.size(), byteArray.release());
}
@@ -2023,27 +1932,6 @@ void CanvasRenderingContext2D::webkitPutImageDataHD(ImageData* data, float dx, f
putImageData(data, ImageBuffer::BackingStoreCoordinateSystem, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight, ec);
}
-void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element)
-{
- drawFocusIfNeededInternal(m_path, element);
-}
-
-void CanvasRenderingContext2D::drawFocusIfNeeded(DOMPath* path, Element* element)
-{
- drawFocusIfNeededInternal(path->path(), element);
-}
-
-void CanvasRenderingContext2D::drawFocusIfNeededInternal(const Path& path, Element* element)
-{
- GraphicsContext* context = drawingContext();
-
- if (!element || !element->focused() || !state().m_hasInvertibleTransform || path.isEmpty()
- || !element->isDescendantOf(canvas()) || !context)
- return;
-
- context->drawFocusRing(path, 1, 1, RenderTheme::focusRingColor());
-}
-
void CanvasRenderingContext2D::putImageData(ImageData* data, ImageBuffer::CoordinateSystem coordinateSystem, float dx, float dy, float dirtyX, float dirtyY,
float dirtyWidth, float dirtyHeight, ExceptionCode& ec)
{
@@ -2083,12 +1971,17 @@ void CanvasRenderingContext2D::putImageData(ImageData* data, ImageBuffer::Coordi
buffer->putByteArray(Unmultiplied, data->data(), IntSize(data->width(), data->height()), sourceRect, IntPoint(destOffset), coordinateSystem);
+ if (coordinateSystem == ImageBuffer::BackingStoreCoordinateSystem) {
+ FloatRect dirtyRect = destRect;
+ dirtyRect.scale(1 / canvas()->deviceScaleFactor());
+ destRect = enclosingIntRect(dirtyRect);
+ }
didDraw(destRect, CanvasDidDrawApplyNone); // ignore transform, shadow and clip
}
String CanvasRenderingContext2D::font() const
{
- if (!state().m_font.realized())
+ if (!state().m_realizedFont)
return defaultFont;
StringBuilder serializedFont;
@@ -2102,11 +1995,11 @@ String CanvasRenderingContext2D::font() const
serializedFont.appendNumber(fontDescription.computedPixelSize());
serializedFont.appendLiteral("px");
- for (unsigned i = 0; i < fontDescription.familyCount(); ++i) {
+ for (unsigned i = 0; i < state().m_font.familyCount(); ++i) {
if (i)
serializedFont.append(',');
// FIXME: We should append family directly to serializedFont rather than building a temporary string.
- String family = fontDescription.familyAt(i);
+ String family = state().m_font.familyAt(i);
if (family.startsWith("-webkit-"))
family = family.substring(8);
if (family.contains(' '))
@@ -2121,11 +2014,11 @@ String CanvasRenderingContext2D::font() const
void CanvasRenderingContext2D::setFont(const String& newFont)
{
- if (newFont == state().m_unparsedFont && state().m_font.realized())
+ if (newFont == state().m_unparsedFont && state().m_realizedFont)
return;
RefPtr<MutableStyleProperties> parsedStyle = MutableStyleProperties::create();
- CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, newFont, true, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode), nullptr);
+ CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, newFont, true, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode), 0);
if (parsedStyle->isEmpty())
return;
@@ -2143,11 +2036,7 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
// Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
// relative to the canvas.
- Ref<RenderStyle> newStyle = RenderStyle::create();
-
- Document& document = canvas()->document();
- document.updateStyleIfNeeded();
-
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
if (RenderStyle* computedStyle = canvas()->computedStyle())
newStyle->setFontDescription(computedStyle->fontDescription());
else {
@@ -2159,11 +2048,11 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
newStyle->setFontDescription(defaultFontDescription);
}
- newStyle->fontCascade().update(&document.fontSelector());
+ newStyle->font().update(newStyle->font().fontSelector());
// Now map the font property longhands into the style.
StyleResolver& styleResolver = canvas()->document().ensureStyleResolver();
- styleResolver.applyPropertyToStyle(CSSPropertyFontFamily, parsedStyle->getPropertyCSSValue(CSSPropertyFontFamily).get(), &newStyle.get());
+ styleResolver.applyPropertyToStyle(CSSPropertyFontFamily, parsedStyle->getPropertyCSSValue(CSSPropertyFontFamily).get(), newStyle.get());
styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontStyle, parsedStyle->getPropertyCSSValue(CSSPropertyFontStyle).get());
styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontVariant, parsedStyle->getPropertyCSSValue(CSSPropertyFontVariant).get());
styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontWeight, parsedStyle->getPropertyCSSValue(CSSPropertyFontWeight).get());
@@ -2176,7 +2065,10 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
styleResolver.updateFont();
styleResolver.applyPropertyToCurrentStyle(CSSPropertyLineHeight, parsedStyle->getPropertyCSSValue(CSSPropertyLineHeight).get());
- modifiableState().m_font.initialize(document.fontSelector(), newStyle);
+ modifiableState().m_font = newStyle->font();
+ modifiableState().m_font.update(styleResolver.fontSelector());
+ modifiableState().m_realizedFont = true;
+ styleResolver.fontSelector()->registerForInvalidationCallbacks(&modifiableState());
}
String CanvasRenderingContext2D::textAlign() const
@@ -2211,49 +2103,6 @@ void CanvasRenderingContext2D::setTextBaseline(const String& s)
modifiableState().m_textBaseline = baseline;
}
-inline TextDirection CanvasRenderingContext2D::toTextDirection(Direction direction, RenderStyle** computedStyle) const
-{
- RenderStyle* style = (computedStyle || direction == Direction::Inherit) ? canvas()->computedStyle() : nullptr;
- if (computedStyle)
- *computedStyle = style;
- switch (direction) {
- case Direction::Inherit:
- return style ? style->direction() : LTR;
- case Direction::RTL:
- return RTL;
- case Direction::LTR:
- return LTR;
- }
- ASSERT_NOT_REACHED();
- return LTR;
-}
-
-String CanvasRenderingContext2D::direction() const
-{
- if (state().m_direction == Direction::Inherit)
- canvas()->document().updateStyleIfNeeded();
- return toTextDirection(state().m_direction) == RTL ? ASCIILiteral("rtl") : ASCIILiteral("ltr");
-}
-
-void CanvasRenderingContext2D::setDirection(const String& directionString)
-{
- Direction direction;
- if (directionString == "inherit")
- direction = Direction::Inherit;
- else if (directionString == "rtl")
- direction = Direction::RTL;
- else if (directionString == "ltr")
- direction = Direction::LTR;
- else
- return;
-
- if (state().m_direction == direction)
- return;
-
- realizeSaves();
- modifiableState().m_direction = direction;
-}
-
void CanvasRenderingContext2D::fillText(const String& text, float x, float y)
{
drawTextInternal(text, x, y, true);
@@ -2294,7 +2143,7 @@ static void normalizeSpaces(String& text)
unsigned textLength = text.length();
Vector<UChar> charVector(textLength);
- StringView(text).getCharactersWithUpconvert(charVector.data());
+ memcpy(charVector.data(), text.deprecatedCharacters(), textLength * sizeof(UChar));
charVector[i++] = ' ';
@@ -2305,16 +2154,18 @@ static void normalizeSpaces(String& text)
text = String::adopt(charVector);
}
-Ref<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
+PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
{
- Ref<TextMetrics> metrics = TextMetrics::create();
+ FontCachePurgePreventer fontCachePurgePreventer;
+
+ RefPtr<TextMetrics> metrics = TextMetrics::create();
String normalizedText = text;
normalizeSpaces(normalizedText);
- metrics->setWidth(fontProxy().width(TextRun(normalizedText)));
+ metrics->setWidth(accessFont().width(TextRun(normalizedText)));
- return metrics;
+ return metrics.release();
}
void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth, bool useMaxWidth)
@@ -2338,21 +2189,22 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
if (fill && gradient && gradient->isZeroSize())
return;
- const auto& fontProxy = this->fontProxy();
- const FontMetrics& fontMetrics = fontProxy.fontMetrics();
+ FontCachePurgePreventer fontCachePurgePreventer;
+
+ const Font& font = accessFont();
+ const FontMetrics& fontMetrics = font.fontMetrics();
String normalizedText = text;
normalizeSpaces(normalizedText);
// FIXME: Need to turn off font smoothing.
- RenderStyle* computedStyle;
- canvas()->document().updateStyleIfNeeded();
- TextDirection direction = toTextDirection(state().m_direction, &computedStyle);
+ RenderStyle* computedStyle = canvas()->computedStyle();
+ TextDirection direction = computedStyle ? computedStyle->direction() : LTR;
bool isRTL = direction == RTL;
bool override = computedStyle ? isOverride(computedStyle->unicodeBidi()) : false;
- TextRun textRun(normalizedText, 0, 0, AllowTrailingExpansion, direction, override, true, TextRun::NoRounding);
+ TextRun textRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direction, override, true, TextRun::NoRounding);
// Draw the item text at the correct point.
FloatPoint location(x, y);
switch (state().m_textBaseline) {
@@ -2373,7 +2225,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
break;
}
- float fontWidth = fontProxy.width(TextRun(normalizedText, 0, 0, AllowTrailingExpansion, direction, override));
+ float fontWidth = font.width(TextRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direction, override));
useMaxWidth = (useMaxWidth && maxWidth < fontWidth);
float width = useMaxWidth ? maxWidth : fontWidth;
@@ -2404,40 +2256,8 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
#if USE(CG)
const CanvasStyle& drawStyle = fill ? state().m_fillStyle : state().m_strokeStyle;
if (drawStyle.canvasGradient() || drawStyle.canvasPattern()) {
-
IntRect maskRect = enclosingIntRect(textRect);
- // If we have a shadow, we need to draw it before the mask operation.
- // Follow a procedure similar to paintTextWithShadows in TextPainter.
-
- if (shouldDrawShadows()) {
- GraphicsContextStateSaver stateSaver(*c);
-
- FloatSize offset = FloatSize(0, 2 * maskRect.height());
-
- FloatSize shadowOffset;
- float shadowRadius;
- Color shadowColor;
- ColorSpace shadowColorSpace;
- c->getShadow(shadowOffset, shadowRadius, shadowColor, shadowColorSpace);
-
- FloatRect shadowRect(maskRect);
- shadowRect.inflate(shadowRadius * 1.4);
- shadowRect.move(shadowOffset * -1);
- c->clip(shadowRect);
-
- shadowOffset += offset;
-
- c->setLegacyShadow(shadowOffset, shadowRadius, shadowColor, shadowColorSpace);
-
- if (fill)
- c->setFillColor(Color::black, ColorSpaceDeviceRGB);
- else
- c->setStrokeColor(Color::black, ColorSpaceDeviceRGB);
-
- fontProxy.drawBidiText(*c, textRun, location + offset, FontCascade::UseFallbackIfFontNotReady);
- }
-
std::unique_ptr<ImageBuffer> maskImage = c->createCompatibleBuffer(maskRect.size());
GraphicsContext* maskImageContext = maskImage->context();
@@ -2455,10 +2275,10 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
maskImageContext->translate(location.x() - maskRect.x(), location.y() - maskRect.y());
// We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work.
maskImageContext->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1));
- fontProxy.drawBidiText(maskImageContext, textRun, FloatPoint(0, 0), FontCascade::UseFallbackIfFontNotReady);
+ maskImageContext->drawBidiText(font, textRun, FloatPoint(0, 0), Font::UseFallbackIfFontNotReady);
} else {
maskImageContext->translate(-maskRect.x(), -maskRect.y());
- fontProxy.drawBidiText(maskImageContext, textRun, location, FontCascade::UseFallbackIfFontNotReady);
+ maskImageContext->drawBidiText(font, textRun, location, Font::UseFallbackIfFontNotReady);
}
GraphicsContextStateSaver stateSaver(*c);
@@ -2471,27 +2291,16 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
c->setTextDrawingMode(fill ? TextModeFill : TextModeStroke);
- GraphicsContextStateSaver stateSaver(*c);
if (useMaxWidth) {
+ GraphicsContextStateSaver stateSaver(*c);
c->translate(location.x(), location.y());
// We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work.
c->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1));
- location = FloatPoint();
- }
+ c->drawBidiText(font, textRun, FloatPoint(0, 0), Font::UseFallbackIfFontNotReady);
+ } else
+ c->drawBidiText(font, textRun, location, Font::UseFallbackIfFontNotReady);
- if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- beginCompositeLayer();
- fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady);
- endCompositeLayer();
- didDrawEntireCanvas();
- } else if (state().m_globalComposite == CompositeCopy) {
- clearCanvas();
- fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady);
- didDrawEntireCanvas();
- } else {
- fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady);
- didDraw(textRect);
- }
+ didDraw(textRect);
}
void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const
@@ -2509,28 +2318,28 @@ void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const
rect.inflate(delta);
}
-auto CanvasRenderingContext2D::fontProxy() -> const FontProxy&
+const Font& CanvasRenderingContext2D::accessFont()
{
canvas()->document().updateStyleIfNeeded();
- if (!state().m_font.realized())
+ if (!state().m_realizedFont)
setFont(state().m_unparsedFont);
return state().m_font;
}
-#if ENABLE(ACCELERATED_2D_CANVAS)
+#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
PlatformLayer* CanvasRenderingContext2D::platformLayer() const
{
return canvas()->buffer() ? canvas()->buffer()->platformLayer() : 0;
}
#endif
-bool CanvasRenderingContext2D::imageSmoothingEnabled() const
+bool CanvasRenderingContext2D::webkitImageSmoothingEnabled() const
{
return state().m_imageSmoothingEnabled;
}
-void CanvasRenderingContext2D::setImageSmoothingEnabled(bool enabled)
+void CanvasRenderingContext2D::setWebkitImageSmoothingEnabled(bool enabled)
{
if (enabled == state().m_imageSmoothingEnabled)
return;
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.h b/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
index 61567fea1..27b7e33c8 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -33,15 +33,17 @@
#include "Color.h"
#include "ColorSpace.h"
#include "FloatSize.h"
-#include "FontCascade.h"
+#include "Font.h"
#include "GraphicsTypes.h"
#include "ImageBuffer.h"
#include "Path.h"
-#include "PlatformLayer.h"
-#include "TextFlags.h"
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
+#if USE(ACCELERATED_COMPOSITING)
+#include "PlatformLayer.h"
+#endif
+
namespace WebCore {
class CanvasGradient;
@@ -57,9 +59,12 @@ class TextMetrics;
typedef int ExceptionCode;
-class CanvasRenderingContext2D final : public CanvasRenderingContext, public CanvasPathMethods {
+class CanvasRenderingContext2D : public CanvasRenderingContext, public CanvasPathMethods {
public:
- CanvasRenderingContext2D(HTMLCanvasElement*, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode);
+ static OwnPtr<CanvasRenderingContext2D> create(HTMLCanvasElement* canvas, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode)
+ {
+ return adoptPtr(new CanvasRenderingContext2D(canvas, usesCSSCompatibilityParseMode, usesDashboardCompatibilityMode));
+ }
virtual ~CanvasRenderingContext2D();
const CanvasStyle& strokeStyle() const { return state().m_strokeStyle; }
@@ -132,20 +137,18 @@ public:
void beginPath();
- void fill(const String& winding = ASCIILiteral("nonzero"));
- void stroke();
- void clip(const String& winding = ASCIILiteral("nonzero"));
+#if ENABLE(CANVAS_PATH)
+ PassRefPtr<DOMPath> currentPath();
+ void setCurrentPath(DOMPath*);
+#endif
- void fill(DOMPath*, const String& winding = ASCIILiteral("nonzero"));
- void stroke(DOMPath*);
- void clip(DOMPath*, const String& winding = ASCIILiteral("nonzero"));
+ void fill(const String& winding = "nonzero");
+ void stroke();
+ void clip(const String& winding = "nonzero");
- bool isPointInPath(const float x, const float y, const String& winding = ASCIILiteral("nonzero"));
+ bool isPointInPath(const float x, const float y, const String& winding = "nonzero");
bool isPointInStroke(const float x, const float y);
- bool isPointInPath(DOMPath*, const float x, const float y, const String& winding = ASCIILiteral("nonzero"));
- bool isPointInStroke(DOMPath*, const float x, const float y);
-
void clearRect(float x, float y, float width, float height);
void fillRect(float x, float y, float width, float height);
void strokeRect(float x, float y, float width, float height);
@@ -183,24 +186,21 @@ public:
void setCompositeOperation(const String&);
- RefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode&);
- RefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode&);
- RefPtr<CanvasPattern> createPattern(HTMLImageElement*, const String& repetitionType, ExceptionCode&);
- RefPtr<CanvasPattern> createPattern(HTMLCanvasElement*, const String& repetitionType, ExceptionCode&);
+ PassRefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode&);
+ PassRefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode&);
+ PassRefPtr<CanvasPattern> createPattern(HTMLImageElement*, const String& repetitionType, ExceptionCode&);
+ PassRefPtr<CanvasPattern> createPattern(HTMLCanvasElement*, const String& repetitionType, ExceptionCode&);
- RefPtr<ImageData> createImageData(RefPtr<ImageData>&&, ExceptionCode&) const;
- RefPtr<ImageData> createImageData(float width, float height, ExceptionCode&) const;
- RefPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionCode&) const;
- RefPtr<ImageData> webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionCode&) const;
+ PassRefPtr<ImageData> createImageData(PassRefPtr<ImageData>, ExceptionCode&) const;
+ PassRefPtr<ImageData> createImageData(float width, float height, ExceptionCode&) const;
+ PassRefPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionCode&) const;
+ PassRefPtr<ImageData> webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionCode&) const;
void putImageData(ImageData*, float dx, float dy, ExceptionCode&);
void putImageData(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
void webkitPutImageDataHD(ImageData*, float dx, float dy, ExceptionCode&);
void webkitPutImageDataHD(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
- void drawFocusIfNeeded(Element*);
- void drawFocusIfNeeded(DOMPath*, Element*);
-
- float webkitBackingStorePixelRatio() const { return 1; }
+ float webkitBackingStorePixelRatio() const { return canvas()->deviceScaleFactor(); }
void reset();
@@ -213,55 +213,28 @@ public:
String textBaseline() const;
void setTextBaseline(const String&);
- String direction() const;
- void setDirection(const String&);
-
void fillText(const String& text, float x, float y);
void fillText(const String& text, float x, float y, float maxWidth);
void strokeText(const String& text, float x, float y);
void strokeText(const String& text, float x, float y, float maxWidth);
- Ref<TextMetrics> measureText(const String& text);
+ PassRefPtr<TextMetrics> measureText(const String& text);
LineCap getLineCap() const { return state().m_lineCap; }
LineJoin getLineJoin() const { return state().m_lineJoin; }
- bool imageSmoothingEnabled() const;
- void setImageSmoothingEnabled(bool);
+ bool webkitImageSmoothingEnabled() const;
+ void setWebkitImageSmoothingEnabled(bool);
private:
- enum class Direction {
- Inherit,
- RTL,
- LTR
- };
-
- class FontProxy : public FontSelectorClient {
- public:
- FontProxy() = default;
- virtual ~FontProxy();
- FontProxy(const FontProxy&);
- FontProxy& operator=(const FontProxy&);
-
- bool realized() const { return m_font.fontSelector(); }
- void initialize(FontSelector&, RenderStyle&);
- FontMetrics fontMetrics() const;
- const FontDescription& fontDescription() const;
- float width(const TextRun&) const;
- void drawBidiText(GraphicsContext&, const TextRun&, const FloatPoint&, FontCascade::CustomFontNotReadyAction) const;
-
- private:
- void update(FontSelector&);
- virtual void fontsNeedUpdate(FontSelector&) override;
-
- FontCascade m_font;
- };
-
- struct State final {
+ struct State : FontSelectorClient {
State();
+ virtual ~State();
State(const State&);
State& operator=(const State&);
+ virtual void fontsNeedUpdate(FontSelector*) override;
+
String m_unparsedStrokeColor;
String m_unparsedFillColor;
CanvasStyle m_strokeStyle;
@@ -285,10 +258,10 @@ private:
// Text state.
TextAlign m_textAlign;
TextBaseline m_textBaseline;
- Direction m_direction;
String m_unparsedFont;
- FontProxy m_font;
+ Font m_font;
+ bool m_realizedFont;
};
enum CanvasDidDrawOption {
@@ -299,6 +272,8 @@ private:
CanvasDidDrawApplyAll = 0xffffffff
};
+ CanvasRenderingContext2D(HTMLCanvasElement*, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode);
+
State& modifiableState() { ASSERT(!m_unrealizedSaveCount); return m_stateStack.last(); }
const State& state() const { return m_stateStack.last(); }
@@ -325,26 +300,12 @@ private:
void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
- // The relationship between FontCascade and CanvasRenderingContext2D::FontProxy must hold certain invariants.
- // Therefore, all font operations must pass through the State.
- const FontProxy& fontProxy();
+ const Font& accessFont();
#if ENABLE(DASHBOARD_SUPPORT)
void clearPathForDashboardBackwardCompatibilityMode();
#endif
- void beginCompositeLayer();
- void endCompositeLayer();
-
- void fillInternal(const Path&, const String& winding);
- void strokeInternal(const Path&);
- void clipInternal(const Path&, const String& winding);
-
- bool isPointInPathInternal(const Path&, float x, float y, const String& winding);
- bool isPointInStrokeInternal(const Path&, float x, float y);
-
- void drawFocusIfNeededInternal(const Path&, Element*);
-
void clearCanvas();
Path transformAreaToDevice(const Path&) const;
Path transformAreaToDevice(const FloatRect&) const;
@@ -356,20 +317,20 @@ private:
void inflateStrokeRect(FloatRect&) const;
+ template<class T> void fullCanvasCompositedFill(const T&);
template<class T> void fullCanvasCompositedDrawImage(T*, ColorSpace, const FloatRect&, const FloatRect&, CompositeOperator);
- void prepareGradientForDashboard(CanvasGradient& gradient) const;
+ void prepareGradientForDashboard(CanvasGradient* gradient) const;
- RefPtr<ImageData> getImageData(ImageBuffer::CoordinateSystem, float sx, float sy, float sw, float sh, ExceptionCode&) const;
+ PassRefPtr<ImageData> getImageData(ImageBuffer::CoordinateSystem, float sx, float sy, float sw, float sh, ExceptionCode&) const;
void putImageData(ImageData*, ImageBuffer::CoordinateSystem, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
virtual bool is2d() const override { return true; }
virtual bool isAccelerated() const override;
virtual bool hasInvertibleTransform() const override { return state().m_hasInvertibleTransform; }
- TextDirection toTextDirection(Direction, RenderStyle** computedStyle = nullptr) const;
-#if ENABLE(ACCELERATED_2D_CANVAS)
+#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
virtual PlatformLayer* platformLayer() const override;
#endif
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl b/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
index b2c032cc5..ffac89618 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,136 +30,117 @@ interface CanvasRenderingContext2D : CanvasRenderingContext {
void save();
void restore();
- void scale(unrestricted float sx, unrestricted float sy);
- void rotate(unrestricted float angle);
- void translate(unrestricted float tx, unrestricted float ty);
- void transform(unrestricted float m11, unrestricted float m12, unrestricted float m21, unrestricted float m22,
- unrestricted float dx, unrestricted float dy);
- void setTransform(unrestricted float m11, unrestricted float m12, unrestricted float m21, unrestricted float m22,
- unrestricted float dx, unrestricted float dy);
+ void scale(float sx, float sy);
+ void rotate(float angle);
+ void translate(float tx, float ty);
+ void transform(float m11, float m12, float m21, float m22, float dx, float dy);
+ void setTransform(float m11, float m12, float m21, float m22, float dx, float dy);
- attribute unrestricted float globalAlpha;
+ attribute float globalAlpha;
[TreatNullAs=NullString] attribute DOMString globalCompositeOperation;
[RaisesException] CanvasGradient createLinearGradient(float x0, float y0, float x1, float y1);
[RaisesException] CanvasGradient createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1);
- attribute unrestricted float lineWidth;
+ attribute float lineWidth;
[TreatNullAs=NullString] attribute DOMString lineCap;
[TreatNullAs=NullString] attribute DOMString lineJoin;
- attribute unrestricted float miterLimit;
+ attribute float miterLimit;
- attribute unrestricted float shadowOffsetX;
- attribute unrestricted float shadowOffsetY;
- attribute unrestricted float shadowBlur;
+ attribute float shadowOffsetX;
+ attribute float shadowOffsetY;
+ attribute float shadowBlur;
[TreatNullAs=NullString] attribute DOMString shadowColor;
- void setLineDash(sequence<unrestricted float> dash);
- sequence<unrestricted float> getLineDash();
- attribute unrestricted float lineDashOffset;
+ void setLineDash(sequence<float> dash);
+ sequence<float> getLineDash();
+ attribute float lineDashOffset;
[Custom] attribute Array webkitLineDash;
- attribute unrestricted float webkitLineDashOffset;
+ attribute float webkitLineDashOffset;
- void clearRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
- void fillRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ void clearRect(float x, float y, float width, float height);
+ void fillRect(float x, float y, float width, float height);
void beginPath();
+#if defined(ENABLE_CANVAS_PATH) && ENABLE_CANVAS_PATH
+ attribute DOMPath currentPath;
+#endif
+
// FIXME: These methods should be shared with CanvasRenderingContext2D in the CanvasPathMethods interface.
void closePath();
- void moveTo(unrestricted float x, unrestricted float y);
- void lineTo(unrestricted float x, unrestricted float y);
- void quadraticCurveTo(unrestricted float cpx, unrestricted float cpy, unrestricted float x, unrestricted float y);
- void bezierCurveTo(unrestricted float cp1x, unrestricted float cp1y, unrestricted float cp2x, unrestricted float cp2y,
- unrestricted float x, unrestricted float y);
- [RaisesException] void arcTo(unrestricted float x1, unrestricted float y1, unrestricted float x2, unrestricted float y2,
- unrestricted float radius);
- void rect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
- [RaisesException] void arc(unrestricted float x, unrestricted float y, unrestricted float radius, unrestricted float startAngle,
- unrestricted float endAngle, [Default=Undefined] optional boolean anticlockwise);
- [RaisesException] void ellipse(unrestricted float x, unrestricted float y, unrestricted float radiusX, unrestricted float radiusY, unrestricted float rotation, unrestricted float startAngle, unrestricted float endAngle, [Default=Undefined] optional boolean anticlockwise);
-
- void fill(DOMPath path, optional CanvasWindingRule winding);
- void stroke(DOMPath path);
- void clip(DOMPath path, optional CanvasWindingRule winding);
+ void moveTo(float x, float y);
+ void lineTo(float x, float y);
+ void quadraticCurveTo(float cpx, float cpy, float x, float y);
+ void bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
+ [RaisesException] void arcTo(float x1, float y1, float x2, float y2, float radius);
+ void rect(float x, float y, float width, float height);
+ [RaisesException] void arc(float x, float y, float radius, float startAngle, float endAngle, [Default=Undefined] optional boolean anticlockwise);
void fill(optional CanvasWindingRule winding);
void stroke();
void clip(optional CanvasWindingRule winding);
-
- boolean isPointInPath(DOMPath path, unrestricted float x, unrestricted float y, optional CanvasWindingRule winding);
- boolean isPointInStroke(DOMPath path, unrestricted float x, unrestricted float y);
-
- boolean isPointInPath(unrestricted float x, unrestricted float y, optional CanvasWindingRule winding);
- boolean isPointInStroke(unrestricted float x, unrestricted float y);
+ boolean isPointInPath(float x, float y, optional CanvasWindingRule winding);
+ boolean isPointInStroke(float x, float y);
// text
attribute DOMString font;
attribute DOMString textAlign;
attribute DOMString textBaseline;
- attribute DOMString direction;
TextMetrics measureText(DOMString text);
// other
- void setAlpha([Default=Undefined] optional unrestricted float alpha);
+ void setAlpha([Default=Undefined] optional float alpha);
void setCompositeOperation([Default=Undefined] optional DOMString compositeOperation);
- void setLineWidth([Default=Undefined] optional unrestricted float width);
+#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
+ void setLineWidth([Default=Undefined] optional float width);
void setLineCap([Default=Undefined] optional DOMString cap);
void setLineJoin([Default=Undefined] optional DOMString join);
- void setMiterLimit([Default=Undefined] optional unrestricted float limit);
+ void setMiterLimit([Default=Undefined] optional float limit);
+#endif
void clearShadow();
- void fillText(DOMString text, unrestricted float x, unrestricted float y, optional unrestricted float maxWidth);
- void strokeText(DOMString text, unrestricted float x, unrestricted float y, optional unrestricted float maxWidth);
-
- void setStrokeColor([StrictTypeChecking] DOMString color, optional unrestricted float alpha);
- void setStrokeColor(unrestricted float grayLevel, optional float alpha);
- void setStrokeColor(unrestricted float r, unrestricted float g, unrestricted float b, unrestricted float a);
- void setStrokeColor(unrestricted float c, unrestricted float m, unrestricted float y, unrestricted float k, unrestricted float a);
-
- void setFillColor([StrictTypeChecking] DOMString color, optional unrestricted float alpha);
- void setFillColor(unrestricted float grayLevel, optional unrestricted float alpha);
- void setFillColor(unrestricted float r, unrestricted float g, unrestricted float b, unrestricted float a);
- void setFillColor(unrestricted float c, unrestricted float m, unrestricted float y, unrestricted float k, unrestricted float a);
-
- void strokeRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
-
- [RaisesException] void drawImage(HTMLImageElement? image, unrestricted float x, unrestricted float y);
- [RaisesException] void drawImage(HTMLImageElement? image, unrestricted float x, unrestricted float y,
- unrestricted float width, unrestricted float height);
- [RaisesException] void drawImage(HTMLImageElement? image, unrestricted float sx, unrestricted float sy, unrestricted float sw,
- unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);
- [RaisesException] void drawImage(HTMLCanvasElement? canvas, unrestricted float x, unrestricted float y);
- [RaisesException] void drawImage(HTMLCanvasElement? canvas, unrestricted float x, unrestricted float y,
- unrestricted float width, unrestricted float height);
- [RaisesException] void drawImage(HTMLCanvasElement? canvas, unrestricted float sx, unrestricted float sy, unrestricted float sw,
- unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);
+ void fillText(DOMString text, float x, float y, optional float maxWidth);
+ void strokeText(DOMString text, float x, float y, optional float maxWidth);
+
+ void setStrokeColor([StrictTypeChecking] DOMString color, optional float alpha);
+ void setStrokeColor(float grayLevel, optional float alpha);
+ void setStrokeColor(float r, float g, float b, float a);
+ void setStrokeColor(float c, float m, float y, float k, float a);
+
+ void setFillColor([StrictTypeChecking] DOMString color, optional float alpha);
+ void setFillColor(float grayLevel, optional float alpha);
+ void setFillColor(float r, float g, float b, float a);
+ void setFillColor(float c, float m, float y, float k, float a);
+
+ void strokeRect(float x, float y, float width, float height);
+
+ [RaisesException] void drawImage(HTMLImageElement? image, float x, float y);
+ [RaisesException] void drawImage(HTMLImageElement? image, float x, float y, float width, float height);
+ [RaisesException] void drawImage(HTMLImageElement? image, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
+ [RaisesException] void drawImage(HTMLCanvasElement? canvas, float x, float y);
+ [RaisesException] void drawImage(HTMLCanvasElement? canvas, float x, float y, float width, float height);
+ [RaisesException] void drawImage(HTMLCanvasElement? canvas, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
- [RaisesException] void drawImage(HTMLVideoElement? video, unrestricted float x, unrestricted float y);
- [RaisesException] void drawImage(HTMLVideoElement? video, unrestricted float x, unrestricted float y,
- unrestricted float width, unrestricted float height);
- [RaisesException] void drawImage(HTMLVideoElement? video, unrestricted float sx, unrestricted float sy, unrestricted float sw,
- unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);
+ [RaisesException] void drawImage(HTMLVideoElement? video, float x, float y);
+ [RaisesException] void drawImage(HTMLVideoElement? video, float x, float y, float width, float height);
+ [RaisesException] void drawImage(HTMLVideoElement? video, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
#endif
void drawImageFromRect(HTMLImageElement image,
- optional unrestricted float sx, optional unrestricted float sy, optional unrestricted float sw, optional unrestricted float sh,
- optional unrestricted float dx, optional unrestricted float dy, optional unrestricted float dw, optional unrestricted float dh,
- optional DOMString compositeOperation);
-
- void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur,
- [StrictTypeChecking] optional DOMString color, optional unrestricted float alpha);
- void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur, unrestricted float grayLevel,
- optional unrestricted float alpha);
- void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur, unrestricted float r,
- unrestricted float g, unrestricted float b, unrestricted float a);
- void setShadow(float width, unrestricted float height, unrestricted float blur, unrestricted float c, unrestricted float m,
- unrestricted float y, unrestricted float k, unrestricted float a);
+ optional float sx, optional float sy, optional float sw, optional float sh,
+ optional float dx, optional float dy, optional float dw, optional float dh,
+ optional DOMString compositeOperation);
+
+ void setShadow(float width, float height, float blur, [StrictTypeChecking] optional DOMString color, optional float alpha);
+ void setShadow(float width, float height, float blur, float grayLevel, optional float alpha);
+ void setShadow(float width, float height, float blur, float r, float g, float b, float a);
+ void setShadow(float width, float height, float blur, float c, float m, float y, float k, float a);
[RaisesException] void putImageData(ImageData? imagedata, float dx, float dy);
[RaisesException] void putImageData(ImageData? imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
@@ -179,14 +160,9 @@ interface CanvasRenderingContext2D : CanvasRenderingContext {
[RaisesException] ImageData getImageData(float sx, float sy, float sw, float sh);
[RaisesException] ImageData webkitGetImageDataHD(float sx, float sy, float sw, float sh);
-
- // Focus rings
- void drawFocusIfNeeded(Element element);
- void drawFocusIfNeeded(DOMPath path, Element element);
readonly attribute float webkitBackingStorePixelRatio;
- attribute boolean imageSmoothingEnabled;
- [ImplementedAs=imageSmoothingEnabled] attribute boolean webkitImageSmoothingEnabled;
+ attribute boolean webkitImageSmoothingEnabled;
};
diff --git a/Source/WebCore/html/canvas/CanvasStyle.cpp b/Source/WebCore/html/canvas/CanvasStyle.cpp
index d358a2179..8b0883951 100644
--- a/Source/WebCore/html/canvas/CanvasStyle.cpp
+++ b/Source/WebCore/html/canvas/CanvasStyle.cpp
@@ -13,10 +13,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/CanvasStyle.h b/Source/WebCore/html/canvas/CanvasStyle.h
index 9beb16269..a5d3e5166 100644
--- a/Source/WebCore/html/canvas/CanvasStyle.h
+++ b/Source/WebCore/html/canvas/CanvasStyle.h
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/DOMPath.cpp b/Source/WebCore/html/canvas/DOMPath.cpp
deleted file mode 100644
index d51b78ada..000000000
--- a/Source/WebCore/html/canvas/DOMPath.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "DOMPath.h"
-
-namespace WebCore {
-
-DOMPath::~DOMPath()
-{
-}
-
-}
diff --git a/Source/WebCore/html/canvas/DOMPath.h b/Source/WebCore/html/canvas/DOMPath.h
index 64aa46c30..6358e4602 100644
--- a/Source/WebCore/html/canvas/DOMPath.h
+++ b/Source/WebCore/html/canvas/DOMPath.h
@@ -28,37 +28,32 @@
#ifndef DOMPath_h
#define DOMPath_h
+#if ENABLE(CANVAS_PATH)
+
#include "CanvasPathMethods.h"
-#include "SVGMatrix.h"
-#include "SVGPathUtilities.h"
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
+#if ENABLE(SVG)
+#include "SVGPathUtilities.h"
+#endif
+
namespace WebCore {
-class WEBCORE_EXPORT DOMPath final : public RefCounted<DOMPath>, public CanvasPathMethods {
+class DOMPath : public RefCounted<DOMPath>, public CanvasPathMethods {
WTF_MAKE_FAST_ALLOCATED;
public:
- virtual ~DOMPath();
-
- static Ref<DOMPath> create() { return adoptRef(*new DOMPath); }
- static Ref<DOMPath> create(const Path& path) { return adoptRef(*new DOMPath(path)); }
- static Ref<DOMPath> create(const DOMPath* path) { return create(path->path()); }
+ static PassRefPtr<DOMPath> create() { return adoptRef(new DOMPath); }
+ static PassRefPtr<DOMPath> create(const Path& path) { return adoptRef(new DOMPath(path)); }
+ static PassRefPtr<DOMPath> create(const DOMPath* path) { return create(path->path()); }
- static Ref<DOMPath> create(const String& pathData)
+#if ENABLE(SVG)
+ static PassRefPtr<DOMPath> create(const String& pathData)
{
Path path;
buildPathFromString(pathData, path);
return create(path);
}
-
-#if ENABLE(CANVAS_PATH)
- void addPath(const DOMPath* path) { addPath(path, AffineTransform()); }
- void addPath(const DOMPath* path, const AffineTransform& transform)
- {
- if (!path || !transform.isInvertible())
- return;
- m_path.addPath(path->path(), transform);
- }
#endif
const Path& path() const { return m_path; }
@@ -69,4 +64,7 @@ private:
};
}
+
+#endif
+
#endif
diff --git a/Source/WebCore/html/canvas/DOMPath.idl b/Source/WebCore/html/canvas/DOMPath.idl
index 8f8636a47..0c262c681 100644
--- a/Source/WebCore/html/canvas/DOMPath.idl
+++ b/Source/WebCore/html/canvas/DOMPath.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,13 +29,12 @@
[
Constructor,
Constructor(DOMPath path),
+#if defined(ENABLE_SVG) && ENABLE_SVG
Constructor(DOMString text),
- InterfaceName=Path2D,
-] interface DOMPath {
-
-#if defined(ENABLE_CANVAS_PATH) && ENABLE_CANVAS_PATH
- void addPath(DOMPath? path, optional SVGMatrix? transform);
#endif
+ Conditional=CANVAS_PATH,
+ InterfaceName=Path,
+] interface DOMPath {
// FIXME: These methods should be shared with CanvasRenderingContext2D in the CanvasPathMethods interface.
void closePath();
@@ -63,11 +62,9 @@
[Default=Undefined] optional float width,
[Default=Undefined] optional float height);
[RaisesException] void arc([Default=Undefined] optional float x,
- [Default=Undefined] optional float y,
- [Default=Undefined] optional float radius,
- [Default=Undefined] optional float startAngle,
- [Default=Undefined] optional float endAngle,
- [Default=Undefined] optional boolean anticlockwise);
- [RaisesException] void ellipse(unrestricted float x, unrestricted float y, unrestricted float radiusX, unrestricted float radiusY, unrestricted float rotation, unrestricted float startAngle, unrestricted float endAngle, [Default=Undefined] optional boolean anticlockwise);
-
+ [Default=Undefined] optional float y,
+ [Default=Undefined] optional float radius,
+ [Default=Undefined] optional float startAngle,
+ [Default=Undefined] optional float endAngle,
+ [Default=Undefined] optional boolean anticlockwise);
};
diff --git a/Source/WebCore/html/canvas/EXTBlendMinMax.cpp b/Source/WebCore/html/canvas/EXTBlendMinMax.cpp
deleted file mode 100644
index f5eada66f..000000000
--- a/Source/WebCore/html/canvas/EXTBlendMinMax.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL)
-#include "EXTBlendMinMax.h"
-
-namespace WebCore {
-
-EXTBlendMinMax::EXTBlendMinMax(WebGLRenderingContextBase* context)
- : WebGLExtension(context)
-{
-}
-
-EXTBlendMinMax::~EXTBlendMinMax()
-{
-}
-
-WebGLExtension::ExtensionName EXTBlendMinMax::getName() const
-{
- return EXTBlendMinMaxName;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/EXTBlendMinMax.h b/Source/WebCore/html/canvas/EXTBlendMinMax.h
deleted file mode 100644
index 8bd8c933d..000000000
--- a/Source/WebCore/html/canvas/EXTBlendMinMax.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef EXTBlendMinMax_h
-#define EXTBlendMinMax_h
-
-#include "WebGLExtension.h"
-
-namespace WebCore {
-
-class EXTBlendMinMax final : public WebGLExtension {
-public:
- explicit EXTBlendMinMax(WebGLRenderingContextBase*);
- virtual ~EXTBlendMinMax();
-
- virtual ExtensionName getName() const override;
-};
-
-} // namespace WebCore
-
-#endif // EXTBlendMinMax_h
diff --git a/Source/WebCore/html/canvas/EXTBlendMinMax.idl b/Source/WebCore/html/canvas/EXTBlendMinMax.idl
deleted file mode 100644
index 08acbd8b6..000000000
--- a/Source/WebCore/html/canvas/EXTBlendMinMax.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-* Copyright (C) 2014 Apple Inc. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-*
-* 1. Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* 2. Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
-* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
-* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-[
- NoInterfaceObject,
- Conditional=WEBGL,
- GenerateIsReachable=ImplWebGLRenderingContext
-] interface EXTBlendMinMax {
- const unsigned int MIN_EXT = 0x8007;
- const unsigned int MAX_EXT = 0x8008;
-};
diff --git a/Source/WebCore/html/canvas/WebGLDrawBuffers.cpp b/Source/WebCore/html/canvas/EXTDrawBuffers.cpp
index bceaebf28..1a2bbf1a9 100644
--- a/Source/WebCore/html/canvas/WebGLDrawBuffers.cpp
+++ b/Source/WebCore/html/canvas/EXTDrawBuffers.cpp
@@ -26,45 +26,45 @@
#include "config.h"
#if ENABLE(WEBGL)
-#include "WebGLDrawBuffers.h"
+
+#include "EXTDrawBuffers.h"
#include "Extensions3D.h"
namespace WebCore {
-WebGLDrawBuffers::WebGLDrawBuffers(WebGLRenderingContextBase* context)
+EXTDrawBuffers::EXTDrawBuffers(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
-WebGLDrawBuffers::~WebGLDrawBuffers()
+EXTDrawBuffers::~EXTDrawBuffers()
{
}
-WebGLExtension::ExtensionName WebGLDrawBuffers::getName() const
+WebGLExtension::ExtensionName EXTDrawBuffers::getName() const
{
- return WebGLExtension::WebGLDrawBuffersName;
+ return WebGLExtension::EXTDrawBuffersName;
}
-#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101000)
-
-bool WebGLDrawBuffers::supported(WebGLRenderingContextBase*)
+OwnPtr<EXTDrawBuffers> EXTDrawBuffers::create(WebGLRenderingContext* context)
{
- return false;
+ return adoptPtr(new EXTDrawBuffers(context));
}
-#else
-
-bool WebGLDrawBuffers::supported(WebGLRenderingContextBase* context)
+// static
+bool EXTDrawBuffers::supported(WebGLRenderingContext* context)
{
+#if OS(DARWIN)
+ // https://bugs.webkit.org/show_bug.cgi?id=112486
+ return false;
+#endif
Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
- return extensions->supports("GL_EXT_draw_buffers")
- && satisfiesWebGLRequirements(context);
+ return (extensions->supports("GL_EXT_draw_buffers")
+ && satisfiesWebGLRequirements(context));
}
-#endif
-
-void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GC3Denum>& buffers)
+void EXTDrawBuffers::drawBuffersEXT(const Vector<GC3Denum>& buffers)
{
if (m_context->isContextLost())
return;
@@ -72,11 +72,11 @@ void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GC3Denum>& buffers)
const GC3Denum* bufs = buffers.data();
if (!m_context->m_framebufferBinding) {
if (n != 1) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffersWEBGL", "more than one buffer");
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffersEXT", "more than one buffer");
return;
}
if (bufs[0] != GraphicsContext3D::BACK && bufs[0] != GraphicsContext3D::NONE) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffersWEBGL", "BACK or NONE");
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffersEXT", "BACK or NONE");
return;
}
// Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
@@ -85,12 +85,12 @@ void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GC3Denum>& buffers)
m_context->setBackDrawBuffer(bufs[0]);
} else {
if (n > m_context->getMaxDrawBuffers()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffersWEBGL", "more than max draw buffers");
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffersEXT", "more than max draw buffers");
return;
}
for (GC3Dsizei i = 0; i < n; ++i) {
if (bufs[i] != GraphicsContext3D::NONE && bufs[i] != static_cast<GC3Denum>(Extensions3D::COLOR_ATTACHMENT0_EXT + i)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffersWEBGL", "COLOR_ATTACHMENTi_EXT or NONE");
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffersEXT", "COLOR_ATTACHMENTi_EXT or NONE");
return;
}
}
@@ -99,7 +99,7 @@ void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GC3Denum>& buffers)
}
// static
-bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContextBase* webglContext)
+bool EXTDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglContext)
{
GraphicsContext3D* context = webglContext->graphicsContext3D();
diff --git a/Source/WebCore/html/canvas/WebGLDrawBuffers.h b/Source/WebCore/html/canvas/EXTDrawBuffers.h
index a36f29372..b5963fb70 100644
--- a/Source/WebCore/html/canvas/WebGLDrawBuffers.h
+++ b/Source/WebCore/html/canvas/EXTDrawBuffers.h
@@ -23,28 +23,31 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebGLDrawBuffers_h
-#define WebGLDrawBuffers_h
+#ifndef EXTDrawBuffers_h
+#define EXTDrawBuffers_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLDrawBuffers final : public WebGLExtension {
+class EXTDrawBuffers : public WebGLExtension {
public:
- explicit WebGLDrawBuffers(WebGLRenderingContextBase*);
- virtual ~WebGLDrawBuffers();
+ static OwnPtr<EXTDrawBuffers> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContext*);
+ virtual ~EXTDrawBuffers();
virtual ExtensionName getName() const override;
- void drawBuffersWEBGL(const Vector<GC3Denum>& buffers);
+ void drawBuffersEXT(const Vector<GC3Denum>& buffers);
private:
- static bool satisfiesWebGLRequirements(WebGLRenderingContextBase*);
+ EXTDrawBuffers(WebGLRenderingContext*);
+
+ static bool satisfiesWebGLRequirements(WebGLRenderingContext*);
};
} // namespace WebCore
-#endif // WebGLDrawBuffers_h
+#endif // EXTDrawBuffers_h
diff --git a/Source/WebCore/html/canvas/EXTDrawBuffers.idl b/Source/WebCore/html/canvas/EXTDrawBuffers.idl
new file mode 100644
index 000000000..864e5504e
--- /dev/null
+++ b/Source/WebCore/html/canvas/EXTDrawBuffers.idl
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef unsigned long GLenum;
+
+[
+ NoInterfaceObject,
+ Conditional=WEBGL,
+ GenerateIsReachable=ImplWebGLRenderingContext,
+ DoNotCheckConstants,
+] interface EXTDrawBuffers {
+ const GLenum COLOR_ATTACHMENT0_EXT = 0x8CE0;
+ const GLenum COLOR_ATTACHMENT1_EXT = 0x8CE1;
+ const GLenum COLOR_ATTACHMENT2_EXT = 0x8CE2;
+ const GLenum COLOR_ATTACHMENT3_EXT = 0x8CE3;
+ const GLenum COLOR_ATTACHMENT4_EXT = 0x8CE4;
+ const GLenum COLOR_ATTACHMENT5_EXT = 0x8CE5;
+ const GLenum COLOR_ATTACHMENT6_EXT = 0x8CE6;
+ const GLenum COLOR_ATTACHMENT7_EXT = 0x8CE7;
+ const GLenum COLOR_ATTACHMENT8_EXT = 0x8CE8;
+ const GLenum COLOR_ATTACHMENT9_EXT = 0x8CE9;
+ const GLenum COLOR_ATTACHMENT10_EXT = 0x8CEA;
+ const GLenum COLOR_ATTACHMENT11_EXT = 0x8CEB;
+ const GLenum COLOR_ATTACHMENT12_EXT = 0x8CEC;
+ const GLenum COLOR_ATTACHMENT13_EXT = 0x8CED;
+ const GLenum COLOR_ATTACHMENT14_EXT = 0x8CEE;
+ const GLenum COLOR_ATTACHMENT15_EXT = 0x8CEF;
+
+ const GLenum DRAW_BUFFER0_EXT = 0x8825;
+ const GLenum DRAW_BUFFER1_EXT = 0x8826;
+ const GLenum DRAW_BUFFER2_EXT = 0x8827;
+ const GLenum DRAW_BUFFER3_EXT = 0x8828;
+ const GLenum DRAW_BUFFER4_EXT = 0x8829;
+ const GLenum DRAW_BUFFER5_EXT = 0x882A;
+ const GLenum DRAW_BUFFER6_EXT = 0x882B;
+ const GLenum DRAW_BUFFER7_EXT = 0x882C;
+ const GLenum DRAW_BUFFER8_EXT = 0x882D;
+ const GLenum DRAW_BUFFER9_EXT = 0x882E;
+ const GLenum DRAW_BUFFER10_EXT = 0x882F;
+ const GLenum DRAW_BUFFER11_EXT = 0x8830;
+ const GLenum DRAW_BUFFER12_EXT = 0x8831;
+ const GLenum DRAW_BUFFER13_EXT = 0x8832;
+ const GLenum DRAW_BUFFER14_EXT = 0x8833;
+ const GLenum DRAW_BUFFER15_EXT = 0x8834;
+
+ const GLenum MAX_COLOR_ATTACHMENTS_EXT = 0x8CDF;
+ const GLenum MAX_DRAW_BUFFERS_EXT = 0x8824;
+
+ void drawBuffersEXT(sequence<GLenum> buffers);
+};
diff --git a/Source/WebCore/html/canvas/EXTFragDepth.cpp b/Source/WebCore/html/canvas/EXTFragDepth.cpp
deleted file mode 100644
index 8670736cc..000000000
--- a/Source/WebCore/html/canvas/EXTFragDepth.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL)
-#include "EXTFragDepth.h"
-
-namespace WebCore {
-
-EXTFragDepth::EXTFragDepth(WebGLRenderingContextBase* context)
- : WebGLExtension(context)
-{
-}
-
-EXTFragDepth::~EXTFragDepth()
-{
-}
-
-WebGLExtension::ExtensionName EXTFragDepth::getName() const
-{
- return EXTFragDepthName;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/EXTFragDepth.h b/Source/WebCore/html/canvas/EXTFragDepth.h
deleted file mode 100644
index 0a3735526..000000000
--- a/Source/WebCore/html/canvas/EXTFragDepth.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef EXTFragDepth_h
-#define EXTFragDepth_h
-
-#include "WebGLExtension.h"
-
-namespace WebCore {
-
-class EXTFragDepth final : public WebGLExtension {
-public:
- explicit EXTFragDepth(WebGLRenderingContextBase*);
- virtual ~EXTFragDepth();
-
- virtual ExtensionName getName() const override;
-};
-
-} // namespace WebCore
-
-#endif // EXTFragDepth_h
diff --git a/Source/WebCore/html/canvas/EXTFragDepth.idl b/Source/WebCore/html/canvas/EXTFragDepth.idl
deleted file mode 100644
index 5edc4aa30..000000000
--- a/Source/WebCore/html/canvas/EXTFragDepth.idl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-* Copyright (C) 2014 Apple Inc. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-*
-* 1. Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* 2. Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
-* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
-* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-[
- NoInterfaceObject,
- Conditional=WEBGL,
- GenerateIsReachable=ImplWebGLRenderingContext
-] interface EXTFragDepth {
-};
diff --git a/Source/WebCore/html/canvas/EXTShaderTextureLOD.cpp b/Source/WebCore/html/canvas/EXTShaderTextureLOD.cpp
deleted file mode 100644
index 0da325d00..000000000
--- a/Source/WebCore/html/canvas/EXTShaderTextureLOD.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL)
-#include "EXTShaderTextureLOD.h"
-
-namespace WebCore {
-
-EXTShaderTextureLOD::EXTShaderTextureLOD(WebGLRenderingContextBase* context)
- : WebGLExtension(context)
-{
-}
-
-EXTShaderTextureLOD::~EXTShaderTextureLOD()
-{
-}
-
-WebGLExtension::ExtensionName EXTShaderTextureLOD::getName() const
-{
- return EXTShaderTextureLODName;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/EXTShaderTextureLOD.h b/Source/WebCore/html/canvas/EXTShaderTextureLOD.h
deleted file mode 100644
index 30bb238bf..000000000
--- a/Source/WebCore/html/canvas/EXTShaderTextureLOD.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef EXTShaderTextureLOD_h
-#define EXTShaderTextureLOD_h
-
-#include "WebGLExtension.h"
-
-namespace WebCore {
-
-class EXTShaderTextureLOD final : public WebGLExtension {
-public:
- explicit EXTShaderTextureLOD(WebGLRenderingContextBase*);
- virtual ~EXTShaderTextureLOD();
-
- virtual ExtensionName getName() const override;
-};
-
-} // namespace WebCore
-
-#endif // EXTShaderTextureLOD_h
diff --git a/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.cpp b/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.cpp
index da74c4be1..8ae249456 100644
--- a/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.cpp
+++ b/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-EXTTextureFilterAnisotropic::EXTTextureFilterAnisotropic(WebGLRenderingContextBase* context)
+EXTTextureFilterAnisotropic::EXTTextureFilterAnisotropic(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -45,6 +45,11 @@ WebGLExtension::ExtensionName EXTTextureFilterAnisotropic::getName() const
return EXTTextureFilterAnisotropicName;
}
+OwnPtr<EXTTextureFilterAnisotropic> EXTTextureFilterAnisotropic::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new EXTTextureFilterAnisotropic(context));
+}
+
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.h b/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.h
index ce615f99f..5e76ebb01 100644
--- a/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.h
+++ b/Source/WebCore/html/canvas/EXTTextureFilterAnisotropic.h
@@ -27,15 +27,19 @@
#define EXTTextureFilterAnisotropic_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class EXTTextureFilterAnisotropic final : public WebGLExtension {
+class EXTTextureFilterAnisotropic : public WebGLExtension {
public:
- explicit EXTTextureFilterAnisotropic(WebGLRenderingContextBase*);
- virtual ~EXTTextureFilterAnisotropic();
+ static OwnPtr<EXTTextureFilterAnisotropic> create(WebGLRenderingContext*);
+ virtual ~EXTTextureFilterAnisotropic();
virtual ExtensionName getName() const override;
+
+private:
+ EXTTextureFilterAnisotropic(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/EXTsRGB.cpp b/Source/WebCore/html/canvas/EXTsRGB.cpp
deleted file mode 100644
index 24f508886..000000000
--- a/Source/WebCore/html/canvas/EXTsRGB.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL)
-#include "EXTsRGB.h"
-
-namespace WebCore {
-
-EXTsRGB::EXTsRGB(WebGLRenderingContextBase* context)
- : WebGLExtension(context)
-{
-}
-
-EXTsRGB::~EXTsRGB()
-{
-}
-
-WebGLExtension::ExtensionName EXTsRGB::getName() const
-{
- return EXTsRGBName;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/EXTsRGB.h b/Source/WebCore/html/canvas/EXTsRGB.h
deleted file mode 100644
index 07014b3d5..000000000
--- a/Source/WebCore/html/canvas/EXTsRGB.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef EXTsRGB_h
-#define EXTsRGB_h
-
-#include "WebGLExtension.h"
-
-namespace WebCore {
-
-class EXTsRGB final : public WebGLExtension {
-public:
- explicit EXTsRGB(WebGLRenderingContextBase*);
- virtual ~EXTsRGB();
-
- virtual ExtensionName getName() const override;
-};
-
-} // namespace WebCore
-
-#endif // EXTsRGB_h
diff --git a/Source/WebCore/html/canvas/EXTsRGB.idl b/Source/WebCore/html/canvas/EXTsRGB.idl
deleted file mode 100644
index de06b37e8..000000000
--- a/Source/WebCore/html/canvas/EXTsRGB.idl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-* Copyright (C) 2014 Apple Inc. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-*
-* 1. Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* 2. Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
-* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
-* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-[
- NoInterfaceObject,
- Conditional=WEBGL,
- GenerateIsReachable=ImplWebGLRenderingContext
-] interface EXTsRGB {
- const unsigned int SRGB_EXT = 0x8C40;
- const unsigned int SRGB_ALPHA_EXT = 0x8C42;
- const unsigned int SRGB8_ALPHA8_EXT = 0x8C43;
- const unsigned int FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT = 0x8210;
-};
diff --git a/Source/WebCore/html/canvas/OESElementIndexUint.cpp b/Source/WebCore/html/canvas/OESElementIndexUint.cpp
index 65b6838de..66024153a 100644
--- a/Source/WebCore/html/canvas/OESElementIndexUint.cpp
+++ b/Source/WebCore/html/canvas/OESElementIndexUint.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-OESElementIndexUint::OESElementIndexUint(WebGLRenderingContextBase* context)
+OESElementIndexUint::OESElementIndexUint(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -45,6 +45,11 @@ WebGLExtension::ExtensionName OESElementIndexUint::getName() const
return OESElementIndexUintName;
}
+OwnPtr<OESElementIndexUint> OESElementIndexUint::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new OESElementIndexUint(context));
+}
+
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESElementIndexUint.h b/Source/WebCore/html/canvas/OESElementIndexUint.h
index b4cf8a4ad..83ce56a8d 100644
--- a/Source/WebCore/html/canvas/OESElementIndexUint.h
+++ b/Source/WebCore/html/canvas/OESElementIndexUint.h
@@ -27,15 +27,19 @@
#define OESElementIndexUint_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class OESElementIndexUint final : public WebGLExtension {
+class OESElementIndexUint : public WebGLExtension {
public:
- explicit OESElementIndexUint(WebGLRenderingContextBase*);
- virtual ~OESElementIndexUint();
+ static OwnPtr<OESElementIndexUint> create(WebGLRenderingContext*);
+ virtual ~OESElementIndexUint();
virtual ExtensionName getName() const override;
+
+private:
+ OESElementIndexUint(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/OESStandardDerivatives.cpp b/Source/WebCore/html/canvas/OESStandardDerivatives.cpp
index e754acf73..0f2c876c7 100644
--- a/Source/WebCore/html/canvas/OESStandardDerivatives.cpp
+++ b/Source/WebCore/html/canvas/OESStandardDerivatives.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-OESStandardDerivatives::OESStandardDerivatives(WebGLRenderingContextBase* context)
+OESStandardDerivatives::OESStandardDerivatives(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -45,6 +45,11 @@ WebGLExtension::ExtensionName OESStandardDerivatives::getName() const
return OESStandardDerivativesName;
}
+OwnPtr<OESStandardDerivatives> OESStandardDerivatives::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new OESStandardDerivatives(context));
+}
+
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESStandardDerivatives.h b/Source/WebCore/html/canvas/OESStandardDerivatives.h
index ff1d4ab5d..a21dfd89c 100644
--- a/Source/WebCore/html/canvas/OESStandardDerivatives.h
+++ b/Source/WebCore/html/canvas/OESStandardDerivatives.h
@@ -27,15 +27,19 @@
#define OESStandardDerivatives_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class OESStandardDerivatives final : public WebGLExtension {
+class OESStandardDerivatives : public WebGLExtension {
public:
- explicit OESStandardDerivatives(WebGLRenderingContextBase*);
- virtual ~OESStandardDerivatives();
+ static OwnPtr<OESStandardDerivatives> create(WebGLRenderingContext*);
+ virtual ~OESStandardDerivatives();
virtual ExtensionName getName() const override;
+
+private:
+ OESStandardDerivatives(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/OESTextureFloat.cpp b/Source/WebCore/html/canvas/OESTextureFloat.cpp
index b8ffec7d3..223136c42 100644
--- a/Source/WebCore/html/canvas/OESTextureFloat.cpp
+++ b/Source/WebCore/html/canvas/OESTextureFloat.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-OESTextureFloat::OESTextureFloat(WebGLRenderingContextBase* context)
+OESTextureFloat::OESTextureFloat(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -45,6 +45,11 @@ WebGLExtension::ExtensionName OESTextureFloat::getName() const
return OESTextureFloatName;
}
+OwnPtr<OESTextureFloat> OESTextureFloat::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new OESTextureFloat(context));
+}
+
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESTextureFloat.h b/Source/WebCore/html/canvas/OESTextureFloat.h
index 24a08192b..6c67ea11b 100644
--- a/Source/WebCore/html/canvas/OESTextureFloat.h
+++ b/Source/WebCore/html/canvas/OESTextureFloat.h
@@ -27,15 +27,19 @@
#define OESTextureFloat_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class OESTextureFloat final : public WebGLExtension {
+class OESTextureFloat : public WebGLExtension {
public:
- OESTextureFloat(WebGLRenderingContextBase*);
- virtual ~OESTextureFloat();
+ static OwnPtr<OESTextureFloat> create(WebGLRenderingContext*);
+ virtual ~OESTextureFloat();
virtual ExtensionName getName() const override;
+
+private:
+ OESTextureFloat(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/OESTextureFloatLinear.cpp b/Source/WebCore/html/canvas/OESTextureFloatLinear.cpp
index 2a10a50ad..d93491608 100644
--- a/Source/WebCore/html/canvas/OESTextureFloatLinear.cpp
+++ b/Source/WebCore/html/canvas/OESTextureFloatLinear.cpp
@@ -30,7 +30,7 @@
namespace WebCore {
-OESTextureFloatLinear::OESTextureFloatLinear(WebGLRenderingContextBase* context)
+OESTextureFloatLinear::OESTextureFloatLinear(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -44,6 +44,11 @@ WebGLExtension::ExtensionName OESTextureFloatLinear::getName() const
return OESTextureFloatLinearName;
}
+OwnPtr<OESTextureFloatLinear> OESTextureFloatLinear::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new OESTextureFloatLinear(context));
+}
+
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESTextureFloatLinear.h b/Source/WebCore/html/canvas/OESTextureFloatLinear.h
index 088afc8a0..3e9fe87cc 100644
--- a/Source/WebCore/html/canvas/OESTextureFloatLinear.h
+++ b/Source/WebCore/html/canvas/OESTextureFloatLinear.h
@@ -27,15 +27,19 @@
#define OESTextureFloatLinear_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class OESTextureFloatLinear final : public WebGLExtension {
+class OESTextureFloatLinear : public WebGLExtension {
public:
- explicit OESTextureFloatLinear(WebGLRenderingContextBase*);
- virtual ~OESTextureFloatLinear();
+ static OwnPtr<OESTextureFloatLinear> create(WebGLRenderingContext*);
+ virtual ~OESTextureFloatLinear();
virtual ExtensionName getName() const override;
+
+private:
+ OESTextureFloatLinear(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/OESTextureHalfFloat.cpp b/Source/WebCore/html/canvas/OESTextureHalfFloat.cpp
index bdd167c03..fd2e25bd2 100644
--- a/Source/WebCore/html/canvas/OESTextureHalfFloat.cpp
+++ b/Source/WebCore/html/canvas/OESTextureHalfFloat.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-OESTextureHalfFloat::OESTextureHalfFloat(WebGLRenderingContextBase* context)
+OESTextureHalfFloat::OESTextureHalfFloat(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -45,6 +45,11 @@ WebGLExtension::ExtensionName OESTextureHalfFloat::getName() const
return OESTextureHalfFloatName;
}
+OwnPtr<OESTextureHalfFloat> OESTextureHalfFloat::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new OESTextureHalfFloat(context));
+}
+
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESTextureHalfFloat.h b/Source/WebCore/html/canvas/OESTextureHalfFloat.h
index ce7ee52de..c8ab9feb1 100644
--- a/Source/WebCore/html/canvas/OESTextureHalfFloat.h
+++ b/Source/WebCore/html/canvas/OESTextureHalfFloat.h
@@ -27,15 +27,19 @@
#define OESTextureHalfFloat_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class OESTextureHalfFloat final : public WebGLExtension {
+class OESTextureHalfFloat : public WebGLExtension {
public:
- OESTextureHalfFloat(WebGLRenderingContextBase*);
- virtual ~OESTextureHalfFloat();
+ static OwnPtr<OESTextureHalfFloat> create(WebGLRenderingContext*);
+ virtual ~OESTextureHalfFloat();
virtual ExtensionName getName() const override;
+
+private:
+ OESTextureHalfFloat(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.cpp b/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.cpp
index 4211c8062..e2ec8b250 100644
--- a/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.cpp
+++ b/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.cpp
@@ -30,7 +30,7 @@
namespace WebCore {
-OESTextureHalfFloatLinear::OESTextureHalfFloatLinear(WebGLRenderingContextBase* context)
+OESTextureHalfFloatLinear::OESTextureHalfFloatLinear(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -44,6 +44,11 @@ WebGLExtension::ExtensionName OESTextureHalfFloatLinear::getName() const
return OESTextureHalfFloatLinearName;
}
+OwnPtr<OESTextureHalfFloatLinear> OESTextureHalfFloatLinear::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new OESTextureHalfFloatLinear(context));
+}
+
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.h b/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.h
index e46944806..073b48a9f 100644
--- a/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.h
+++ b/Source/WebCore/html/canvas/OESTextureHalfFloatLinear.h
@@ -27,15 +27,19 @@
#define OESTextureHalfFloatLinear_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class OESTextureHalfFloatLinear final : public WebGLExtension {
+class OESTextureHalfFloatLinear : public WebGLExtension {
public:
- OESTextureHalfFloatLinear(WebGLRenderingContextBase*);
- virtual ~OESTextureHalfFloatLinear();
+ static OwnPtr<OESTextureHalfFloatLinear> create(WebGLRenderingContext*);
+ virtual ~OESTextureHalfFloatLinear();
virtual ExtensionName getName() const override;
+
+private:
+ OESTextureHalfFloatLinear(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/OESVertexArrayObject.cpp b/Source/WebCore/html/canvas/OESVertexArrayObject.cpp
index 16aa8d757..36ab832d9 100644
--- a/Source/WebCore/html/canvas/OESVertexArrayObject.cpp
+++ b/Source/WebCore/html/canvas/OESVertexArrayObject.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,11 +30,10 @@
#include "OESVertexArrayObject.h"
#include "Extensions3D.h"
-#include "WebGLRenderingContext.h"
namespace WebCore {
-OESVertexArrayObject::OESVertexArrayObject(WebGLRenderingContextBase* context)
+OESVertexArrayObject::OESVertexArrayObject(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -48,12 +47,17 @@ WebGLExtension::ExtensionName OESVertexArrayObject::getName() const
return OESVertexArrayObjectName;
}
+OwnPtr<OESVertexArrayObject> OESVertexArrayObject::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new OESVertexArrayObject(context));
+}
+
PassRefPtr<WebGLVertexArrayObjectOES> OESVertexArrayObject::createVertexArrayOES()
{
if (m_context->isContextLost())
return 0;
- RefPtr<WebGLVertexArrayObjectOES> o = WebGLVertexArrayObjectOES::create(m_context, WebGLVertexArrayObjectOES::VAOTypeUser);
+ RefPtr<WebGLVertexArrayObjectOES> o = WebGLVertexArrayObjectOES::create(m_context, WebGLVertexArrayObjectOES::VaoTypeUser);
m_context->addContextObject(o.get());
return o.release();
}
@@ -63,8 +67,8 @@ void OESVertexArrayObject::deleteVertexArrayOES(WebGLVertexArrayObjectOES* array
if (!arrayObject || m_context->isContextLost())
return;
- if (!arrayObject->isDefaultObject() && arrayObject == static_cast<WebGLRenderingContext*>(m_context)->m_boundVertexArrayObject)
- static_cast<WebGLRenderingContext*>(m_context)->setBoundVertexArrayObject(0);
+ if (!arrayObject->isDefaultObject() && arrayObject == m_context->m_boundVertexArrayObject)
+ m_context->setBoundVertexArrayObject(0);
arrayObject->deleteObject(m_context->graphicsContext3D());
}
@@ -97,11 +101,13 @@ void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayOb
extensions->bindVertexArrayOES(arrayObject->object());
arrayObject->setHasEverBeenBound();
- static_cast<WebGLRenderingContext*>(m_context)->setBoundVertexArrayObject(arrayObject);
+ m_context->setBoundVertexArrayObject(arrayObject);
} else {
extensions->bindVertexArrayOES(0);
- static_cast<WebGLRenderingContext*>(m_context)->setBoundVertexArrayObject(0);
+ m_context->setBoundVertexArrayObject(0);
}
+
+ m_context->cleanupAfterGraphicsCall(false);
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/OESVertexArrayObject.h b/Source/WebCore/html/canvas/OESVertexArrayObject.h
index 51e8a06a1..b9f859929 100644
--- a/Source/WebCore/html/canvas/OESVertexArrayObject.h
+++ b/Source/WebCore/html/canvas/OESVertexArrayObject.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,25 +28,29 @@
#include "GraphicsTypes3D.h"
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLRenderingContextBase;
+class WebGLRenderingContext;
class WebGLVertexArrayObjectOES;
typedef int ExceptionCode;
-class OESVertexArrayObject final : public WebGLExtension {
+class OESVertexArrayObject : public WebGLExtension {
public:
- OESVertexArrayObject(WebGLRenderingContextBase*);
- virtual ~OESVertexArrayObject();
+ static OwnPtr<OESVertexArrayObject> create(WebGLRenderingContext*);
+ virtual ~OESVertexArrayObject();
virtual ExtensionName getName() const override;
PassRefPtr<WebGLVertexArrayObjectOES> createVertexArrayOES();
void deleteVertexArrayOES(WebGLVertexArrayObjectOES*);
GC3Dboolean isVertexArrayOES(WebGLVertexArrayObjectOES*);
void bindVertexArrayOES(WebGLVertexArrayObjectOES*, ExceptionCode&);
+
+private:
+ OESVertexArrayObject(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/OESVertexArrayObject.idl b/Source/WebCore/html/canvas/OESVertexArrayObject.idl
index 29faab558..53f475d94 100644
--- a/Source/WebCore/html/canvas/OESVertexArrayObject.idl
+++ b/Source/WebCore/html/canvas/OESVertexArrayObject.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp b/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp
deleted file mode 100644
index 3810f167c..000000000
--- a/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp
+++ /dev/null
@@ -1,2510 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL) && ENABLE(WEBGL2)
-#include "WebGL2RenderingContext.h"
-
-#include "CachedImage.h"
-#include "EXTTextureFilterAnisotropic.h"
-#include "Extensions3D.h"
-#include "HTMLCanvasElement.h"
-#include "HTMLImageElement.h"
-#include "HTMLVideoElement.h"
-#include "ImageData.h"
-#include "OESTextureFloat.h"
-#include "OESTextureFloatLinear.h"
-#include "OESTextureHalfFloat.h"
-#include "OESTextureHalfFloatLinear.h"
-#include "RenderBox.h"
-#include "WebGLActiveInfo.h"
-#include "WebGLCompressedTextureATC.h"
-#include "WebGLCompressedTexturePVRTC.h"
-#include "WebGLCompressedTextureS3TC.h"
-#include "WebGLContextAttributes.h"
-#include "WebGLDebugRendererInfo.h"
-#include "WebGLDebugShaders.h"
-#include "WebGLDepthTexture.h"
-#include "WebGLLoseContext.h"
-#include "WebGLQuery.h"
-#include "WebGLSampler.h"
-#include "WebGLSync.h"
-#include "WebGLTransformFeedback.h"
-#include "WebGLVertexArrayObject.h"
-
-namespace WebCore {
-
-WebGL2RenderingContext::WebGL2RenderingContext(HTMLCanvasElement* passedCanvas, GraphicsContext3D::Attributes attributes)
- : WebGLRenderingContextBase(passedCanvas, attributes)
-{
-}
-
-WebGL2RenderingContext::WebGL2RenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context,
- GraphicsContext3D::Attributes attributes) : WebGLRenderingContextBase(passedCanvas, context, attributes)
-{
- initializeShaderExtensions();
- initializeVertexArrayObjects();
-}
-
-void WebGL2RenderingContext::initializeVertexArrayObjects()
-{
- m_defaultVertexArrayObject = WebGLVertexArrayObject::create(this, WebGLVertexArrayObject::VAOTypeDefault);
- addContextObject(m_defaultVertexArrayObject.get());
- m_boundVertexArrayObject = m_defaultVertexArrayObject;
- if (!isGLES2Compliant())
- initVertexAttrib0();
-}
-
-void WebGL2RenderingContext::initializeShaderExtensions()
-{
- m_context->getExtensions()->ensureEnabled("GL_OES_standard_derivatives");
- m_context->getExtensions()->ensureEnabled("GL_EXT_draw_buffers");
- m_context->getExtensions()->ensureEnabled("GL_EXT_shader_texture_lod");
- m_context->getExtensions()->ensureEnabled("GL_EXT_frag_depth");
-}
-
-void WebGL2RenderingContext::copyBufferSubData(GC3Denum readTarget, GC3Denum writeTarget, GC3Dint64 readOffset, GC3Dint64 writeOffset, GC3Dint64 size)
-{
- UNUSED_PARAM(readTarget);
- UNUSED_PARAM(writeTarget);
- UNUSED_PARAM(readOffset);
- UNUSED_PARAM(writeOffset);
- UNUSED_PARAM(size);
-}
-
-void WebGL2RenderingContext::getBufferSubData(GC3Denum target, GC3Dint64 offset, ArrayBufferView* returnedData)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(offset);
- UNUSED_PARAM(returnedData);
-}
-
-void WebGL2RenderingContext::getBufferSubData(GC3Denum target, GC3Dint64 offset, ArrayBuffer* returnedData)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(offset);
- UNUSED_PARAM(returnedData);
-}
-
-void WebGL2RenderingContext::blitFramebuffer(GC3Dint srcX0, GC3Dint srcY0, GC3Dint srcX1, GC3Dint srcY1, GC3Dint dstX0, GC3Dint dstY0, GC3Dint dstX1, GC3Dint dstY1, GC3Dbitfield mask, GC3Denum filter)
-{
- UNUSED_PARAM(srcX0);
- UNUSED_PARAM(srcX1);
- UNUSED_PARAM(srcY0);
- UNUSED_PARAM(srcY1);
- UNUSED_PARAM(dstX0);
- UNUSED_PARAM(dstX1);
- UNUSED_PARAM(dstY0);
- UNUSED_PARAM(dstY1);
- UNUSED_PARAM(mask);
- UNUSED_PARAM(filter);
-}
-
-void WebGL2RenderingContext::framebufferTextureLayer(GC3Denum target, GC3Denum attachment, GC3Duint texture, GC3Dint level, GC3Dint layer)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(attachment);
- UNUSED_PARAM(texture);
- UNUSED_PARAM(level);
- UNUSED_PARAM(layer);
-}
-
-WebGLGetInfo WebGL2RenderingContext::getInternalformatParameter(GC3Denum target, GC3Denum internalformat, GC3Denum pname)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(internalformat);
- UNUSED_PARAM(pname);
- return WebGLGetInfo();
-}
-
-void WebGL2RenderingContext::invalidateFramebuffer(GC3Denum target, Vector<GC3Denum> attachments)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(attachments);
-}
-
-void WebGL2RenderingContext::invalidateSubFramebuffer(GC3Denum target, Vector<GC3Denum> attachments, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(attachments);
- UNUSED_PARAM(x);
- UNUSED_PARAM(y);
- UNUSED_PARAM(width);
- UNUSED_PARAM(height);
-}
-
-void WebGL2RenderingContext::readBuffer(GC3Denum src)
-{
- UNUSED_PARAM(src);
-}
-
-void WebGL2RenderingContext::renderbufferStorageMultisample(GC3Denum target, GC3Dsizei samples, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(samples);
- UNUSED_PARAM(internalformat);
- UNUSED_PARAM(width);
- UNUSED_PARAM(height);
-}
-
-void WebGL2RenderingContext::texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(levels);
- UNUSED_PARAM(internalformat);
- UNUSED_PARAM(width);
- UNUSED_PARAM(height);
-}
-
-void WebGL2RenderingContext::texStorage3D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(levels);
- UNUSED_PARAM(internalformat);
- UNUSED_PARAM(width);
- UNUSED_PARAM(height);
- UNUSED_PARAM(depth);
-}
-
-void WebGL2RenderingContext::texImage3D(GC3Denum target, GC3Dint level, GC3Dint internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Dint border, GC3Denum format, GC3Denum type, ArrayBufferView* pixels)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(level);
- UNUSED_PARAM(internalformat);
- UNUSED_PARAM(width);
- UNUSED_PARAM(height);
- UNUSED_PARAM(depth);
- UNUSED_PARAM(border);
- UNUSED_PARAM(format);
- UNUSED_PARAM(type);
- UNUSED_PARAM(pixels);
-}
-
-void WebGL2RenderingContext::texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Denum format, GC3Denum type, ArrayBufferView* pixels)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(level);
- UNUSED_PARAM(xoffset);
- UNUSED_PARAM(yoffset);
- UNUSED_PARAM(zoffset);
- UNUSED_PARAM(width);
- UNUSED_PARAM(height);
- UNUSED_PARAM(depth);
- UNUSED_PARAM(format);
- UNUSED_PARAM(type);
- UNUSED_PARAM(pixels);
-}
-
-void WebGL2RenderingContext::texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Denum format, GC3Denum type, ImageData* source)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(level);
- UNUSED_PARAM(xoffset);
- UNUSED_PARAM(yoffset);
- UNUSED_PARAM(zoffset);
- UNUSED_PARAM(format);
- UNUSED_PARAM(type);
- UNUSED_PARAM(source);
-}
-
-void WebGL2RenderingContext::texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Denum format, GC3Denum type, HTMLImageElement* source)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(level);
- UNUSED_PARAM(xoffset);
- UNUSED_PARAM(yoffset);
- UNUSED_PARAM(zoffset);
- UNUSED_PARAM(format);
- UNUSED_PARAM(type);
- UNUSED_PARAM(source);
-}
-
-void WebGL2RenderingContext::texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Denum format, GC3Denum type, HTMLCanvasElement* source)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(level);
- UNUSED_PARAM(xoffset);
- UNUSED_PARAM(yoffset);
- UNUSED_PARAM(zoffset);
- UNUSED_PARAM(format);
- UNUSED_PARAM(type);
- UNUSED_PARAM(source);
-}
-
-void WebGL2RenderingContext::texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Denum format, GC3Denum type, HTMLVideoElement* source)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(level);
- UNUSED_PARAM(xoffset);
- UNUSED_PARAM(yoffset);
- UNUSED_PARAM(zoffset);
- UNUSED_PARAM(format);
- UNUSED_PARAM(type);
- UNUSED_PARAM(source);
-}
-
-void WebGL2RenderingContext::copyTexSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(level);
- UNUSED_PARAM(xoffset);
- UNUSED_PARAM(yoffset);
- UNUSED_PARAM(zoffset);
- UNUSED_PARAM(x);
- UNUSED_PARAM(y);
- UNUSED_PARAM(width);
- UNUSED_PARAM(height);
-}
-
-void WebGL2RenderingContext::compressedTexImage3D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Dint border, GC3Dsizei imageSize, ArrayBufferView* data)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(level);
- UNUSED_PARAM(internalformat);
- UNUSED_PARAM(width);
- UNUSED_PARAM(height);
- UNUSED_PARAM(depth);
- UNUSED_PARAM(border);
- UNUSED_PARAM(imageSize);
- UNUSED_PARAM(data);
-}
-
-void WebGL2RenderingContext::compressedTexSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Denum format, GC3Dsizei imageSize, ArrayBufferView* data)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(level);
- UNUSED_PARAM(xoffset);
- UNUSED_PARAM(yoffset);
- UNUSED_PARAM(zoffset);
- UNUSED_PARAM(width);
- UNUSED_PARAM(height);
- UNUSED_PARAM(depth);
- UNUSED_PARAM(format);
- UNUSED_PARAM(imageSize);
- UNUSED_PARAM(data);
-}
-
-GC3Dint WebGL2RenderingContext::getFragDataLocation(WebGLProgram* program, String name)
-{
- UNUSED_PARAM(program);
- UNUSED_PARAM(name);
- return 0;
-}
-
-void WebGL2RenderingContext::uniform1ui(WebGLUniformLocation* location, GC3Duint v0)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(v0);
-}
-
-void WebGL2RenderingContext::uniform2ui(WebGLUniformLocation* location, GC3Duint v0, GC3Duint v1)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(v0);
- UNUSED_PARAM(v1);
-}
-
-void WebGL2RenderingContext::uniform3ui(WebGLUniformLocation* location, GC3Duint v0, GC3Duint v1, GC3Duint v2)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(v0);
- UNUSED_PARAM(v1);
- UNUSED_PARAM(v2);
-}
-
-void WebGL2RenderingContext::uniform4ui(WebGLUniformLocation* location, GC3Duint v0, GC3Duint v1, GC3Duint v2, GC3Duint v3)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(v0);
- UNUSED_PARAM(v1);
- UNUSED_PARAM(v2);
- UNUSED_PARAM(v3);
-}
-
-void WebGL2RenderingContext::uniform1uiv(WebGLUniformLocation* location, Uint32Array* value)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(value);
-}
-
-void WebGL2RenderingContext::uniform2uiv(WebGLUniformLocation* location, Uint32Array* value)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(value);
-}
-
-void WebGL2RenderingContext::uniform3uiv(WebGLUniformLocation* location, Uint32Array* value)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(value);
-}
-
-void WebGL2RenderingContext::uniform4uiv(WebGLUniformLocation* location, Uint32Array* value)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(value);
-}
-
-void WebGL2RenderingContext::uniformMatrix2x3fv(WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(transpose);
- UNUSED_PARAM(value);
-}
-
-void WebGL2RenderingContext::uniformMatrix3x2fv(WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(transpose);
- UNUSED_PARAM(value);
-}
-
-void WebGL2RenderingContext::uniformMatrix2x4fv(WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(transpose);
- UNUSED_PARAM(value);
-}
-
-void WebGL2RenderingContext::uniformMatrix4x2fv(WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(transpose);
- UNUSED_PARAM(value);
-}
-
-void WebGL2RenderingContext::uniformMatrix3x4fv(WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(transpose);
- UNUSED_PARAM(value);
-}
-
-void WebGL2RenderingContext::uniformMatrix4x3fv(WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value)
-{
- UNUSED_PARAM(location);
- UNUSED_PARAM(transpose);
- UNUSED_PARAM(value);
-}
-
-void WebGL2RenderingContext::vertexAttribI4i(GC3Duint index, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w)
-{
- UNUSED_PARAM(index);
- UNUSED_PARAM(x);
- UNUSED_PARAM(y);
- UNUSED_PARAM(z);
- UNUSED_PARAM(w);
-}
-
-void WebGL2RenderingContext::vertexAttribI4iv(GC3Duint index, Int32Array* v)
-{
- UNUSED_PARAM(index);
- UNUSED_PARAM(v);
-}
-
-void WebGL2RenderingContext::vertexAttribI4ui(GC3Duint index, GC3Duint x, GC3Duint y, GC3Duint z, GC3Duint w)
-{
- UNUSED_PARAM(index);
- UNUSED_PARAM(x);
- UNUSED_PARAM(y);
- UNUSED_PARAM(z);
- UNUSED_PARAM(w);
-}
-
-void WebGL2RenderingContext::vertexAttribI4uiv(GC3Duint index, Uint32Array* v)
-{
- UNUSED_PARAM(index);
- UNUSED_PARAM(v);
-}
-
-void WebGL2RenderingContext::vertexAttribIPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dsizei stride, GC3Dint64 offset)
-{
- UNUSED_PARAM(index);
- UNUSED_PARAM(size);
- UNUSED_PARAM(type);
- UNUSED_PARAM(stride);
- UNUSED_PARAM(offset);
-}
-
-void WebGL2RenderingContext::clear(GC3Dbitfield mask)
-{
- if (isContextLostOrPending())
- return;
- if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clear", "invalid mask");
- return;
- }
- if (m_framebufferBinding && (mask & GraphicsContext3D::COLOR_BUFFER_BIT) && isIntegerFormat(m_framebufferBinding->getColorBufferFormat())) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clear", "cannot clear an integer buffer");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
- return;
- }
- if (!clearIfComposited(mask))
- m_context->clear(mask);
- markContextChanged();
-}
-
-void WebGL2RenderingContext::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
-{
- if (isContextLostOrPending())
- return;
-
- WebGLRenderingContextBase::vertexAttribDivisor(index, divisor);
-}
-
-void WebGL2RenderingContext::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei instanceCount)
-{
- if (isContextLostOrPending())
- return;
-
- WebGLRenderingContextBase::drawArraysInstanced(mode, first, count, instanceCount);
-}
-
-void WebGL2RenderingContext::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dint64 offset, GC3Dsizei instanceCount)
-{
- if (isContextLostOrPending())
- return;
-
- WebGLRenderingContextBase::drawElementsInstanced(mode, count, type, offset, instanceCount);
-}
-
-void WebGL2RenderingContext::drawRangeElements(GC3Denum mode, GC3Duint start, GC3Duint end, GC3Dsizei count, GC3Denum type, GC3Dint64 offset)
-{
- UNUSED_PARAM(mode);
- UNUSED_PARAM(start);
- UNUSED_PARAM(end);
- UNUSED_PARAM(count);
- UNUSED_PARAM(type);
- UNUSED_PARAM(offset);
-}
-
-void WebGL2RenderingContext::drawBuffers(Vector<GC3Denum> buffers)
-{
- if (isContextLost())
- return;
- GC3Dsizei n = buffers.size();
- const GC3Denum* bufs = buffers.data();
- if (!m_framebufferBinding) {
- if (n != 1) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffers", "more than one buffer");
- return;
- }
- if (bufs[0] != GraphicsContext3D::BACK && bufs[0] != GraphicsContext3D::NONE) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffers", "BACK or NONE");
- return;
- }
- // Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
- GC3Denum value = (bufs[0] == GraphicsContext3D::BACK) ? GraphicsContext3D::COLOR_ATTACHMENT0 : GraphicsContext3D::NONE;
- graphicsContext3D()->getExtensions()->drawBuffersEXT(1, &value);
- setBackDrawBuffer(bufs[0]);
- } else {
- if (n > getMaxDrawBuffers()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffers", "more than max draw buffers");
- return;
- }
- for (GC3Dsizei i = 0; i < n; ++i) {
- if (bufs[i] != GraphicsContext3D::NONE && bufs[i] != static_cast<GC3Denum>(GraphicsContext3D::COLOR_ATTACHMENT0 + i)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffers", "COLOR_ATTACHMENTi or NONE");
- return;
- }
- }
- m_framebufferBinding->drawBuffers(buffers);
- }
-}
-
-void WebGL2RenderingContext::clearBufferiv(GC3Denum buffer, GC3Dint drawbuffer, Int32Array* value)
-{
- UNUSED_PARAM(value);
- switch (buffer) {
- case GraphicsContext3D::COLOR:
- if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferiv", "buffer index out of range");
- return;
- }
- // TODO: Call clearBufferiv, requires gl3.h and ES3/gl.h
- break;
- case GraphicsContext3D::STENCIL:
- if (drawbuffer) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferiv", "buffer index must be 0");
- return;
- }
- // TODO: Call clearBufferiv, requires gl3.h and ES3/gl.h
- break;
- case GraphicsContext3D::DEPTH:
- case GraphicsContext3D::DEPTH_STENCIL:
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferiv", "buffer argument must be COLOR or STENCIL");
- break;
- }
-}
-
-void WebGL2RenderingContext::clearBufferuiv(GC3Denum buffer, GC3Dint drawbuffer, Uint32Array* value)
-{
- UNUSED_PARAM(value);
- switch (buffer) {
- case GraphicsContext3D::COLOR:
- if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferuiv", "buffer index out of range");
- return;
- }
- // TODO: Call clearBufferuiv, requires gl3.h and ES3/gl.h
- break;
- case GraphicsContext3D::DEPTH:
- case GraphicsContext3D::STENCIL:
- case GraphicsContext3D::DEPTH_STENCIL:
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferuiv", "buffer argument must be COLOR");
- break;
- }
-}
-
-void WebGL2RenderingContext::clearBufferfv(GC3Denum buffer, GC3Dint drawbuffer, Float32Array* value)
-{
- UNUSED_PARAM(value);
- switch (buffer) {
- case GraphicsContext3D::COLOR:
- if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferfv", "buffer index out of range");
- return;
- }
- // TODO: Call clearBufferfv, requires gl3.h and ES3/gl.h
- break;
- case GraphicsContext3D::DEPTH:
- if (drawbuffer) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferfv", "buffer index must be 0");
- return;
- }
- // TODO: Call clearBufferfv, requires gl3.h and ES3/gl.h
- break;
- case GraphicsContext3D::STENCIL:
- case GraphicsContext3D::DEPTH_STENCIL:
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferfv", "buffer argument must be COLOR OR DEPTH");
- break;
- }
-}
-
-void WebGL2RenderingContext::clearBufferfi(GC3Denum buffer, GC3Dint drawbuffer, GC3Dfloat depth, GC3Dint stencil)
-{
- UNUSED_PARAM(depth);
- UNUSED_PARAM(stencil);
- switch (buffer) {
- case GraphicsContext3D::DEPTH_STENCIL:
- if (drawbuffer) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferfv", "buffer index must be 0");
- return;
- }
- // TODO: Call clearBufferfi, requires gl3.h and ES3/gl.h
- break;
- case GraphicsContext3D::COLOR:
- case GraphicsContext3D::DEPTH:
- case GraphicsContext3D::STENCIL:
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferfv", "buffer argument must be DEPTH_STENCIL");
- break;
- }
-}
-
-PassRefPtr<WebGLQuery> WebGL2RenderingContext::createQuery()
-{
- return nullptr;
-}
-
-void WebGL2RenderingContext::deleteQuery(WebGLQuery* query)
-{
- UNUSED_PARAM(query);
-}
-
-GC3Dboolean WebGL2RenderingContext::isQuery(WebGLQuery* query)
-{
- UNUSED_PARAM(query);
- return false;
-}
-
-void WebGL2RenderingContext::beginQuery(GC3Denum target, WebGLQuery* query)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(query);
-}
-
-void WebGL2RenderingContext::endQuery(GC3Denum target)
-{
- UNUSED_PARAM(target);
-}
-
-PassRefPtr<WebGLQuery> WebGL2RenderingContext::getQuery(GC3Denum target, GC3Denum pname)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(pname);
- return nullptr;
-}
-
-WebGLGetInfo WebGL2RenderingContext::getQueryParameter(WebGLQuery* query, GC3Denum pname)
-{
- UNUSED_PARAM(query);
- UNUSED_PARAM(pname);
- return WebGLGetInfo();
-}
-
-PassRefPtr<WebGLSampler> WebGL2RenderingContext::createSampler()
-{
- return nullptr;
-}
-
-void WebGL2RenderingContext::deleteSampler(WebGLSampler* sampler)
-{
- UNUSED_PARAM(sampler);
-}
-
-GC3Dboolean WebGL2RenderingContext::isSampler(WebGLSampler* sampler)
-{
- UNUSED_PARAM(sampler);
- return false;
-}
-
-void WebGL2RenderingContext::bindSampler(GC3Duint unit, WebGLSampler* sampler)
-{
- UNUSED_PARAM(unit);
- UNUSED_PARAM(sampler);
-}
-
-void WebGL2RenderingContext::samplerParameteri(WebGLSampler* sampler, GC3Denum pname, GC3Dint param)
-{
- UNUSED_PARAM(sampler);
- UNUSED_PARAM(pname);
- UNUSED_PARAM(param);
-}
-
-void WebGL2RenderingContext::samplerParameterf(WebGLSampler* sampler, GC3Denum pname, GC3Dfloat param)
-{
- UNUSED_PARAM(sampler);
- UNUSED_PARAM(pname);
- UNUSED_PARAM(param);
-}
-
-WebGLGetInfo WebGL2RenderingContext::getSamplerParameter(WebGLSampler* sampler, GC3Denum pname)
-{
- UNUSED_PARAM(sampler);
- UNUSED_PARAM(pname);
- return WebGLGetInfo();
-}
-
-PassRefPtr<WebGLSync> WebGL2RenderingContext::fenceSync(GC3Denum condition, GC3Dbitfield flags)
-{
- UNUSED_PARAM(condition);
- UNUSED_PARAM(flags);
- return nullptr;
-}
-
-GC3Dboolean WebGL2RenderingContext::isSync(WebGLSync* sync)
-{
- UNUSED_PARAM(sync);
- return false;
-}
-
-void WebGL2RenderingContext::deleteSync(WebGLSync* sync)
-{
- UNUSED_PARAM(sync);
-}
-
-GC3Denum WebGL2RenderingContext::clientWaitSync(WebGLSync* sync, GC3Dbitfield flags, GC3Duint64 timeout)
-{
- UNUSED_PARAM(sync);
- UNUSED_PARAM(flags);
- UNUSED_PARAM(timeout);
- return 0;
-}
-
-void WebGL2RenderingContext::waitSync(WebGLSync* sync, GC3Dbitfield flags, GC3Duint64 timeout)
-{
- UNUSED_PARAM(sync);
- UNUSED_PARAM(flags);
- UNUSED_PARAM(timeout);
-}
-
-WebGLGetInfo WebGL2RenderingContext::getSyncParameter(WebGLSync* sync, GC3Denum pname)
-{
- UNUSED_PARAM(sync);
- UNUSED_PARAM(pname);
- return WebGLGetInfo();
-}
-
-PassRefPtr<WebGLTransformFeedback> WebGL2RenderingContext::createTransformFeedback()
-{
- return nullptr;
-}
-
-void WebGL2RenderingContext::deleteTransformFeedback(WebGLTransformFeedback* id)
-{
- UNUSED_PARAM(id);
-}
-
-GC3Dboolean WebGL2RenderingContext::isTransformFeedback(WebGLTransformFeedback* id)
-{
- UNUSED_PARAM(id);
- return false;
-}
-
-void WebGL2RenderingContext::bindTransformFeedback(GC3Denum target, WebGLTransformFeedback* id)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(id);
-}
-
-void WebGL2RenderingContext::beginTransformFeedback(GC3Denum primitiveMode)
-{
- UNUSED_PARAM(primitiveMode);
-}
-
-void WebGL2RenderingContext::endTransformFeedback()
-{
-}
-
-void WebGL2RenderingContext::transformFeedbackVaryings(WebGLProgram* program, Vector<String> varyings, GC3Denum bufferMode)
-{
- UNUSED_PARAM(program);
- UNUSED_PARAM(varyings);
- UNUSED_PARAM(bufferMode);
-}
-
-PassRefPtr<WebGLActiveInfo> WebGL2RenderingContext::getTransformFeedbackVarying(WebGLProgram* program, GC3Duint index)
-{
- UNUSED_PARAM(program);
- UNUSED_PARAM(index);
- return nullptr;
-}
-
-void WebGL2RenderingContext::pauseTransformFeedback()
-{
-}
-
-void WebGL2RenderingContext::resumeTransformFeedback()
-{
-}
-
-void WebGL2RenderingContext::bindBufferBase(GC3Denum target, GC3Duint index, WebGLBuffer* buffer)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(index);
- UNUSED_PARAM(buffer);
-}
-
-void WebGL2RenderingContext::bindBufferRange(GC3Denum target, GC3Duint index, WebGLBuffer* buffer, GC3Dint64 offset, GC3Dint64 size)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(index);
- UNUSED_PARAM(buffer);
- UNUSED_PARAM(offset);
- UNUSED_PARAM(size);
-}
-
-WebGLGetInfo WebGL2RenderingContext::getIndexedParameter(GC3Denum target, GC3Duint index)
-{
- UNUSED_PARAM(target);
- UNUSED_PARAM(index);
- switch (target) {
- case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_BINDING:
- case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_SIZE:
- case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_START:
- case GraphicsContext3D::UNIFORM_BUFFER_BINDING:
- case GraphicsContext3D::UNIFORM_BUFFER_SIZE:
- case GraphicsContext3D::UNIFORM_BUFFER_START:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getIndexedParameter", "parameter name not yet supported");
- return WebGLGetInfo();
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getIndexedParameter", "invalid parameter name");
- return WebGLGetInfo();
-
- }
- return WebGLGetInfo();
-}
-
-Uint32Array* WebGL2RenderingContext::getUniformIndices(WebGLProgram* program, Vector<String> uniformNames)
-{
- UNUSED_PARAM(program);
- UNUSED_PARAM(uniformNames);
- return nullptr;
-}
-
-Int32Array* WebGL2RenderingContext::getActiveUniforms(WebGLProgram* program, Uint32Array* uniformIndices, GC3Denum pname)
-{
- UNUSED_PARAM(program);
- UNUSED_PARAM(uniformIndices);
- UNUSED_PARAM(pname);
- return nullptr;
-}
-
-GC3Duint WebGL2RenderingContext::getUniformBlockIndex(WebGLProgram* program, String uniformBlockName)
-{
- UNUSED_PARAM(program);
- UNUSED_PARAM(uniformBlockName);
- return 0;
-}
-
-WebGLGetInfo WebGL2RenderingContext::getActiveUniformBlockParameter(WebGLProgram* program, GC3Duint uniformBlockIndex, GC3Denum pname)
-{
- UNUSED_PARAM(program);
- UNUSED_PARAM(uniformBlockIndex);
- UNUSED_PARAM(pname);
- return WebGLGetInfo();
-}
-
-WebGLGetInfo WebGL2RenderingContext::getActiveUniformBlockName(WebGLProgram* program, GC3Duint uniformBlockIndex)
-{
- UNUSED_PARAM(program);
- UNUSED_PARAM(uniformBlockIndex);
- return WebGLGetInfo();
-}
-
-void WebGL2RenderingContext::uniformBlockBinding(WebGLProgram* program, GC3Duint uniformBlockIndex, GC3Duint uniformBlockBinding)
-{
- UNUSED_PARAM(program);
- UNUSED_PARAM(uniformBlockIndex);
- UNUSED_PARAM(uniformBlockBinding);
-}
-
-PassRefPtr<WebGLVertexArrayObject> WebGL2RenderingContext::createVertexArray()
-{
- if (isContextLost())
- return 0;
-
- RefPtr<WebGLVertexArrayObject> o = WebGLVertexArrayObject::create(this, WebGLVertexArrayObject::VAOTypeUser);
- addContextObject(o.get());
- return o.release();
-}
-
-void WebGL2RenderingContext::deleteVertexArray(WebGLVertexArrayObject* arrayObject)
-{
- if (!arrayObject || isContextLost())
- return;
-
- if (arrayObject->isDeleted())
- return;
-
- if (!arrayObject->isDefaultObject() && arrayObject == m_boundVertexArrayObject)
- setBoundVertexArrayObject(0);
-
- arrayObject->deleteObject(graphicsContext3D());
-}
-
-GC3Dboolean WebGL2RenderingContext::isVertexArray(WebGLVertexArrayObject* arrayObject)
-{
- if (!arrayObject || isContextLost())
- return 0;
-
- if (!arrayObject->hasEverBeenBound() || !arrayObject->validate(0, this))
- return 0;
-
- return m_context->isVertexArray(arrayObject->object());
-}
-
-void WebGL2RenderingContext::bindVertexArray(WebGLVertexArrayObject* arrayObject)
-{
- if (isContextLost())
- return;
-
- if (arrayObject && (arrayObject->isDeleted() || !arrayObject->validate(0, this) || !m_contextObjects.contains(arrayObject))) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
- return;
- }
- if (arrayObject && !arrayObject->isDefaultObject() && arrayObject->object()) {
- m_context->bindVertexArray(arrayObject->object());
-
- arrayObject->setHasEverBeenBound();
- setBoundVertexArrayObject(arrayObject);
- } else {
- m_context->bindVertexArray(m_defaultVertexArrayObject->object());
- setBoundVertexArrayObject(m_defaultVertexArrayObject);
- }
-}
-
-WebGLExtension* WebGL2RenderingContext::getExtension(const String& name)
-{
- if (isContextLostOrPending())
- return nullptr;
-
- if (equalIgnoringCase(name, "WEBKIT_EXT_texture_filter_anisotropic")
- && m_context->getExtensions()->supports("GL_EXT_texture_filter_anisotropic")) {
- if (!m_extTextureFilterAnisotropic) {
- m_context->getExtensions()->ensureEnabled("GL_EXT_texture_filter_anisotropic");
- m_extTextureFilterAnisotropic = std::make_unique<EXTTextureFilterAnisotropic>(this);
- }
- return m_extTextureFilterAnisotropic.get();
- }
- if (equalIgnoringCase(name, "OES_texture_float")
- && m_context->getExtensions()->supports("GL_OES_texture_float")) {
- if (!m_oesTextureFloat) {
- m_context->getExtensions()->ensureEnabled("GL_OES_texture_float");
- m_oesTextureFloat = std::make_unique<OESTextureFloat>(this);
- }
- return m_oesTextureFloat.get();
- }
- if (equalIgnoringCase(name, "OES_texture_float_linear")
- && m_context->getExtensions()->supports("GL_OES_texture_float_linear")) {
- if (!m_oesTextureFloatLinear) {
- m_context->getExtensions()->ensureEnabled("GL_OES_texture_float_linear");
- m_oesTextureFloatLinear = std::make_unique<OESTextureFloatLinear>(this);
- }
- return m_oesTextureFloatLinear.get();
- }
- if (equalIgnoringCase(name, "OES_texture_half_float")
- && m_context->getExtensions()->supports("GL_OES_texture_half_float")) {
- if (!m_oesTextureHalfFloat) {
- m_context->getExtensions()->ensureEnabled("GL_OES_texture_half_float");
- m_oesTextureHalfFloat = std::make_unique<OESTextureHalfFloat>(this);
- }
- return m_oesTextureHalfFloat.get();
- }
- if (equalIgnoringCase(name, "OES_texture_half_float_linear")
- && m_context->getExtensions()->supports("GL_OES_texture_half_float_linear")) {
- if (!m_oesTextureHalfFloatLinear) {
- m_context->getExtensions()->ensureEnabled("GL_OES_texture_half_float_linear");
- m_oesTextureHalfFloatLinear = std::make_unique<OESTextureHalfFloatLinear>(this);
- }
- return m_oesTextureHalfFloatLinear.get();
- }
- if (equalIgnoringCase(name, "WEBGL_lose_context")) {
- if (!m_webglLoseContext)
- m_webglLoseContext = std::make_unique<WebGLLoseContext>(this);
- return m_webglLoseContext.get();
- }
- if ((equalIgnoringCase(name, "WEBKIT_WEBGL_compressed_texture_atc"))
- && WebGLCompressedTextureATC::supported(this)) {
- if (!m_webglCompressedTextureATC)
- m_webglCompressedTextureATC = std::make_unique<WebGLCompressedTextureATC>(this);
- return m_webglCompressedTextureATC.get();
- }
- if ((equalIgnoringCase(name, "WEBKIT_WEBGL_compressed_texture_pvrtc"))
- && WebGLCompressedTexturePVRTC::supported(this)) {
- if (!m_webglCompressedTexturePVRTC)
- m_webglCompressedTexturePVRTC = std::make_unique<WebGLCompressedTexturePVRTC>(this);
- return m_webglCompressedTexturePVRTC.get();
- }
- if (equalIgnoringCase(name, "WEBGL_compressed_texture_s3tc")
- && WebGLCompressedTextureS3TC::supported(this)) {
- if (!m_webglCompressedTextureS3TC)
- m_webglCompressedTextureS3TC = std::make_unique<WebGLCompressedTextureS3TC>(this);
- return m_webglCompressedTextureS3TC.get();
- }
- if (equalIgnoringCase(name, "WEBGL_depth_texture")
- && WebGLDepthTexture::supported(graphicsContext3D())) {
- if (!m_webglDepthTexture) {
- m_context->getExtensions()->ensureEnabled("GL_CHROMIUM_depth_texture");
- m_webglDepthTexture = std::make_unique<WebGLDepthTexture>(this);
- }
- return m_webglDepthTexture.get();
- }
- if (allowPrivilegedExtensions()) {
- if (equalIgnoringCase(name, "WEBGL_debug_renderer_info")) {
- if (!m_webglDebugRendererInfo)
- m_webglDebugRendererInfo = std::make_unique<WebGLDebugRendererInfo>(this);
- return m_webglDebugRendererInfo.get();
- }
- if (equalIgnoringCase(name, "WEBGL_debug_shaders")
- && m_context->getExtensions()->supports("GL_ANGLE_translated_shader_source")) {
- if (!m_webglDebugShaders)
- m_webglDebugShaders = std::make_unique<WebGLDebugShaders>(this);
- return m_webglDebugShaders.get();
- }
- }
-
- return nullptr;
-}
-
-Vector<String> WebGL2RenderingContext::getSupportedExtensions()
-{
- Vector<String> result;
-
- if (m_isPendingPolicyResolution)
- return result;
-
- if (m_context->getExtensions()->supports("GL_OES_texture_float"))
- result.append("OES_texture_float");
- if (m_context->getExtensions()->supports("GL_OES_texture_float_linear"))
- result.append("OES_texture_float_linear");
- if (m_context->getExtensions()->supports("GL_OES_texture_half_float"))
- result.append("OES_texture_half_float");
- if (m_context->getExtensions()->supports("GL_OES_texture_half_float_linear"))
- result.append("OES_texture_half_float_linear");
- if (m_context->getExtensions()->supports("GL_EXT_texture_filter_anisotropic"))
- result.append("WEBKIT_EXT_texture_filter_anisotropic");
- if (WebGLCompressedTextureATC::supported(this))
- result.append("WEBKIT_WEBGL_compressed_texture_atc");
- if (WebGLCompressedTexturePVRTC::supported(this))
- result.append("WEBKIT_WEBGL_compressed_texture_pvrtc");
- if (WebGLCompressedTextureS3TC::supported(this))
- result.append("WEBGL_compressed_texture_s3tc");
- if (WebGLDepthTexture::supported(graphicsContext3D()))
- result.append("WEBGL_depth_texture");
- result.append("WEBGL_lose_context");
- if (allowPrivilegedExtensions()) {
- if (m_context->getExtensions()->supports("GL_ANGLE_translated_shader_source"))
- result.append("WEBGL_debug_shaders");
- result.append("WEBGL_debug_renderer_info");
- }
-
- return result;
-}
-
-WebGLGetInfo WebGL2RenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
- return WebGLGetInfo();
-
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound");
- return WebGLGetInfo();
- }
-
- WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(attachment);
- if (!object) {
- if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
- return WebGLGetInfo(GraphicsContext3D::NONE);
- // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
- // specifies INVALID_OPERATION.
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-
- ASSERT(object->isTexture() || object->isRenderbuffer());
- if (object->isTexture()) {
- switch (pname) {
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- return WebGLGetInfo(GraphicsContext3D::TEXTURE);
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(reinterpret_cast<WebGLTexture*>(object)));
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: {
- GC3Dint value = 0;
- m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
- return WebGLGetInfo(value);
- }
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment");
- return WebGLGetInfo();
- }
- } else {
- switch (pname) {
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- return WebGLGetInfo(GraphicsContext3D::RENDERBUFFER);
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(reinterpret_cast<WebGLRenderbuffer*>(object)));
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING : {
- WebGLRenderbuffer* renderBuffer = reinterpret_cast<WebGLRenderbuffer*>(object);
- GC3Denum renderBufferFormat = renderBuffer->getInternalFormat();
- if (renderBufferFormat == GraphicsContext3D::SRGB8_ALPHA8
- || renderBufferFormat == GraphicsContext3D::COMPRESSED_SRGB8_ETC2
- || renderBufferFormat == GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
- || renderBufferFormat == GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) {
- return WebGLGetInfo(GraphicsContext3D::SRGB);
- }
- return WebGLGetInfo(GraphicsContext3D::LINEAR);
- }
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
- return WebGLGetInfo();
- }
- }
-}
-
-bool WebGL2RenderingContext::validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment)
-{
- if (target != GraphicsContext3D::FRAMEBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
- return false;
- }
- switch (attachment) {
- case GraphicsContext3D::COLOR_ATTACHMENT0:
- case GraphicsContext3D::DEPTH_ATTACHMENT:
- case GraphicsContext3D::STENCIL_ATTACHMENT:
- case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
- break;
- default:
- if (attachment > GraphicsContext3D::COLOR_ATTACHMENT0
- && attachment < static_cast<GC3Denum>(GraphicsContext3D::COLOR_ATTACHMENT0 + getMaxColorAttachments()))
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid attachment");
- return false;
- }
- return true;
-}
-
-GC3Dint WebGL2RenderingContext::getMaxDrawBuffers()
-{
- if (!m_maxDrawBuffers)
- m_context->getIntegerv(GraphicsContext3D::MAX_DRAW_BUFFERS, &m_maxDrawBuffers);
- return m_maxDrawBuffers;
-}
-
-GC3Dint WebGL2RenderingContext::getMaxColorAttachments()
-{
- // DrawBuffers requires MAX_COLOR_ATTACHMENTS == MAX_DRAW_BUFFERS
- if (!m_maxColorAttachments)
- m_context->getIntegerv(GraphicsContext3D::MAX_DRAW_BUFFERS, &m_maxColorAttachments);
- return m_maxColorAttachments;
-}
-
-void WebGL2RenderingContext::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLostOrPending())
- return;
- if (target != GraphicsContext3D::RENDERBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid target");
- return;
- }
- if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
- return;
- }
- if (!validateSize("renderbufferStorage", width, height))
- return;
- switch (internalformat) {
- case GraphicsContext3D::DEPTH_COMPONENT16:
- case GraphicsContext3D::DEPTH_COMPONENT32F:
- case GraphicsContext3D::DEPTH_COMPONENT24:
- case GraphicsContext3D::RGBA32I:
- case GraphicsContext3D::RGBA32UI:
- case GraphicsContext3D::RGBA16I:
- case GraphicsContext3D::RGBA16UI:
- case GraphicsContext3D::RGBA8:
- case GraphicsContext3D::RGBA8I:
- case GraphicsContext3D::RGBA8UI:
- case GraphicsContext3D::RGB10_A2:
- case GraphicsContext3D::RGB10_A2UI:
- case GraphicsContext3D::RGBA4:
- case GraphicsContext3D::RG32I:
- case GraphicsContext3D::RG32UI:
- case GraphicsContext3D::RG16I:
- case GraphicsContext3D::RG16UI:
- case GraphicsContext3D::RG8:
- case GraphicsContext3D::RG8I:
- case GraphicsContext3D::RG8UI:
- case GraphicsContext3D::R32I:
- case GraphicsContext3D::R32UI:
- case GraphicsContext3D::R16I:
- case GraphicsContext3D::R16UI:
- case GraphicsContext3D::R8:
- case GraphicsContext3D::R8I:
- case GraphicsContext3D::R8UI:
- case GraphicsContext3D::RGB5_A1:
- case GraphicsContext3D::RGB565:
- case GraphicsContext3D::STENCIL_INDEX8:
- case GraphicsContext3D::SRGB8_ALPHA8:
- m_context->renderbufferStorage(target, internalformat, width, height);
- m_renderbufferBinding->setInternalFormat(internalformat);
- m_renderbufferBinding->setIsValid(true);
- m_renderbufferBinding->setSize(width, height);
- break;
- case GraphicsContext3D::DEPTH32F_STENCIL8:
- case GraphicsContext3D::DEPTH24_STENCIL8:
- if (!isDepthStencilSupported()) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
- return;
- }
- m_context->renderbufferStorage(target, internalformat, width, height);
- m_renderbufferBinding->setSize(width, height);
- m_renderbufferBinding->setIsValid(isDepthStencilSupported());
- m_renderbufferBinding->setInternalFormat(internalformat);
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
- return;
- }
- applyStencilTest();
-}
-
-void WebGL2RenderingContext::hint(GC3Denum target, GC3Denum mode)
-{
- if (isContextLostOrPending())
- return;
- bool isValid = false;
- switch (target) {
- case GraphicsContext3D::GENERATE_MIPMAP_HINT:
- case GraphicsContext3D::FRAGMENT_SHADER_DERIVATIVE_HINT:
- isValid = true;
- break;
- }
- if (!isValid) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "hint", "invalid target");
- return;
- }
- m_context->hint(target, mode);
-}
-
-void WebGL2RenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
-{
- if (isContextLostOrPending())
- return;
- RefPtr<WebGLContextAttributes> attributes = getContextAttributes();
- GC3Denum bufferFormat = attributes->alpha() ? GraphicsContext3D::RGBA : GraphicsContext3D::RGB;
- if (!validateTexFuncParameters("copyTexImage2D", CopyTexImage, target, level, internalformat, width, height, border, bufferFormat, GraphicsContext3D::UNSIGNED_BYTE))
- return;
- if (!validateSettableTexFormat("copyTexImage2D", internalformat))
- return;
- WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
- if (!tex)
- return;
- if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
- return;
- }
- if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
- return;
- }
- clearIfComposited();
- if (isResourceSafe())
- m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
- else {
- GC3Dint clippedX, clippedY;
- GC3Dsizei clippedWidth, clippedHeight;
- if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
- m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border,
- internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);
- if (clippedWidth > 0 && clippedHeight > 0) {
- m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
- clippedX, clippedY, clippedWidth, clippedHeight);
- }
- } else
- m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
- }
- // FIXME: if the framebuffer is not complete, none of the below should be executed.
- tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
-}
-
-void WebGL2RenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec)
-{
- ec = 0;
- ASSERT(!isContextLost());
- if (!validateTexFuncParameters("texSubImage2D", TexSubImage, target, level, internalformat, width, height, 0, format, type))
- return;
- ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
- ASSERT(validateSettableTexFormat("texSubImage2D", format));
- WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
- if (!tex) {
- ASSERT_NOT_REACHED();
- return;
- }
- ASSERT((xoffset + width) >= 0);
- ASSERT((yoffset + height) >= 0);
- ASSERT(tex->getWidth(target, level) >= (xoffset + width));
- ASSERT(tex->getHeight(target, level) >= (yoffset + height));
- ASSERT(tex->getInternalFormat(target, level) == format);
- ASSERT(tex->getType(target, level) == type);
- m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
-}
-
-void WebGL2RenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
-{
- ec = 0;
- Vector<uint8_t> data;
- GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
- if (!imageExtractor.extractSucceeded()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image");
- return;
- }
- GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
- GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
- const void* imagePixelData = imageExtractor.imagePixelData();
-
- bool needConversion = true;
- if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
- needConversion = false;
- else {
- if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- }
-
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
-
- WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
- GC3Denum internalformat = tex->getInternalFormat(target, level);
- texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), internalformat, format, type, needConversion ? data.data() : imagePixelData, ec);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
-{
- if (isContextLostOrPending() || !validateTexFuncData("texSubImage2D", level, width, height, GraphicsContext3D::NONE, format, type, pixels, NullNotAllowed) || !validateTexFunc("texSubImage2D", TexSubImage, SourceArrayBufferView, target, level, GraphicsContext3D::NONE, width, height, 0, format, type, xoffset, yoffset))
- return;
-
- void* data = pixels->baseAddress();
- Vector<uint8_t> tempData;
- bool changeUnpackAlignment = false;
- if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
- if (!m_context->extractTextureData(width, height, format, type,
- m_unpackAlignment,
- m_unpackFlipY, m_unpackPremultiplyAlpha,
- data,
- tempData))
- return;
- data = tempData.data();
- changeUnpackAlignment = true;
- }
- if (changeUnpackAlignment)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
- GC3Denum internalformat = tex->getInternalFormat(target, level);
- texSubImage2DBase(target, level, xoffset, yoffset, width, height, internalformat, format, type, data, ec);
- if (changeUnpackAlignment)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLostOrPending() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage, SourceImageData, target, level, GraphicsContext3D::NONE, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
- return;
-
- Vector<uint8_t> data;
- bool needConversion = true;
- // The data from ImageData is always of format RGBA8.
- // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
- if (format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
- needConversion = false;
- else {
- if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image data");
- return;
- }
- }
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
-
- WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
- GC3Denum internalformat = tex->getInternalFormat(target, level);
- texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), internalformat, format, type, needConversion ? data.data() : pixels->data()->data(), ec);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLostOrPending() || !validateHTMLImageElement("texSubImage2D", image, ec))
- return;
-
- RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
- if (imageForRender->isSVGImage())
- imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), 1);
-
- if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLImageElement, target, level, GraphicsContext3D::NONE, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
- return;
-
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-
-void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLostOrPending() || !validateHTMLCanvasElement("texSubImage2D", canvas, ec)
- || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, GraphicsContext3D::NONE, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
- return;
-
- RefPtr<ImageData> imageData = canvas->getImageData();
- if (imageData)
- texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec);
- else
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-
-#if ENABLE(VIDEO)
-void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLostOrPending() || !validateHTMLVideoElement("texSubImage2D", video, ec)
- || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, target, level, GraphicsContext3D::NONE, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
- return;
-
- RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);
- if (!image)
- return;
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-#endif
-
-bool WebGL2RenderingContext::validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType functionType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type)
-{
- if (functionType == CopyTexImage) {
- GC3Denum framebufferInternalFormat = 0;
- WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(GraphicsContext3D::COLOR_ATTACHMENT0);
- if (object->isTexture()) {
- WebGLTexture* texture = reinterpret_cast<WebGLTexture*>(object);
- framebufferInternalFormat = baseInternalFormatFromInternalFormat(texture->getInternalFormat(GraphicsContext3D::TEXTURE_2D, 0));
- } else if (object->isRenderbuffer()) {
- WebGLRenderbuffer* renderBuffer = reinterpret_cast<WebGLRenderbuffer*>(object);
- framebufferInternalFormat = baseInternalFormatFromInternalFormat(renderBuffer->getInternalFormat());
- }
-
- GC3Denum baseTextureInternalFormat = baseInternalFormatFromInternalFormat(internalformat);
- bool validFormatCombination = true;
- switch (framebufferInternalFormat) {
- case GraphicsContext3D::RED:
- if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::RED)
- validFormatCombination = false;
- break;
- case GraphicsContext3D::RG:
- if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::RED && baseTextureInternalFormat != GraphicsContext3D::RG)
- validFormatCombination = false;
- break;
- case GraphicsContext3D::RGB:
- if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::RED && baseTextureInternalFormat != GraphicsContext3D::RG && baseTextureInternalFormat != GraphicsContext3D::RGB)
- validFormatCombination = false;
- break;
- case GraphicsContext3D::RGBA:
- if (baseTextureInternalFormat != GraphicsContext3D::ALPHA && baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::LUMINANCE_ALPHA && baseTextureInternalFormat != GraphicsContext3D::RED && baseTextureInternalFormat != GraphicsContext3D::RG && baseTextureInternalFormat != GraphicsContext3D::RGB && baseTextureInternalFormat != GraphicsContext3D::RGBA)
- validFormatCombination = false;
- break;
- case GraphicsContext3D::DEPTH_COMPONENT:
- validFormatCombination = false;
- break;
- case GraphicsContext3D::DEPTH_STENCIL:
- validFormatCombination = false;
- break;
- }
-
- if (!validFormatCombination) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "copyTexImage: invalid combination of framebuffer and texture formats");
- return false;
- }
-
- ExceptionCode ec;
- bool isSRGB = (getFramebufferAttachmentParameter(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, ec).getInt() == GraphicsContext3D::SRGB);
- if (isSRGB != (framebufferInternalFormat == GraphicsContext3D::SRGB8 || framebufferInternalFormat == GraphicsContext3D::SRGB8_ALPHA8)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "framebuffer attachment color encoding and internal format do not match");
- return false;
- }
- }
-
- // We absolutely have to validate the format and type combination.
- // The texImage2D entry points taking HTMLImage, etc. will produce
- // temporary data based on this combination, so it must be legal.
- if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level) || !validateTexFuncLevel(functionName, target, level))
- return false;
-
- if (width < 0 || height < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
- return false;
- }
-
- GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);
- switch (target) {
- case GraphicsContext3D::TEXTURE_2D:
- if (width > maxTextureSizeForLevel || height > maxTextureSizeForLevel) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range");
- return false;
- }
- break;
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (functionType != TexSubImage && width != height) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");
- return false;
- }
- // No need to check height here. For texImage width == height.
- // For texSubImage that will be checked when checking yoffset + height is in range.
- if (width > maxTextureSizeForLevel) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range for cube map");
- return false;
- }
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
- return false;
- }
-
- if (border) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0");
- return false;
- }
-
- return true;
-}
-
-bool WebGL2RenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level)
-{
- // Verify that a valid format has been provided.
- switch (format) {
- case GraphicsContext3D::ALPHA:
- case GraphicsContext3D::LUMINANCE:
- case GraphicsContext3D::LUMINANCE_ALPHA:
- case GraphicsContext3D::RGB:
- case GraphicsContext3D::RGBA:
- case GraphicsContext3D::RGBA_INTEGER:
- case GraphicsContext3D::RG:
- case GraphicsContext3D::RG_INTEGER:
- case GraphicsContext3D::RED_INTEGER:
- break;
- case GraphicsContext3D::DEPTH_STENCIL:
- case GraphicsContext3D::DEPTH_COMPONENT:
- if (m_webglDepthTexture)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled");
- return false;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format");
- return false;
- }
-
- // Verify that a valid type has been provided.
- switch (type) {
- case GraphicsContext3D::UNSIGNED_BYTE:
- case GraphicsContext3D::BYTE:
- case GraphicsContext3D::UNSIGNED_SHORT:
- case GraphicsContext3D::SHORT:
- case GraphicsContext3D::UNSIGNED_INT:
- case GraphicsContext3D::INT:
- case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
- case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
- case GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV:
- case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
- case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
- case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
- break;
- case GraphicsContext3D::FLOAT:
- if (m_oesTextureFloat)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
- return false;
- case GraphicsContext3D::HALF_FLOAT:
- case GraphicsContext3D::HALF_FLOAT_OES:
- if (m_oesTextureHalfFloat)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
- return false;
- case GraphicsContext3D::UNSIGNED_INT_24_8:
- case GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV:
- if (isDepthStencilSupported())
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
- return false;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
- return false;
- }
-
- // Veryify that a valid internal format has been provided.
- switch (internalformat) {
- case GraphicsContext3D::RGBA:
- case GraphicsContext3D::RGB:
- case GraphicsContext3D::LUMINANCE_ALPHA:
- case GraphicsContext3D::LUMINANCE:
- case GraphicsContext3D::ALPHA:
- case GraphicsContext3D::RGBA32I:
- case GraphicsContext3D::RGBA32UI:
- case GraphicsContext3D::RGBA16I:
- case GraphicsContext3D::RGBA16UI:
- case GraphicsContext3D::RGBA8:
- case GraphicsContext3D::RGBA8I:
- case GraphicsContext3D::RGBA8UI:
- case GraphicsContext3D::RGB10_A2:
- case GraphicsContext3D::RGB10_A2UI:
- case GraphicsContext3D::RGBA4:
- case GraphicsContext3D::RG32I:
- case GraphicsContext3D::RG32UI:
- case GraphicsContext3D::RG16I:
- case GraphicsContext3D::RG16UI:
- case GraphicsContext3D::RG8:
- case GraphicsContext3D::RG8I:
- case GraphicsContext3D::RG8UI:
- case GraphicsContext3D::R32I:
- case GraphicsContext3D::R32UI:
- case GraphicsContext3D::R16I:
- case GraphicsContext3D::R16UI:
- case GraphicsContext3D::R8:
- case GraphicsContext3D::R8I:
- case GraphicsContext3D::R8UI:
- case GraphicsContext3D::RGB5_A1:
- case GraphicsContext3D::RGB8:
- case GraphicsContext3D::RGB565:
- case GraphicsContext3D::RGBA32F:
- case GraphicsContext3D::RGBA16F:
- case GraphicsContext3D::RGBA8_SNORM:
- case GraphicsContext3D::RGB32F:
- case GraphicsContext3D::RGB32I:
- case GraphicsContext3D::RGB32UI:
- case GraphicsContext3D::RGB16F:
- case GraphicsContext3D::RGB16I:
- case GraphicsContext3D::RGB16UI:
- case GraphicsContext3D::RGB8_SNORM:
- case GraphicsContext3D::RGB8I:
- case GraphicsContext3D::RGB8UI:
- case GraphicsContext3D::SRGB8:
- case GraphicsContext3D::SRGB8_ALPHA8:
- case GraphicsContext3D::R11F_G11F_B10F:
- case GraphicsContext3D::RGB9_E5:
- case GraphicsContext3D::RG32F:
- case GraphicsContext3D::RG16F:
- case GraphicsContext3D::RG8_SNORM:
- case GraphicsContext3D::R32F:
- case GraphicsContext3D::R16F:
- case GraphicsContext3D::R8_SNORM:
- case GraphicsContext3D::STENCIL_INDEX8:
- break;
- case GraphicsContext3D::DEPTH_COMPONENT16:
- case GraphicsContext3D::DEPTH_COMPONENT32F:
- case GraphicsContext3D::DEPTH_COMPONENT24:
- if (m_webglDepthTexture)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled");
- return false;
- case GraphicsContext3D::DEPTH32F_STENCIL8:
- case GraphicsContext3D::DEPTH24_STENCIL8:
- if (isDepthStencilSupported())
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture internal format");
- return false;
- case GraphicsContext3D::NONE:
- // When calling validateTexFuncFormatAndType with internalformat == GraphicsContext3D::NONE, the intent is
- // only to check for whether or not the format and type are valid types, which we have already done at this point.
- return true;
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture internal format");
- return false;
- }
-
- // Verify that the combination of format, internalformat and type is supported.
- switch (format) {
- case GraphicsContext3D::RGBA:
- if (type == GraphicsContext3D::UNSIGNED_BYTE
- && (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGBA8 || internalformat == GraphicsContext3D::RGB5_A1 || internalformat == GraphicsContext3D::RGBA4 || internalformat == GraphicsContext3D::SRGB8_ALPHA8))
- break;
- if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGBA8_SNORM)
- break;
- if (type == GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
- && (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGBA4))
- break;
- if (type == GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1
- && (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGB5_A1))
- break;
- if (type == GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV
- && (internalformat == GraphicsContext3D::RGB10_A2 || internalformat == GraphicsContext3D::RGB5_A1))
- break;
- if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) && internalformat == GraphicsContext3D::RGBA16F)
- break;
- if (type == GraphicsContext3D::FLOAT
- && (internalformat == GraphicsContext3D::RGBA32F || internalformat == GraphicsContext3D::RGBA16F))
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
- return false;
- case GraphicsContext3D::RGBA_INTEGER:
- if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RGBA8UI)
- break;
- if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGBA8I)
- break;
- if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::RGBA16UI)
- break;
- if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::RGBA16I)
- break;
- if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::RGBA32UI)
- break;
- if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::RGBA32I)
- break;
- if (type == GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV && internalformat == GraphicsContext3D::RGB10_A2UI)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
- return false;
- case GraphicsContext3D::RGB:
- if (type == GraphicsContext3D::UNSIGNED_BYTE
- && (internalformat == GraphicsContext3D::RGB || internalformat == GraphicsContext3D::RGB8 || internalformat == GraphicsContext3D::RGB565
- || internalformat == GraphicsContext3D::SRGB8))
- break;
- if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGB8_SNORM)
- break;
- if (type == GraphicsContext3D::UNSIGNED_SHORT_5_6_5
- && (internalformat == GraphicsContext3D::RGB || internalformat == GraphicsContext3D::RGB565))
- break;
- if (type == GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV && internalformat == GraphicsContext3D::R11F_G11F_B10F)
- break;
- if (type == GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV && internalformat == GraphicsContext3D::RGB9_E5)
- break;
- if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES)
- && (internalformat == GraphicsContext3D::RGB16F || internalformat == GraphicsContext3D::R11F_G11F_B10F || internalformat == GraphicsContext3D::RGB9_E5))
- break;
- if (type == GraphicsContext3D::FLOAT
- && (internalformat == GraphicsContext3D::RGB32F || internalformat == GraphicsContext3D::RGB16F || internalformat == GraphicsContext3D::R11F_G11F_B10F || internalformat == GraphicsContext3D::RGB9_E5))
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
- return false;
- case GraphicsContext3D::RGB_INTEGER:
- if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RGB8UI)
- break;
- if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGB8I)
- break;
- if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::RGB16UI)
- break;
- if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::RGB16I)
- break;
- if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::RGB32UI)
- break;
- if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::RGB32I)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
- return false;
- case GraphicsContext3D::RG:
- if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RG8)
- break;
- if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RG8_SNORM)
- break;
- if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) && internalformat == GraphicsContext3D::RG16F)
- break;
- if (type == GraphicsContext3D::FLOAT
- && (internalformat == GraphicsContext3D::RG32F || internalformat == GraphicsContext3D::RG16F))
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
- return false;
- case GraphicsContext3D::RG_INTEGER:
- if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RG8UI)
- break;
- if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RG8I)
- break;
- if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::RG16UI)
- break;
- if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::RG16I)
- break;
- if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::RG32UI)
- break;
- if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::RG32I)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
- return false;
- case GraphicsContext3D::RED:
- if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::R8)
- break;
- if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::R8_SNORM)
- break;
- if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) && internalformat == GraphicsContext3D::R16F)
- break;
- if (type == GraphicsContext3D::FLOAT
- && (internalformat == GraphicsContext3D::R32F || internalformat == GraphicsContext3D::R16F))
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
- return false;
- case GraphicsContext3D::RED_INTEGER:
- if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::R8UI)
- break;
- if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::R8I)
- break;
- if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::R16UI)
- break;
- if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::R16I)
- break;
- if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::R32UI)
- break;
- if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::R32I)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
- return false;
- case GraphicsContext3D::DEPTH_COMPONENT:
- if (!m_webglDepthTexture) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");
- return false;
- }
- if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::DEPTH_COMPONENT16)
- break;
- if (type == GraphicsContext3D::UNSIGNED_INT
- && (internalformat == GraphicsContext3D::DEPTH_COMPONENT24 || internalformat == GraphicsContext3D::DEPTH_COMPONENT16))
- break;
- if (type == GraphicsContext3D::FLOAT && internalformat == GraphicsContext3D::DEPTH_COMPONENT32F)
- break;
- if (level > 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
- return false;
- }
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
- return false;
- case GraphicsContext3D::DEPTH_STENCIL:
- if (!m_webglDepthTexture || !isDepthStencilSupported()) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");
- return false;
- }
- if (type == GraphicsContext3D::UNSIGNED_INT_24_8 && internalformat == GraphicsContext3D::DEPTH24_STENCIL8)
- break;
- if (type == GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV && internalformat == GraphicsContext3D::DEPTH32F_STENCIL8)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
- return false;
- case GraphicsContext3D::ALPHA:
- case GraphicsContext3D::LUMINANCE:
- case GraphicsContext3D::LUMINANCE_ALPHA:
- if ((type == GraphicsContext3D::UNSIGNED_BYTE || type == GraphicsContext3D::HALF_FLOAT_OES || type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::FLOAT) && internalformat == format)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
- return false;
- default:
- ASSERT_NOT_REACHED();
- }
-
- return true;
-}
-
-bool WebGL2RenderingContext::validateTexFuncData(const char* functionName, GC3Dint level,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum internalformat, GC3Denum format, GC3Denum type,
- ArrayBufferView* pixels,
- NullDisposition disposition)
-{
- if (!pixels) {
- if (disposition == NullAllowed)
- return true;
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels");
- return false;
- }
-
- if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level))
- return false;
- if (!validateSettableTexFormat(functionName, format))
- return false;
-
- switch (type) {
- case GraphicsContext3D::BYTE:
- if (pixels->getType() != JSC::TypeInt8) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type BYTE but ArrayBufferView not Int8Array");
- return false;
- }
- break;
- case GraphicsContext3D::UNSIGNED_BYTE:
- if (pixels->getType() != JSC::TypeUint8) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
- return false;
- }
- break;
- case GraphicsContext3D::SHORT:
- if (pixels->getType() != JSC::TypeInt16) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type SHORT but ArrayBufferView not Int16Array");
- return false;
- }
- break;
- case GraphicsContext3D::UNSIGNED_SHORT:
- case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
- case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
- case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
- if (pixels->getType() != JSC::TypeUint16) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
- return false;
- }
- break;
- case GraphicsContext3D::INT:
- if (pixels->getType() != JSC::TypeInt32) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type INT but ArrayBufferView not Int32Array");
- return false;
- }
- break;
- case GraphicsContext3D::UNSIGNED_INT:
- case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
- case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
- if (pixels->getType() != JSC::TypeUint32) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_INT but ArrayBufferView not Uint32Array");
- return false;
- }
- break;
- case GraphicsContext3D::HALF_FLOAT:
- case GraphicsContext3D::FLOAT:
- if (pixels->getType() != JSC::TypeFloat32) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
- return false;
- }
- break;
- case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float
- // As per the specification, ArrayBufferView should be null when
- // OES_texture_half_float is enabled.
- if (pixels) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL");
- return false;
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- unsigned totalBytesRequired;
- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
- if (error != GraphicsContext3D::NO_ERROR) {
- synthesizeGLError(error, functionName, "invalid texture dimensions");
- return false;
- }
- if (pixels->byteLength() < totalBytesRequired) {
- if (m_unpackAlignment != 1) {
- m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
- if (pixels->byteLength() == totalBytesRequired) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
- return false;
- }
- }
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
- return false;
- }
- return true;
-}
-
-GC3Denum WebGL2RenderingContext::baseInternalFormatFromInternalFormat(GC3Denum internalformat)
-{
- // Handles sized, unsized, and compressed internal formats.
- switch (internalformat) {
- case GraphicsContext3D::R8:
- case GraphicsContext3D::R8_SNORM:
- case GraphicsContext3D::R16F:
- case GraphicsContext3D::R32F:
- case GraphicsContext3D::R8I:
- case GraphicsContext3D::R8UI:
- case GraphicsContext3D::R16I:
- case GraphicsContext3D::R16UI:
- case GraphicsContext3D::R32I:
- case GraphicsContext3D::R32UI:
- case GraphicsContext3D::COMPRESSED_R11_EAC:
- case GraphicsContext3D::COMPRESSED_SIGNED_R11_EAC:
- return GraphicsContext3D::RED;
- case GraphicsContext3D::RG8:
- case GraphicsContext3D::RG8_SNORM:
- case GraphicsContext3D::RG16F:
- case GraphicsContext3D::RG32F:
- case GraphicsContext3D::RG8I:
- case GraphicsContext3D::RG8UI:
- case GraphicsContext3D::RG16I:
- case GraphicsContext3D::RG16UI:
- case GraphicsContext3D::RG32I:
- case GraphicsContext3D::RG32UI:
- case GraphicsContext3D::COMPRESSED_RG11_EAC:
- case GraphicsContext3D::COMPRESSED_SIGNED_RG11_EAC:
- return GraphicsContext3D::RG;
- case GraphicsContext3D::RGB8:
- case GraphicsContext3D::RGB8_SNORM:
- case GraphicsContext3D::RGB565:
- case GraphicsContext3D::SRGB8:
- case GraphicsContext3D::RGB16F:
- case GraphicsContext3D::RGB32F:
- case GraphicsContext3D::RGB8I:
- case GraphicsContext3D::RGB8UI:
- case GraphicsContext3D::RGB16I:
- case GraphicsContext3D::RGB16UI:
- case GraphicsContext3D::RGB32I:
- case GraphicsContext3D::RGB32UI:
- case GraphicsContext3D::RGB:
- case GraphicsContext3D::COMPRESSED_RGB8_ETC2:
- case GraphicsContext3D::COMPRESSED_SRGB8_ETC2:
- return GraphicsContext3D::RGB;
- case GraphicsContext3D::RGBA4:
- case GraphicsContext3D::RGB5_A1:
- case GraphicsContext3D::RGBA8:
- case GraphicsContext3D::RGBA8_SNORM:
- case GraphicsContext3D::RGB10_A2:
- case GraphicsContext3D::RGB10_A2UI:
- case GraphicsContext3D::SRGB8_ALPHA8:
- case GraphicsContext3D::RGBA16F:
- case GraphicsContext3D::RGBA32F:
- case GraphicsContext3D::RGBA8I:
- case GraphicsContext3D::RGBA8UI:
- case GraphicsContext3D::RGBA16I:
- case GraphicsContext3D::RGBA16UI:
- case GraphicsContext3D::RGBA32I:
- case GraphicsContext3D::RGBA32UI:
- case GraphicsContext3D::RGBA:
- case GraphicsContext3D::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
- case GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
- case GraphicsContext3D::COMPRESSED_RGBA8_ETC2_EAC:
- case GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
- return GraphicsContext3D::RGBA;
- case GraphicsContext3D::DEPTH_COMPONENT16:
- case GraphicsContext3D::DEPTH_COMPONENT24:
- case GraphicsContext3D::DEPTH_COMPONENT32F:
- return GraphicsContext3D::DEPTH_COMPONENT;
- case GraphicsContext3D::DEPTH24_STENCIL8:
- case GraphicsContext3D::DEPTH32F_STENCIL8:
- return GraphicsContext3D::DEPTH_STENCIL;
- case GraphicsContext3D::LUMINANCE:
- case GraphicsContext3D::LUMINANCE_ALPHA:
- case GraphicsContext3D::ALPHA:
- return internalformat;
- default:
- ASSERT_NOT_REACHED();
- return GraphicsContext3D::NONE;
- }
-}
-
-bool WebGL2RenderingContext::isIntegerFormat(GC3Denum internalformat)
-{
- switch (baseInternalFormatFromInternalFormat(internalformat)) {
- case GraphicsContext3D::RED_INTEGER:
- case GraphicsContext3D::RG_INTEGER:
- case GraphicsContext3D::RGB_INTEGER:
- case GraphicsContext3D::RGBA_INTEGER:
- return true;
- }
- return false;
-}
-
-WebGLGetInfo WebGL2RenderingContext::getParameter(GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return WebGLGetInfo();
- const int intZero = 0;
- switch (pname) {
- case GraphicsContext3D::ACTIVE_TEXTURE:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
- return getWebGLFloatArrayParameter(pname);
- case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
- return getWebGLFloatArrayParameter(pname);
- case GraphicsContext3D::ALPHA_BITS:
- return getIntParameter(pname);
- case GraphicsContext3D::ARRAY_BUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
- case GraphicsContext3D::BLEND:
- return getBooleanParameter(pname);
- case GraphicsContext3D::BLEND_COLOR:
- return getWebGLFloatArrayParameter(pname);
- case GraphicsContext3D::BLEND_DST_ALPHA:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::BLEND_DST_RGB:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::BLEND_EQUATION_ALPHA:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::BLEND_EQUATION_RGB:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::BLEND_SRC_ALPHA:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::BLEND_SRC_RGB:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::BLUE_BITS:
- return getIntParameter(pname);
- case GraphicsContext3D::COLOR_CLEAR_VALUE:
- return getWebGLFloatArrayParameter(pname);
- case GraphicsContext3D::COLOR_WRITEMASK:
- return getBooleanArrayParameter(pname);
- case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS:
- return WebGLGetInfo(Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size()).release());
- case GraphicsContext3D::CULL_FACE:
- return getBooleanParameter(pname);
- case GraphicsContext3D::CULL_FACE_MODE:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::CURRENT_PROGRAM:
- return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
- case GraphicsContext3D::DEPTH_BITS:
- if (!m_framebufferBinding && !m_attributes.depth)
- return WebGLGetInfo(intZero);
- return getIntParameter(pname);
- case GraphicsContext3D::DEPTH_CLEAR_VALUE:
- return getFloatParameter(pname);
- case GraphicsContext3D::DEPTH_FUNC:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::DEPTH_RANGE:
- return getWebGLFloatArrayParameter(pname);
- case GraphicsContext3D::DEPTH_TEST:
- return getBooleanParameter(pname);
- case GraphicsContext3D::DEPTH_WRITEMASK:
- return getBooleanParameter(pname);
- case GraphicsContext3D::DITHER:
- return getBooleanParameter(pname);
- case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundVertexArrayObject->getElementArrayBuffer()));
- case GraphicsContext3D::FRAMEBUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
- case GraphicsContext3D::FRONT_FACE:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::GENERATE_MIPMAP_HINT:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::GREEN_BITS:
- return getIntParameter(pname);
- case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT:
- return getIntParameter(pname);
- case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE:
- return getIntParameter(pname);
- case GraphicsContext3D::LINE_WIDTH:
- return getFloatParameter(pname);
- case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_RENDERBUFFER_SIZE:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_TEXTURE_SIZE:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VARYING_VECTORS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VERTEX_ATTRIBS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VIEWPORT_DIMS:
- return getWebGLIntArrayParameter(pname);
- case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
- return getIntParameter(pname);
- case GraphicsContext3D::PACK_ALIGNMENT:
- return getIntParameter(pname);
- case GraphicsContext3D::POLYGON_OFFSET_FACTOR:
- return getFloatParameter(pname);
- case GraphicsContext3D::POLYGON_OFFSET_FILL:
- return getBooleanParameter(pname);
- case GraphicsContext3D::POLYGON_OFFSET_UNITS:
- return getFloatParameter(pname);
- case GraphicsContext3D::RED_BITS:
- return getIntParameter(pname);
- case GraphicsContext3D::RENDERBUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
- case GraphicsContext3D::RENDERER:
- return WebGLGetInfo(String("WebKit WebGL"));
- case GraphicsContext3D::SAMPLE_BUFFERS:
- return getIntParameter(pname);
- case GraphicsContext3D::SAMPLE_COVERAGE_INVERT:
- return getBooleanParameter(pname);
- case GraphicsContext3D::SAMPLE_COVERAGE_VALUE:
- return getFloatParameter(pname);
- case GraphicsContext3D::SAMPLES:
- return getIntParameter(pname);
- case GraphicsContext3D::SCISSOR_BOX:
- return getWebGLIntArrayParameter(pname);
- case GraphicsContext3D::SCISSOR_TEST:
- return getBooleanParameter(pname);
- case GraphicsContext3D::SHADING_LANGUAGE_VERSION:
- return WebGLGetInfo("WebGL GLSL ES 1.0 (" + m_context->getString(GraphicsContext3D::SHADING_LANGUAGE_VERSION) + ")");
- case GraphicsContext3D::STENCIL_BACK_FAIL:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_BACK_FUNC:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_BACK_REF:
- return getIntParameter(pname);
- case GraphicsContext3D::STENCIL_BACK_VALUE_MASK:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_BACK_WRITEMASK:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_BITS:
- if (!m_framebufferBinding && !m_attributes.stencil)
- return WebGLGetInfo(intZero);
- return getIntParameter(pname);
- case GraphicsContext3D::STENCIL_CLEAR_VALUE:
- return getIntParameter(pname);
- case GraphicsContext3D::STENCIL_FAIL:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_FUNC:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_REF:
- return getIntParameter(pname);
- case GraphicsContext3D::STENCIL_TEST:
- return getBooleanParameter(pname);
- case GraphicsContext3D::STENCIL_VALUE_MASK:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_WRITEMASK:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::SUBPIXEL_BITS:
- return getIntParameter(pname);
- case GraphicsContext3D::TEXTURE_BINDING_2D:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].texture2DBinding));
- case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].textureCubeMapBinding));
- case GraphicsContext3D::UNPACK_ALIGNMENT:
- return getIntParameter(pname);
- case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
- return WebGLGetInfo(m_unpackFlipY);
- case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
- return WebGLGetInfo(m_unpackPremultiplyAlpha);
- case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL:
- return WebGLGetInfo(m_unpackColorspaceConversion);
- case GraphicsContext3D::VENDOR:
- return WebGLGetInfo(String("WebKit"));
- case GraphicsContext3D::VERSION:
- return WebGLGetInfo("WebGL 2.0 (" + m_context->getString(GraphicsContext3D::VERSION) + ")");
- case GraphicsContext3D::VIEWPORT:
- return getWebGLIntArrayParameter(pname);
- case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
- if (m_webglDebugRendererInfo)
- return WebGLGetInfo(m_context->getString(GraphicsContext3D::RENDERER));
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
- return WebGLGetInfo();
- case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
- if (m_webglDebugRendererInfo)
- return WebGLGetInfo(m_context->getString(GraphicsContext3D::VENDOR));
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
- return WebGLGetInfo();
- case Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
- if (m_extTextureFilterAnisotropic)
- return getUnsignedIntParameter(Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT);
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
- return WebGLGetInfo();
- case GraphicsContext3D::FRAGMENT_SHADER_DERIVATIVE_HINT:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_3D_TEXTURE_SIZE:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_ARRAY_TEXTURE_LAYERS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_COLOR_ATTACHMENTS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
- return getInt64Parameter(pname);
- case GraphicsContext3D::MAX_COMBINED_UNIFORM_BLOCKS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
- return getInt64Parameter(pname);
- case GraphicsContext3D::MAX_DRAW_BUFFERS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_ELEMENT_INDEX:
- return getInt64Parameter(pname);
- case GraphicsContext3D::MAX_ELEMENTS_INDICES:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_ELEMENTS_VERTICES:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_COMPONENTS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_BLOCKS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_PROGRAM_TEXEL_OFFSET:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_SAMPLES:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_SERVER_WAIT_TIMEOUT:
- return getInt64Parameter(pname);
- case GraphicsContext3D::MAX_TEXTURE_LOD_BIAS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_UNIFORM_BLOCK_SIZE:
- return getInt64Parameter(pname);
- case GraphicsContext3D::MAX_UNIFORM_BUFFER_BINDINGS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VARYING_COMPONENTS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VERTEX_OUTPUT_COMPONENTS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VERTEX_UNIFORM_BLOCKS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VERTEX_UNIFORM_COMPONENTS:
- return getIntParameter(pname);
- case GraphicsContext3D::MIN_PROGRAM_TEXEL_OFFSET:
- return getIntParameter(pname);
- case GraphicsContext3D::PACK_ROW_LENGTH:
- return getIntParameter(pname);
- case GraphicsContext3D::PACK_SKIP_PIXELS:
- return getIntParameter(pname);
- case GraphicsContext3D::PACK_SKIP_ROWS:
- return getIntParameter(pname);
- case GraphicsContext3D::UNPACK_IMAGE_HEIGHT:
- return getIntParameter(pname);
- case GraphicsContext3D::UNPACK_ROW_LENGTH:
- return getIntParameter(pname);
- case GraphicsContext3D::UNPACK_SKIP_IMAGES:
- return getIntParameter(pname);
- case GraphicsContext3D::UNPACK_SKIP_PIXELS:
- return getIntParameter(pname);
- case GraphicsContext3D::UNPACK_SKIP_ROWS:
- return getIntParameter(pname);
- case GraphicsContext3D::RASTERIZER_DISCARD:
- return getBooleanParameter(pname);
- case GraphicsContext3D::SAMPLE_ALPHA_TO_COVERAGE:
- return getBooleanParameter(pname);
- case GraphicsContext3D::SAMPLE_COVERAGE:
- return getBooleanParameter(pname);
- case GraphicsContext3D::TRANSFORM_FEEDBACK_ACTIVE:
- return getBooleanParameter(pname);
- case GraphicsContext3D::TRANSFORM_FEEDBACK_PAUSED:
- return getBooleanParameter(pname);
- case GraphicsContext3D::UNIFORM_BUFFER_OFFSET_ALIGNMENT:
- return getIntParameter(pname);
- case GraphicsContext3D::VERTEX_ARRAY_BINDING: {
- if (!m_boundVertexArrayObject->isDefaultObject())
- return WebGLGetInfo(PassRefPtr<WebGLVertexArrayObject>(static_cast<WebGLVertexArrayObject*>(m_boundVertexArrayObject.get())));
- return WebGLGetInfo();
- }
- break;
- case GraphicsContext3D::DRAW_BUFFER0:
- case GraphicsContext3D::DRAW_BUFFER1:
- case GraphicsContext3D::DRAW_BUFFER2:
- case GraphicsContext3D::DRAW_BUFFER3:
- case GraphicsContext3D::DRAW_BUFFER4:
- case GraphicsContext3D::DRAW_BUFFER5:
- case GraphicsContext3D::DRAW_BUFFER6:
- case GraphicsContext3D::DRAW_BUFFER7:
- case GraphicsContext3D::DRAW_BUFFER8:
- case GraphicsContext3D::DRAW_BUFFER9:
- case GraphicsContext3D::DRAW_BUFFER10:
- case GraphicsContext3D::DRAW_BUFFER11:
- case GraphicsContext3D::DRAW_BUFFER12:
- case GraphicsContext3D::DRAW_BUFFER13:
- case GraphicsContext3D::DRAW_BUFFER14:
- case GraphicsContext3D::DRAW_BUFFER15: {
- GC3Dint value = GraphicsContext3D::NONE;
- if (m_framebufferBinding)
- value = m_framebufferBinding->getDrawBuffer(pname);
- else // emulated backbuffer
- value = m_backDrawBuffer;
- return WebGLGetInfo(value);
- }
- case GraphicsContext3D::COPY_READ_BUFFER:
- case GraphicsContext3D::COPY_WRITE_BUFFER:
- case GraphicsContext3D::PIXEL_PACK_BUFFER_BINDING:
- case GraphicsContext3D::PIXEL_UNPACK_BUFFER_BINDING:
- case GraphicsContext3D::READ_BUFFER:
- case GraphicsContext3D::SAMPLER_BINDING:
- case GraphicsContext3D::TEXTURE_BINDING_2D_ARRAY:
- case GraphicsContext3D::TEXTURE_BINDING_3D:
- case GraphicsContext3D::READ_FRAMEBUFFER_BINDING:
- case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_BINDING:
- case GraphicsContext3D::UNIFORM_BUFFER_BINDING:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "parameter name not yet supported");
- return WebGLGetInfo();
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-bool WebGL2RenderingContext::validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired)
-{
- // Performs conservative validation by caching a maximum index of
- // the given type per element array buffer. If all of the bound
- // array buffers have enough elements to satisfy that maximum
- // index, skips the expensive per-draw-call iteration in
- // validateIndexArrayPrecise.
-
- RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
-
- if (!elementArrayBuffer)
- return false;
-
- GC3Dsizeiptr numElements = elementArrayBuffer->byteLength();
- // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
- if (!numElements)
- return false;
- const ArrayBuffer* buffer = elementArrayBuffer->elementArrayBuffer();
- ASSERT(buffer);
-
- int maxIndex = elementArrayBuffer->getCachedMaxIndex(type);
- if (maxIndex < 0) {
- // Compute the maximum index in the entire buffer for the given type of index.
- switch (type) {
- case GraphicsContext3D::UNSIGNED_BYTE: {
- const GC3Dubyte* p = static_cast<const GC3Dubyte*>(buffer->data());
- for (GC3Dsizeiptr i = 0; i < numElements; i++)
- maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
- break;
- }
- case GraphicsContext3D::UNSIGNED_SHORT: {
- numElements /= sizeof(GC3Dushort);
- const GC3Dushort* p = static_cast<const GC3Dushort*>(buffer->data());
- for (GC3Dsizeiptr i = 0; i < numElements; i++)
- maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
- break;
- }
- case GraphicsContext3D::UNSIGNED_INT: {
- numElements /= sizeof(GC3Duint);
- const GC3Duint* p = static_cast<const GC3Duint*>(buffer->data());
- for (GC3Dsizeiptr i = 0; i < numElements; i++)
- maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
- break;
- }
- default:
- return false;
- }
- elementArrayBuffer->setCachedMaxIndex(type, maxIndex);
- }
-
- if (maxIndex >= 0) {
- // The number of required elements is one more than the maximum
- // index that will be accessed.
- numElementsRequired = maxIndex + 1;
- return true;
- }
-
- return false;
-}
-
-bool WebGL2RenderingContext::validateBlendEquation(const char* functionName, GC3Denum mode)
-{
- switch (mode) {
- case GraphicsContext3D::FUNC_ADD:
- case GraphicsContext3D::FUNC_SUBTRACT:
- case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
- case GraphicsContext3D::MIN:
- case GraphicsContext3D::MAX:
- return true;
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid mode");
- return false;
- }
-}
-
-bool WebGL2RenderingContext::validateCapability(const char* functionName, GC3Denum cap)
-{
- switch (cap) {
- case GraphicsContext3D::BLEND:
- case GraphicsContext3D::CULL_FACE:
- case GraphicsContext3D::DEPTH_TEST:
- case GraphicsContext3D::DITHER:
- case GraphicsContext3D::POLYGON_OFFSET_FILL:
- case GraphicsContext3D::SAMPLE_ALPHA_TO_COVERAGE:
- case GraphicsContext3D::SAMPLE_COVERAGE:
- case GraphicsContext3D::SCISSOR_TEST:
- case GraphicsContext3D::STENCIL_TEST:
- case GraphicsContext3D::RASTERIZER_DISCARD:
- return true;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid capability");
- return false;
- }
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGL2RenderingContext.h b/Source/WebCore/html/canvas/WebGL2RenderingContext.h
deleted file mode 100644
index 9d90e95ee..000000000
--- a/Source/WebCore/html/canvas/WebGL2RenderingContext.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebGL2RenderingContext_h
-#define WebGL2RenderingContext_h
-
-#if ENABLE(WEBGL2)
-
-#include "WebGLRenderingContextBase.h"
-
-namespace WebCore {
-
-class WebGLQuery;
-class WebGLSampler;
-class WebGLSync;
-class WebGLTransformFeedback;
-class WebGLVertexArrayObject;
-
-class WebGL2RenderingContext final : public WebGLRenderingContextBase {
-public:
- WebGL2RenderingContext(HTMLCanvasElement*, GraphicsContext3D::Attributes);
- WebGL2RenderingContext(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>, GraphicsContext3D::Attributes);
- virtual bool isWebGL2() const override { return true; }
-
- /* Buffer objects */
- void copyBufferSubData(GC3Denum readTarget, GC3Denum writeTarget, GC3Dint64 readOffset, GC3Dint64 writeOffset, GC3Dint64 size);
- void getBufferSubData(GC3Denum target, GC3Dint64 offset, ArrayBufferView* returnedData);
- void getBufferSubData(GC3Denum target, GC3Dint64 offset, ArrayBuffer* returnedData);
-
- /* Framebuffer objects */
- virtual WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&) override;
- void blitFramebuffer(GC3Dint srcX0, GC3Dint srcY0, GC3Dint srcX1, GC3Dint srcY1, GC3Dint dstX0, GC3Dint dstY0, GC3Dint dstX1, GC3Dint dstY1, GC3Dbitfield mask, GC3Denum filter);
- void framebufferTextureLayer(GC3Denum target, GC3Denum attachment, GC3Duint texture, GC3Dint level, GC3Dint layer);
- WebGLGetInfo getInternalformatParameter(GC3Denum target, GC3Denum internalformat, GC3Denum pname);
- void invalidateFramebuffer(GC3Denum target, Vector<GC3Denum> attachments);
- void invalidateSubFramebuffer(GC3Denum target, Vector<GC3Denum> attachments, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
- void readBuffer(GC3Denum src);
-
- /* Renderbuffer objects */
- void renderbufferStorageMultisample(GC3Denum target, GC3Dsizei samples, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
-
- /* Texture objects */
- void texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
- void texStorage3D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth);
- void texImage3D(GC3Denum target, GC3Dint level, GC3Dint internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Dint border, GC3Denum format, GC3Denum type, ArrayBufferView* pixels);
- void texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Denum format, GC3Denum type, ArrayBufferView* pixels);
- void texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Denum format, GC3Denum type, ImageData* source);
- void texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Denum format, GC3Denum type, HTMLImageElement* source);
- void texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Denum format, GC3Denum type, HTMLCanvasElement* source);
- void texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Denum format, GC3Denum type, HTMLVideoElement* source);
- void copyTexSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
- void compressedTexImage3D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Dint border, GC3Dsizei imageSize, ArrayBufferView* data);
- void compressedTexSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Denum format, GC3Dsizei imageSize, ArrayBufferView* data);
-
- /* Programs and shaders */
- GC3Dint getFragDataLocation(WebGLProgram* program, String name);
-
- /* Uniforms and attributes */
- void uniform1ui(WebGLUniformLocation* location, GC3Duint v0);
- void uniform2ui(WebGLUniformLocation* location, GC3Duint v0, GC3Duint v1);
- void uniform3ui(WebGLUniformLocation* location, GC3Duint v0, GC3Duint v1, GC3Duint v2);
- void uniform4ui(WebGLUniformLocation* location, GC3Duint v0, GC3Duint v1, GC3Duint v2, GC3Duint v3);
- void uniform1uiv(WebGLUniformLocation* location, Uint32Array* value);
- void uniform2uiv(WebGLUniformLocation* location, Uint32Array* value);
- void uniform3uiv(WebGLUniformLocation* location, Uint32Array* value);
- void uniform4uiv(WebGLUniformLocation* location, Uint32Array* value);
- void uniformMatrix2x3fv(WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value);
- void uniformMatrix3x2fv(WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value);
- void uniformMatrix2x4fv(WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value);
- void uniformMatrix4x2fv(WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value);
- void uniformMatrix3x4fv(WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value);
- void uniformMatrix4x3fv(WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value);
- void vertexAttribI4i(GC3Duint index, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w);
- void vertexAttribI4iv(GC3Duint index, Int32Array* v);
- void vertexAttribI4ui(GC3Duint index, GC3Duint x, GC3Duint y, GC3Duint z, GC3Duint w);
- void vertexAttribI4uiv(GC3Duint index, Uint32Array* v);
- void vertexAttribIPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dsizei stride, GC3Dint64 offset);
-
- /* Writing to the drawing buffer */
- virtual void clear(GC3Dbitfield mask) override;
- void vertexAttribDivisor(GC3Duint index, GC3Duint divisor);
- void drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei instanceCount);
- void drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dint64 offset, GC3Dsizei instanceCount);
- void drawRangeElements(GC3Denum mode, GC3Duint start, GC3Duint end, GC3Dsizei count, GC3Denum type, GC3Dint64 offset);
-
- /* Multiple Render Targets */
- void drawBuffers(Vector<GC3Denum> buffers);
- void clearBufferiv(GC3Denum buffer, GC3Dint drawbuffer, Int32Array* value);
- void clearBufferuiv(GC3Denum buffer, GC3Dint drawbuffer, Uint32Array* value);
- void clearBufferfv(GC3Denum buffer, GC3Dint drawbuffer, Float32Array* value);
- void clearBufferfi(GC3Denum buffer, GC3Dint drawbuffer, GC3Dfloat depth, GC3Dint stencil);
-
- /* Query Objects */
- PassRefPtr<WebGLQuery> createQuery();
- void deleteQuery(WebGLQuery* query);
- GC3Dboolean isQuery(WebGLQuery* query);
- void beginQuery(GC3Denum target, WebGLQuery* query);
- void endQuery(GC3Denum target);
- PassRefPtr<WebGLQuery> getQuery(GC3Denum target, GC3Denum pname);
- WebGLGetInfo getQueryParameter(WebGLQuery* query, GC3Denum pname);
-
- /* Sampler Objects */
- PassRefPtr<WebGLSampler> createSampler();
- void deleteSampler(WebGLSampler* sampler);
- GC3Dboolean isSampler(WebGLSampler* sampler);
- void bindSampler(GC3Duint unit, WebGLSampler* sampler);
- void samplerParameteri(WebGLSampler* sampler, GC3Denum pname, GC3Dint param);
- void samplerParameterf(WebGLSampler* sampler, GC3Denum pname, GC3Dfloat param);
- WebGLGetInfo getSamplerParameter(WebGLSampler* sampler, GC3Denum pname);
-
- /* Sync objects */
- PassRefPtr<WebGLSync> fenceSync(GC3Denum condition, GC3Dbitfield flags);
- GC3Dboolean isSync(WebGLSync* sync);
- void deleteSync(WebGLSync* sync);
- GC3Denum clientWaitSync(WebGLSync* sync, GC3Dbitfield flags, GC3Duint64 timeout);
- void waitSync(WebGLSync* sync, GC3Dbitfield flags, GC3Duint64 timeout);
- WebGLGetInfo getSyncParameter(WebGLSync* sync, GC3Denum pname);
-
- /* Transform Feedback */
- PassRefPtr<WebGLTransformFeedback> createTransformFeedback();
- void deleteTransformFeedback(WebGLTransformFeedback* id);
- GC3Dboolean isTransformFeedback(WebGLTransformFeedback* id);
- void bindTransformFeedback(GC3Denum target, WebGLTransformFeedback* id);
- void beginTransformFeedback(GC3Denum primitiveMode);
- void endTransformFeedback();
- void transformFeedbackVaryings(WebGLProgram* program, Vector<String> varyings, GC3Denum bufferMode);
- PassRefPtr<WebGLActiveInfo> getTransformFeedbackVarying(WebGLProgram* program, GC3Duint index);
- void pauseTransformFeedback();
- void resumeTransformFeedback();
-
- /* Uniform Buffer Objects and Transform Feedback Buffers */
- void bindBufferBase(GC3Denum target, GC3Duint index, WebGLBuffer* buffer);
- void bindBufferRange(GC3Denum target, GC3Duint index, WebGLBuffer* buffer, GC3Dint64 offset, GC3Dint64 size);
- WebGLGetInfo getIndexedParameter(GC3Denum target, GC3Duint index);
- Uint32Array* getUniformIndices(WebGLProgram* program, Vector<String> uniformNames);
- Int32Array* getActiveUniforms(WebGLProgram* program, Uint32Array* uniformIndices, GC3Denum pname);
- GC3Duint getUniformBlockIndex(WebGLProgram* program, String uniformBlockName);
- WebGLGetInfo getActiveUniformBlockParameter(WebGLProgram* program, GC3Duint uniformBlockIndex, GC3Denum pname);
- WebGLGetInfo getActiveUniformBlockName(WebGLProgram* program, GC3Duint uniformBlockIndex);
- void uniformBlockBinding(WebGLProgram* program, GC3Duint uniformBlockIndex, GC3Duint uniformBlockBinding);
-
- /* Vertex Array Objects */
- PassRefPtr<WebGLVertexArrayObject> createVertexArray();
- void deleteVertexArray(WebGLVertexArrayObject* vertexArray);
- GC3Dboolean isVertexArray(WebGLVertexArrayObject* vertexArray);
- void bindVertexArray(WebGLVertexArrayObject* vertexArray);
-
- /* Extensions */
- virtual WebGLExtension* getExtension(const String&) override;
- virtual Vector<String> getSupportedExtensions() override;
- virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&) override;
-
- virtual void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) override;
- virtual void hint(GC3Denum target, GC3Denum mode) override;
- virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) override;
- virtual void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&) override;
- virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&) override;
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&) override;
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&) override;
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&) override;
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&) override;
-#if ENABLE(VIDEO)
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&) override;
-#endif
-
-protected:
- virtual void initializeVertexArrayObjects() override;
- virtual GC3Dint getMaxDrawBuffers() override;
- virtual GC3Dint getMaxColorAttachments() override;
- virtual bool validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired) override;
- virtual bool validateBlendEquation(const char* functionName, GC3Denum mode) override;
- virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) override;
- virtual bool validateTexFuncParameters(const char* functionName,
- TexFuncValidationFunctionType,
- GC3Denum target, GC3Dint level,
- GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type) override;
- virtual bool validateTexFuncData(const char* functionName, GC3Dint level,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum internalformat, GC3Denum format, GC3Denum type,
- ArrayBufferView* pixels,
- NullDisposition) override;
- virtual bool validateCapability(const char* functionName, GC3Denum cap) override;
- virtual bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment) override;
-
-private:
- GC3Denum baseInternalFormatFromInternalFormat(GC3Denum internalformat);
- bool isIntegerFormat(GC3Denum internalformat);
- void initializeShaderExtensions();
-};
-
-} // namespace WebCore
-
-#endif // WEBGL2
-
-#endif
diff --git a/Source/WebCore/html/canvas/WebGL2RenderingContext.idl b/Source/WebCore/html/canvas/WebGL2RenderingContext.idl
deleted file mode 100644
index 927a42147..000000000
--- a/Source/WebCore/html/canvas/WebGL2RenderingContext.idl
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-typedef unsigned long GLenum;
-typedef boolean GLboolean;
-typedef unsigned long GLbitfield;
-typedef byte GLbyte;
-typedef short GLshort;
-typedef long GLint;
-typedef long GLsizei;
-typedef long long GLintptr;
-typedef long long GLsizeiptr;
-typedef long long GLint64;
-typedef octet GLubyte;
-typedef unsigned short GLushort;
-typedef unsigned long GLuint;
-typedef unsigned long long GLuint64;
-typedef unrestricted float GLfloat;
-typedef unrestricted float GLclampf;
-
-[
- Conditional=WEBGL2,
- JSCustomMarkFunction,
- DoNotCheckConstants,
-] interface WebGL2RenderingContext : WebGLRenderingContextBase {
- const GLenum READ_BUFFER = 0x0C02;
- const GLenum UNPACK_ROW_LENGTH = 0x0CF2;
- const GLenum UNPACK_SKIP_ROWS = 0x0CF3;
- const GLenum UNPACK_SKIP_PIXELS = 0x0CF4;
- const GLenum PACK_ROW_LENGTH = 0x0D02;
- const GLenum PACK_SKIP_ROWS = 0x0D03;
- const GLenum PACK_SKIP_PIXELS = 0x0D04;
- const GLenum COLOR = 0x1800;
- const GLenum DEPTH = 0x1801;
- const GLenum STENCIL = 0x1802;
- const GLenum RED = 0x1903;
- const GLenum RGB8 = 0x8051;
- const GLenum RGBA8 = 0x8058;
- const GLenum RGB10_A2 = 0x8059;
- const GLenum TEXTURE_BINDING_3D = 0x806A;
- const GLenum UNPACK_SKIP_IMAGES = 0x806D;
- const GLenum UNPACK_IMAGE_HEIGHT = 0x806E;
- const GLenum TEXTURE_3D = 0x806F;
- const GLenum TEXTURE_WRAP_R = 0x8072;
- const GLenum MAX_3D_TEXTURE_SIZE = 0x8073;
- const GLenum UNSIGNED_INT_2_10_10_10_REV = 0x8368;
- const GLenum MAX_ELEMENTS_VERTICES = 0x80E8;
- const GLenum MAX_ELEMENTS_INDICES = 0x80E9;
- const GLenum TEXTURE_MIN_LOD = 0x813A;
- const GLenum TEXTURE_MAX_LOD = 0x813B;
- const GLenum TEXTURE_BASE_LEVEL = 0x813C;
- const GLenum TEXTURE_MAX_LEVEL = 0x813D;
- const GLenum MIN = 0x8007;
- const GLenum MAX = 0x8008;
- const GLenum DEPTH_COMPONENT24 = 0x81A6;
- const GLenum MAX_TEXTURE_LOD_BIAS = 0x84FD;
- const GLenum TEXTURE_COMPARE_MODE = 0x884C;
- const GLenum TEXTURE_COMPARE_FUNC = 0x884D;
- const GLenum CURRENT_QUERY = 0x8865;
- const GLenum QUERY_RESULT = 0x8866;
- const GLenum QUERY_RESULT_AVAILABLE = 0x8867;
- const GLenum STREAM_READ = 0x88E1;
- const GLenum STREAM_COPY = 0x88E2;
- const GLenum STATIC_READ = 0x88E5;
- const GLenum STATIC_COPY = 0x88E6;
- const GLenum DYNAMIC_READ = 0x88E9;
- const GLenum DYNAMIC_COPY = 0x88EA;
- const GLenum MAX_DRAW_BUFFERS = 0x8824;
- const GLenum DRAW_BUFFER0 = 0x8825;
- const GLenum DRAW_BUFFER1 = 0x8826;
- const GLenum DRAW_BUFFER2 = 0x8827;
- const GLenum DRAW_BUFFER3 = 0x8828;
- const GLenum DRAW_BUFFER4 = 0x8829;
- const GLenum DRAW_BUFFER5 = 0x882A;
- const GLenum DRAW_BUFFER6 = 0x882B;
- const GLenum DRAW_BUFFER7 = 0x882C;
- const GLenum DRAW_BUFFER8 = 0x882D;
- const GLenum DRAW_BUFFER9 = 0x882E;
- const GLenum DRAW_BUFFER10 = 0x882F;
- const GLenum DRAW_BUFFER11 = 0x8830;
- const GLenum DRAW_BUFFER12 = 0x8831;
- const GLenum DRAW_BUFFER13 = 0x8832;
- const GLenum DRAW_BUFFER14 = 0x8833;
- const GLenum DRAW_BUFFER15 = 0x8834;
- const GLenum MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49;
- const GLenum MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A;
- const GLenum SAMPLER_3D = 0x8B5F;
- const GLenum SAMPLER_2D_SHADOW = 0x8B62;
- const GLenum FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8B8B;
- const GLenum PIXEL_PACK_BUFFER = 0x88EB;
- const GLenum PIXEL_UNPACK_BUFFER = 0x88EC;
- const GLenum PIXEL_PACK_BUFFER_BINDING = 0x88ED;
- const GLenum PIXEL_UNPACK_BUFFER_BINDING = 0x88EF;
- const GLenum FLOAT_MAT2x3 = 0x8B65;
- const GLenum FLOAT_MAT2x4 = 0x8B66;
- const GLenum FLOAT_MAT3x2 = 0x8B67;
- const GLenum FLOAT_MAT3x4 = 0x8B68;
- const GLenum FLOAT_MAT4x2 = 0x8B69;
- const GLenum FLOAT_MAT4x3 = 0x8B6A;
- const GLenum SRGB = 0x8C40;
- const GLenum SRGB8 = 0x8C41;
- const GLenum SRGB8_ALPHA8 = 0x8C43;
- const GLenum COMPARE_REF_TO_TEXTURE = 0x884E;
- const GLenum RGBA32F = 0x8814;
- const GLenum RGB32F = 0x8815;
- const GLenum RGBA16F = 0x881A;
- const GLenum RGB16F = 0x881B;
- const GLenum VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD;
- const GLenum MAX_ARRAY_TEXTURE_LAYERS = 0x88FF;
- const GLenum MIN_PROGRAM_TEXEL_OFFSET = 0x8904;
- const GLenum MAX_PROGRAM_TEXEL_OFFSET = 0x8905;
- const GLenum MAX_VARYING_COMPONENTS = 0x8B4B;
- const GLenum TEXTURE_2D_ARRAY = 0x8C1A;
- const GLenum TEXTURE_BINDING_2D_ARRAY = 0x8C1D;
- const GLenum R11F_G11F_B10F = 0x8C3A;
- const GLenum UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B;
- const GLenum RGB9_E5 = 0x8C3D;
- const GLenum UNSIGNED_INT_5_9_9_9_REV = 0x8C3E;
- const GLenum TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8C7F;
- const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8C80;
- const GLenum TRANSFORM_FEEDBACK_VARYINGS = 0x8C83;
- const GLenum TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84;
- const GLenum TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85;
- const GLenum TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88;
- const GLenum RASTERIZER_DISCARD = 0x8C89;
- const GLenum MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A;
- const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B;
- const GLenum INTERLEAVED_ATTRIBS = 0x8C8C;
- const GLenum SEPARATE_ATTRIBS = 0x8C8D;
- const GLenum TRANSFORM_FEEDBACK_BUFFER = 0x8C8E;
- const GLenum TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F;
- const GLenum RGBA32UI = 0x8D70;
- const GLenum RGB32UI = 0x8D71;
- const GLenum RGBA16UI = 0x8D76;
- const GLenum RGB16UI = 0x8D77;
- const GLenum RGBA8UI = 0x8D7C;
- const GLenum RGB8UI = 0x8D7D;
- const GLenum RGBA32I = 0x8D82;
- const GLenum RGB32I = 0x8D83;
- const GLenum RGBA16I = 0x8D88;
- const GLenum RGB16I = 0x8D89;
- const GLenum RGBA8I = 0x8D8E;
- const GLenum RGB8I = 0x8D8F;
- const GLenum RED_INTEGER = 0x8D94;
- const GLenum RGB_INTEGER = 0x8D98;
- const GLenum RGBA_INTEGER = 0x8D99;
- const GLenum SAMPLER_2D_ARRAY = 0x8DC1;
- const GLenum SAMPLER_2D_ARRAY_SHADOW = 0x8DC4;
- const GLenum SAMPLER_CUBE_SHADOW = 0x8DC5;
- const GLenum UNSIGNED_INT_VEC2 = 0x8DC6;
- const GLenum UNSIGNED_INT_VEC3 = 0x8DC7;
- const GLenum UNSIGNED_INT_VEC4 = 0x8DC8;
- const GLenum INT_SAMPLER_2D = 0x8DCA;
- const GLenum INT_SAMPLER_3D = 0x8DCB;
- const GLenum INT_SAMPLER_CUBE = 0x8DCC;
- const GLenum INT_SAMPLER_2D_ARRAY = 0x8DCF;
- const GLenum UNSIGNED_INT_SAMPLER_2D = 0x8DD2;
- const GLenum UNSIGNED_INT_SAMPLER_3D = 0x8DD3;
- const GLenum UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4;
- const GLenum UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7;
- const GLenum DEPTH_COMPONENT32F = 0x8CAC;
- const GLenum DEPTH32F_STENCIL8 = 0x8CAD;
- const GLenum FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD;
- const GLenum FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210;
- const GLenum FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = 0x8211;
- const GLenum FRAMEBUFFER_ATTACHMENT_RED_SIZE = 0x8212;
- const GLenum FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = 0x8213;
- const GLenum FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = 0x8214;
- const GLenum FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = 0x8215;
- const GLenum FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = 0x8216;
- const GLenum FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = 0x8217;
- const GLenum FRAMEBUFFER_DEFAULT = 0x8218;
- const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A;
- const GLenum DEPTH_STENCIL = 0x84F9;
- const GLenum UNSIGNED_INT_24_8 = 0x84FA;
- const GLenum DEPTH24_STENCIL8 = 0x88F0;
- const GLenum UNSIGNED_NORMALIZED = 0x8C17;
- const GLenum DRAW_FRAMEBUFFER_BINDING = 0x8CA6; /* Same as FRAMEBUFFER_BINDING */
- const GLenum READ_FRAMEBUFFER = 0x8CA8;
- const GLenum DRAW_FRAMEBUFFER = 0x8CA9;
- const GLenum READ_FRAMEBUFFER_BINDING = 0x8CAA;
- const GLenum RENDERBUFFER_SAMPLES = 0x8CAB;
- const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = 0x8CD4;
- const GLenum MAX_COLOR_ATTACHMENTS = 0x8CDF;
- const GLenum COLOR_ATTACHMENT1 = 0x8CE1;
- const GLenum COLOR_ATTACHMENT2 = 0x8CE2;
- const GLenum COLOR_ATTACHMENT3 = 0x8CE3;
- const GLenum COLOR_ATTACHMENT4 = 0x8CE4;
- const GLenum COLOR_ATTACHMENT5 = 0x8CE5;
- const GLenum COLOR_ATTACHMENT6 = 0x8CE6;
- const GLenum COLOR_ATTACHMENT7 = 0x8CE7;
- const GLenum COLOR_ATTACHMENT8 = 0x8CE8;
- const GLenum COLOR_ATTACHMENT9 = 0x8CE9;
- const GLenum COLOR_ATTACHMENT10 = 0x8CEA;
- const GLenum COLOR_ATTACHMENT11 = 0x8CEB;
- const GLenum COLOR_ATTACHMENT12 = 0x8CEC;
- const GLenum COLOR_ATTACHMENT13 = 0x8CED;
- const GLenum COLOR_ATTACHMENT14 = 0x8CEE;
- const GLenum COLOR_ATTACHMENT15 = 0x8CEF;
- const GLenum FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56;
- const GLenum MAX_SAMPLES = 0x8D57;
- const GLenum HALF_FLOAT = 0x140B;
- const GLenum RG = 0x8227;
- const GLenum RG_INTEGER = 0x8228;
- const GLenum R8 = 0x8229;
- const GLenum RG8 = 0x822B;
- const GLenum R16F = 0x822D;
- const GLenum R32F = 0x822E;
- const GLenum RG16F = 0x822F;
- const GLenum RG32F = 0x8230;
- const GLenum R8I = 0x8231;
- const GLenum R8UI = 0x8232;
- const GLenum R16I = 0x8233;
- const GLenum R16UI = 0x8234;
- const GLenum R32I = 0x8235;
- const GLenum R32UI = 0x8236;
- const GLenum RG8I = 0x8237;
- const GLenum RG8UI = 0x8238;
- const GLenum RG16I = 0x8239;
- const GLenum RG16UI = 0x823A;
- const GLenum RG32I = 0x823B;
- const GLenum RG32UI = 0x823C;
- const GLenum VERTEX_ARRAY_BINDING = 0x85B5;
- const GLenum R8_SNORM = 0x8F94;
- const GLenum RG8_SNORM = 0x8F95;
- const GLenum RGB8_SNORM = 0x8F96;
- const GLenum RGBA8_SNORM = 0x8F97;
- const GLenum SIGNED_NORMALIZED = 0x8F9C;
- const GLenum PRIMITIVE_RESTART_FIXED_INDEX = 0x8D69;
- const GLenum COPY_READ_BUFFER = 0x8F36;
- const GLenum COPY_WRITE_BUFFER = 0x8F37;
- const GLenum COPY_READ_BUFFER_BINDING = 0x8F36; /* Same as COPY_READ_BUFFER */
- const GLenum COPY_WRITE_BUFFER_BINDING = 0x8F37; /* Same as COPY_WRITE_BUFFER */
- const GLenum UNIFORM_BUFFER = 0x8A11;
- const GLenum UNIFORM_BUFFER_BINDING = 0x8A28;
- const GLenum UNIFORM_BUFFER_START = 0x8A29;
- const GLenum UNIFORM_BUFFER_SIZE = 0x8A2A;
- const GLenum MAX_VERTEX_UNIFORM_BLOCKS = 0x8A2B;
- const GLenum MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8A2D;
- const GLenum MAX_COMBINED_UNIFORM_BLOCKS = 0x8A2E;
- const GLenum MAX_UNIFORM_BUFFER_BINDINGS = 0x8A2F;
- const GLenum MAX_UNIFORM_BLOCK_SIZE = 0x8A30;
- const GLenum MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8A31;
- const GLenum MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8A33;
- const GLenum UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8A34;
- const GLenum ACTIVE_UNIFORM_BLOCKS = 0x8A36;
- const GLenum UNIFORM_TYPE = 0x8A37;
- const GLenum UNIFORM_SIZE = 0x8A38;
- const GLenum UNIFORM_BLOCK_INDEX = 0x8A3A;
- const GLenum UNIFORM_OFFSET = 0x8A3B;
- const GLenum UNIFORM_ARRAY_STRIDE = 0x8A3C;
- const GLenum UNIFORM_MATRIX_STRIDE = 0x8A3D;
- const GLenum UNIFORM_IS_ROW_MAJOR = 0x8A3E;
- const GLenum UNIFORM_BLOCK_BINDING = 0x8A3F;
- const GLenum UNIFORM_BLOCK_DATA_SIZE = 0x8A40;
- const GLenum UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8A42;
- const GLenum UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8A43;
- const GLenum UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8A44;
- const GLenum UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46;
- const GLenum INVALID_INDEX = 0xFFFFFFFF;
- const GLenum MAX_VERTEX_OUTPUT_COMPONENTS = 0x9122;
- const GLenum MAX_FRAGMENT_INPUT_COMPONENTS = 0x9125;
- const GLenum MAX_SERVER_WAIT_TIMEOUT = 0x9111;
- const GLenum OBJECT_TYPE = 0x9112;
- const GLenum SYNC_CONDITION = 0x9113;
- const GLenum SYNC_STATUS = 0x9114;
- const GLenum SYNC_FLAGS = 0x9115;
- const GLenum SYNC_FENCE = 0x9116;
- const GLenum SYNC_GPU_COMMANDS_COMPLETE = 0x9117;
- const GLenum UNSIGNALED = 0x9118;
- const GLenum SIGNALED = 0x9119;
- const GLenum ALREADY_SIGNALED = 0x911A;
- const GLenum TIMEOUT_EXPIRED = 0x911B;
- const GLenum CONDITION_SATISFIED = 0x911C;
- const GLenum WAIT_FAILED = 0x911D;
- const GLenum SYNC_FLUSH_COMMANDS_BIT = 0x00000001;
- const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE;
- const GLenum ANY_SAMPLES_PASSED = 0x8C2F;
- const GLenum ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8D6A;
- const GLenum SAMPLER_BINDING = 0x8919;
- const GLenum RGB10_A2UI = 0x906F;
- const GLenum TEXTURE_SWIZZLE_R = 0x8E42;
- const GLenum TEXTURE_SWIZZLE_G = 0x8E43;
- const GLenum TEXTURE_SWIZZLE_B = 0x8E44;
- const GLenum TEXTURE_SWIZZLE_A = 0x8E45;
- const GLenum GREEN = 0x1904;
- const GLenum BLUE = 0x1905;
- const GLenum INT_2_10_10_10_REV = 0x8D9F;
- const GLenum TRANSFORM_FEEDBACK = 0x8E22;
- const GLenum TRANSFORM_FEEDBACK_PAUSED = 0x8E23;
- const GLenum TRANSFORM_FEEDBACK_ACTIVE = 0x8E24;
- const GLenum TRANSFORM_FEEDBACK_BINDING = 0x8E25;
- const GLenum COMPRESSED_R11_EAC = 0x9270;
- const GLenum COMPRESSED_SIGNED_R11_EAC = 0x9271;
- const GLenum COMPRESSED_RG11_EAC = 0x9272;
- const GLenum COMPRESSED_SIGNED_RG11_EAC = 0x9273;
- const GLenum COMPRESSED_RGB8_ETC2 = 0x9274;
- const GLenum COMPRESSED_SRGB8_ETC2 = 0x9275;
- const GLenum COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276;
- const GLenum COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277;
- const GLenum COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
- const GLenum COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279;
- const GLenum TEXTURE_IMMUTABLE_FORMAT = 0x912F;
- const GLenum MAX_ELEMENT_INDEX = 0x8D6B;
- const GLenum NUM_SAMPLE_COUNTS = 0x9380;
- const GLenum TEXTURE_IMMUTABLE_LEVELS = 0x82DF;
- const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88FE;
-
- const GLuint64 TIMEOUT_IGNORED = 0xFFFFFFFFFFFFFFFF;
-
- /* Buffer objects */
- [StrictTypeChecking] void copyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
- // MapBufferRange, in particular its read-only and write-only modes,
- // can not be exposed safely to JavaScript. GetBufferSubData
- // replaces it for the purpose of fetching data back from the GPU.
- [StrictTypeChecking] void getBufferSubData(GLenum target, GLintptr offset, ArrayBufferView returnedData);
- [StrictTypeChecking] void getBufferSubData(GLenum target, GLintptr offset, ArrayBuffer returnedData);
-
- /* Framebuffer objects */
- [StrictTypeChecking] void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
- [StrictTypeChecking] void framebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
- [StrictTypeChecking, Custom] any getInternalformatParameter(GLenum target, GLenum internalformat, GLenum pname);
- [StrictTypeChecking] void invalidateFramebuffer(GLenum target, sequence<GLenum> attachments);
- [StrictTypeChecking] void invalidateSubFramebuffer(GLenum target, sequence<GLenum> attachments, GLint x, GLint y, GLsizei width, GLsizei height);
- [StrictTypeChecking] void readBuffer(GLenum src);
-
- /* Renderbuffer objects */
- [StrictTypeChecking] void renderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
-
- /* Texture objects */
- [StrictTypeChecking] void texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
- [StrictTypeChecking] void texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
- [StrictTypeChecking] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
- [StrictTypeChecking] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, ArrayBufferView? pixels);
- [StrictTypeChecking] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, ImageData? source);
- [StrictTypeChecking] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLImageElement? source);
- [StrictTypeChecking] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLCanvasElement? source);
- [StrictTypeChecking] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLVideoElement? source);
- [StrictTypeChecking] void copyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
- [StrictTypeChecking] void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, ArrayBufferView data);
- [StrictTypeChecking] void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, ArrayBufferView data);
-
- /* Programs and shaders */
- [StrictTypeChecking] GLint getFragDataLocation(WebGLProgram? program, DOMString name);
-
- /* Uniforms and attributes */
- [StrictTypeChecking] void uniform1ui(WebGLUniformLocation? location, GLuint v0);
- [StrictTypeChecking] void uniform2ui(WebGLUniformLocation? location, GLuint v0, GLuint v1);
- [StrictTypeChecking] void uniform3ui(WebGLUniformLocation? location, GLuint v0, GLuint v1, GLuint v2);
- [StrictTypeChecking] void uniform4ui(WebGLUniformLocation? location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
- [StrictTypeChecking] void uniform1uiv(WebGLUniformLocation? location, Uint32Array value);
- [StrictTypeChecking] void uniform2uiv(WebGLUniformLocation? location, Uint32Array value);
- [StrictTypeChecking] void uniform3uiv(WebGLUniformLocation? location, Uint32Array value);
- [StrictTypeChecking] void uniform4uiv(WebGLUniformLocation? location, Uint32Array value);
- [StrictTypeChecking] void uniformMatrix2x3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value);
- [StrictTypeChecking] void uniformMatrix3x2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value);
- [StrictTypeChecking] void uniformMatrix2x4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value);
- [StrictTypeChecking] void uniformMatrix4x2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value);
- [StrictTypeChecking] void uniformMatrix3x4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value);
- [StrictTypeChecking] void uniformMatrix4x3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value);
- [StrictTypeChecking] void vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
- [StrictTypeChecking] void vertexAttribI4iv(GLuint index, Int32Array v);
- [StrictTypeChecking] void vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
- [StrictTypeChecking] void vertexAttribI4uiv(GLuint index, Uint32Array v);
- [StrictTypeChecking] void vertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
-
- /* Writing to the drawing buffer */
- [StrictTypeChecking] void vertexAttribDivisor(GLuint index, GLuint divisor);
- [StrictTypeChecking] void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
- [StrictTypeChecking] void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei instanceCount);
- [StrictTypeChecking] void drawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLintptr offset);
-
- /* Multiple Render Targets */
- [StrictTypeChecking] void drawBuffers(sequence<GLenum> buffers);
- [StrictTypeChecking] void clearBufferiv(GLenum buffer, GLint drawbuffer, Int32Array value);
- [StrictTypeChecking] void clearBufferuiv(GLenum buffer, GLint drawbuffer, Uint32Array value);
- [StrictTypeChecking] void clearBufferfv(GLenum buffer, GLint drawbuffer, Float32Array value);
- [StrictTypeChecking] void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
-
- /* Query Objects */
- [StrictTypeChecking] WebGLQuery createQuery();
- [StrictTypeChecking] void deleteQuery(WebGLQuery? query);
- [StrictTypeChecking] GLboolean isQuery(WebGLQuery? query);
- [StrictTypeChecking] void beginQuery(GLenum target, WebGLQuery? query);
- [StrictTypeChecking] void endQuery(GLenum target);
- [StrictTypeChecking] WebGLQuery getQuery(GLenum target, GLenum pname);
- [StrictTypeChecking, Custom] any getQueryParameter(WebGLQuery? query, GLenum pname);
-
- /* Sampler Objects */
- [StrictTypeChecking] WebGLSampler createSampler();
- [StrictTypeChecking] void deleteSampler(WebGLSampler? sampler);
- [StrictTypeChecking] GLboolean isSampler(WebGLSampler? sampler);
- [StrictTypeChecking] void bindSampler(GLuint unit, WebGLSampler? sampler);
- [StrictTypeChecking] void samplerParameteri(WebGLSampler? sampler, GLenum pname, GLint param);
- [StrictTypeChecking] void samplerParameterf(WebGLSampler? sampler, GLenum pname, GLfloat param);
- [StrictTypeChecking, Custom] any getSamplerParameter(WebGLSampler? sampler, GLenum pname);
-
- /* Sync objects */
- [StrictTypeChecking] WebGLSync fenceSync(GLenum condition, GLbitfield flags);
- [StrictTypeChecking] GLboolean isSync(WebGLSync? sync);
- [StrictTypeChecking] void deleteSync(WebGLSync? sync);
- [StrictTypeChecking] GLenum clientWaitSync(WebGLSync? sync, GLbitfield flags, GLuint64 timeout);
- [StrictTypeChecking] void waitSync(WebGLSync? sync, GLbitfield flags, GLuint64 timeout);
- [StrictTypeChecking, Custom] any getSyncParameter(WebGLSync? sync, GLenum pname);
-
- /* Transform Feedback */
- [StrictTypeChecking] WebGLTransformFeedback createTransformFeedback();
- [StrictTypeChecking] void deleteTransformFeedback(WebGLTransformFeedback? id);
- [StrictTypeChecking] GLboolean isTransformFeedback(WebGLTransformFeedback? id);
- [StrictTypeChecking] void bindTransformFeedback(GLenum target, WebGLTransformFeedback? id);
- [StrictTypeChecking] void beginTransformFeedback(GLenum primitiveMode);
- [StrictTypeChecking] void endTransformFeedback();
- [StrictTypeChecking] void transformFeedbackVaryings(WebGLProgram? program, sequence<DOMString> varyings, GLenum bufferMode);
- [StrictTypeChecking] WebGLActiveInfo getTransformFeedbackVarying(WebGLProgram? program, GLuint index);
- [StrictTypeChecking] void pauseTransformFeedback();
- [StrictTypeChecking] void resumeTransformFeedback();
-
- /* Uniform Buffer Objects and Transform Feedback Buffers */
- [StrictTypeChecking] void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer);
- [StrictTypeChecking] void bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer, GLintptr offset, GLsizeiptr size);
- [StrictTypeChecking, Custom] any getIndexedParameter(GLenum target, GLuint index);
- [StrictTypeChecking] Uint32Array getUniformIndices(WebGLProgram? program, sequence<DOMString> uniformNames);
- [StrictTypeChecking] Int32Array getActiveUniforms(WebGLProgram? program, Uint32Array uniformIndices, GLenum pname);
- [StrictTypeChecking] GLuint getUniformBlockIndex(WebGLProgram? program, DOMString uniformBlockName);
- [StrictTypeChecking, Custom] any getActiveUniformBlockParameter(WebGLProgram? program, GLuint uniformBlockIndex, GLenum pname);
- [StrictTypeChecking, Custom] any getActiveUniformBlockName(WebGLProgram? program, GLuint uniformBlockIndex);
- [StrictTypeChecking] void uniformBlockBinding(WebGLProgram? program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
-
- /* Vertex Array Objects */
- [StrictTypeChecking] WebGLVertexArrayObject createVertexArray();
- [StrictTypeChecking] void deleteVertexArray(WebGLVertexArrayObject? vertexArray);
- [StrictTypeChecking] GLboolean isVertexArray(WebGLVertexArrayObject? vertexArray);
- [StrictTypeChecking] void bindVertexArray(WebGLVertexArrayObject? vertexArray);
-};
diff --git a/Source/WebCore/html/canvas/WebGLActiveInfo.h b/Source/WebCore/html/canvas/WebGLActiveInfo.h
index 14758b9d4..0938a2366 100644
--- a/Source/WebCore/html/canvas/WebGLActiveInfo.h
+++ b/Source/WebCore/html/canvas/WebGLActiveInfo.h
@@ -35,9 +35,9 @@ namespace WebCore {
class WebGLActiveInfo : public RefCounted<WebGLActiveInfo> {
public:
- static Ref<WebGLActiveInfo> create(const String& name, GC3Denum type, GC3Dint size)
+ static PassRefPtr<WebGLActiveInfo> create(const String& name, GC3Denum type, GC3Dint size)
{
- return adoptRef(*new WebGLActiveInfo(name, type, size));
+ return adoptRef(new WebGLActiveInfo(name, type, size));
}
String name() const { return m_name; }
GC3Denum type() const { return m_type; }
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.cpp b/Source/WebCore/html/canvas/WebGLBuffer.cpp
index e327cf09b..3421e979c 100644
--- a/Source/WebCore/html/canvas/WebGLBuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLBuffer.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,16 +30,16 @@
#include "WebGLBuffer.h"
#include "WebGLContextGroup.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-Ref<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContextBase* ctx)
+PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContext* ctx)
{
- return adoptRef(*new WebGLBuffer(ctx));
+ return adoptRef(new WebGLBuffer(ctx));
}
-WebGLBuffer::WebGLBuffer(WebGLRenderingContextBase* ctx)
+WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx)
: WebGLSharedObject(ctx)
, m_target(0)
, m_byteLength(0)
@@ -81,7 +81,7 @@ bool WebGLBuffer::associateBufferDataImpl(const void* data, GC3Dsizeiptr byteLen
memcpy(m_elementArrayBuffer->data(), data, byteLength);
}
} else
- m_elementArrayBuffer = nullptr;
+ m_elementArrayBuffer = 0;
return true;
case GraphicsContext3D::ARRAY_BUFFER:
m_byteLength = byteLength;
@@ -153,12 +153,6 @@ bool WebGLBuffer::associateBufferSubData(GC3Dintptr offset, ArrayBufferView* arr
return associateBufferSubDataImpl(offset, array->baseAddress(), array->byteLength());
}
-void WebGLBuffer::disassociateBufferData()
-{
- m_byteLength = 0;
- clearCachedMaxIndices();
-}
-
GC3Dsizeiptr WebGLBuffer::byteLength() const
{
return m_byteLength;
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.h b/Source/WebCore/html/canvas/WebGLBuffer.h
index 8075b4a16..3451bb68c 100644
--- a/Source/WebCore/html/canvas/WebGLBuffer.h
+++ b/Source/WebCore/html/canvas/WebGLBuffer.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -37,11 +37,11 @@ class ArrayBufferView;
namespace WebCore {
-class WebGLBuffer final : public WebGLSharedObject {
+class WebGLBuffer : public WebGLSharedObject {
public:
virtual ~WebGLBuffer();
- static Ref<WebGLBuffer> create(WebGLRenderingContextBase*);
+ static PassRefPtr<WebGLBuffer> create(WebGLRenderingContext*);
bool associateBufferData(GC3Dsizeiptr size);
bool associateBufferData(JSC::ArrayBuffer*);
@@ -49,8 +49,6 @@ public:
bool associateBufferSubData(GC3Dintptr offset, JSC::ArrayBuffer*);
bool associateBufferSubData(GC3Dintptr offset, JSC::ArrayBufferView*);
- void disassociateBufferData();
-
GC3Dsizeiptr byteLength() const;
const JSC::ArrayBuffer* elementArrayBuffer() const { return m_elementArrayBuffer.get(); }
@@ -66,7 +64,7 @@ public:
bool hasEverBeenBound() const { return object() && m_target; }
protected:
- WebGLBuffer(WebGLRenderingContextBase*);
+ WebGLBuffer(WebGLRenderingContext*);
virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.idl b/Source/WebCore/html/canvas/WebGLBuffer.idl
index 6e2ab9c57..f43cd6353 100644
--- a/Source/WebCore/html/canvas/WebGLBuffer.idl
+++ b/Source/WebCore/html/canvas/WebGLBuffer.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureATC.cpp b/Source/WebCore/html/canvas/WebGLCompressedTextureATC.cpp
index 50ad655aa..71881ba09 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTextureATC.cpp
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureATC.cpp
@@ -33,7 +33,7 @@
namespace WebCore {
-WebGLCompressedTextureATC::WebGLCompressedTextureATC(WebGLRenderingContextBase* context)
+WebGLCompressedTextureATC::WebGLCompressedTextureATC(WebGLRenderingContext* context)
: WebGLExtension(context)
{
context->addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGB_AMD);
@@ -50,7 +50,12 @@ WebGLExtension::ExtensionName WebGLCompressedTextureATC::getName() const
return WebGLCompressedTextureATCName;
}
-bool WebGLCompressedTextureATC::supported(WebGLRenderingContextBase* context)
+OwnPtr<WebGLCompressedTextureATC> WebGLCompressedTextureATC::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new WebGLCompressedTextureATC(context));
+}
+
+bool WebGLCompressedTextureATC::supported(WebGLRenderingContext* context)
{
Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
return extensions->supports("GL_AMD_compressed_ATC_texture");
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureATC.h b/Source/WebCore/html/canvas/WebGLCompressedTextureATC.h
index 0d9818c3c..6a8d89d5d 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTextureATC.h
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureATC.h
@@ -27,19 +27,23 @@
#define WebGLCompressedTextureATC_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
class WebGLTexture;
-class WebGLCompressedTextureATC final : public WebGLExtension {
+class WebGLCompressedTextureATC : public WebGLExtension {
public:
- explicit WebGLCompressedTextureATC(WebGLRenderingContextBase*);
- virtual ~WebGLCompressedTextureATC();
+ static OwnPtr<WebGLCompressedTextureATC> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContext*);
+ virtual ~WebGLCompressedTextureATC();
virtual ExtensionName getName() const override;
+
+private:
+ WebGLCompressedTextureATC(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.cpp b/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.cpp
index 8caa4c689..d05d4178b 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.cpp
+++ b/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.cpp
@@ -30,11 +30,11 @@
#include "WebGLCompressedTexturePVRTC.h"
#include "Extensions3D.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-WebGLCompressedTexturePVRTC::WebGLCompressedTexturePVRTC(WebGLRenderingContextBase* context)
+WebGLCompressedTexturePVRTC::WebGLCompressedTexturePVRTC(WebGLRenderingContext* context)
: WebGLExtension(context)
{
context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG);
@@ -52,7 +52,12 @@ WebGLExtension::ExtensionName WebGLCompressedTexturePVRTC::getName() const
return WebGLCompressedTexturePVRTCName;
}
-bool WebGLCompressedTexturePVRTC::supported(WebGLRenderingContextBase* context)
+OwnPtr<WebGLCompressedTexturePVRTC> WebGLCompressedTexturePVRTC::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new WebGLCompressedTexturePVRTC(context));
+}
+
+bool WebGLCompressedTexturePVRTC::supported(WebGLRenderingContext* context)
{
Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
return extensions->supports("GL_IMG_texture_compression_pvrtc");
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.h b/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.h
index 361f09ebf..f20e2d25d 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.h
+++ b/Source/WebCore/html/canvas/WebGLCompressedTexturePVRTC.h
@@ -27,16 +27,21 @@
#define WebGLCompressedTexturePVRTC_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLCompressedTexturePVRTC final : public WebGLExtension {
+class WebGLCompressedTexturePVRTC : public WebGLExtension {
public:
- explicit WebGLCompressedTexturePVRTC(WebGLRenderingContextBase*);
- virtual ~WebGLCompressedTexturePVRTC();
+ static OwnPtr<WebGLCompressedTexturePVRTC> create(WebGLRenderingContext*);
+
+ static bool supported(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContextBase*);
+ virtual ~WebGLCompressedTexturePVRTC();
virtual ExtensionName getName() const override;
+
+private:
+ WebGLCompressedTexturePVRTC(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.cpp b/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.cpp
index 42bcd0810..bcf1a3267 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.cpp
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.cpp
@@ -30,11 +30,11 @@
#include "WebGLCompressedTextureS3TC.h"
#include "Extensions3D.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-WebGLCompressedTextureS3TC::WebGLCompressedTextureS3TC(WebGLRenderingContextBase* context)
+WebGLCompressedTextureS3TC::WebGLCompressedTextureS3TC(WebGLRenderingContext* context)
: WebGLExtension(context)
{
context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT);
@@ -52,7 +52,12 @@ WebGLExtension::ExtensionName WebGLCompressedTextureS3TC::getName() const
return WebGLCompressedTextureS3TCName;
}
-bool WebGLCompressedTextureS3TC::supported(WebGLRenderingContextBase* context)
+OwnPtr<WebGLCompressedTextureS3TC> WebGLCompressedTextureS3TC::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new WebGLCompressedTextureS3TC(context));
+}
+
+bool WebGLCompressedTextureS3TC::supported(WebGLRenderingContext* context)
{
Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
return extensions->supports("GL_EXT_texture_compression_s3tc")
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.h b/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.h
index 5590ef67d..c6c9edb45 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.h
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureS3TC.h
@@ -27,19 +27,23 @@
#define WebGLCompressedTextureS3TC_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
class WebGLTexture;
-class WebGLCompressedTextureS3TC final : public WebGLExtension {
+class WebGLCompressedTextureS3TC : public WebGLExtension {
public:
- explicit WebGLCompressedTextureS3TC(WebGLRenderingContextBase*);
- virtual ~WebGLCompressedTextureS3TC();
+ static OwnPtr<WebGLCompressedTextureS3TC> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContext*);
+ virtual ~WebGLCompressedTextureS3TC();
virtual ExtensionName getName() const override;
+
+private:
+ WebGLCompressedTextureS3TC(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.cpp b/Source/WebCore/html/canvas/WebGLContextAttributes.cpp
index 2abfeb8f0..e36e04ef0 100644
--- a/Source/WebCore/html/canvas/WebGLContextAttributes.cpp
+++ b/Source/WebCore/html/canvas/WebGLContextAttributes.cpp
@@ -32,14 +32,14 @@
namespace WebCore {
-Ref<WebGLContextAttributes> WebGLContextAttributes::create()
+PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create()
{
- return adoptRef(*new WebGLContextAttributes());
+ return adoptRef(new WebGLContextAttributes());
}
-Ref<WebGLContextAttributes> WebGLContextAttributes::create(GraphicsContext3D::Attributes attributes)
+PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create(GraphicsContext3D::Attributes attributes)
{
- return adoptRef(*new WebGLContextAttributes(attributes));
+ return adoptRef(new WebGLContextAttributes(attributes));
}
WebGLContextAttributes::WebGLContextAttributes()
diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.h b/Source/WebCore/html/canvas/WebGLContextAttributes.h
index ac00d057b..5391a2b7d 100644
--- a/Source/WebCore/html/canvas/WebGLContextAttributes.h
+++ b/Source/WebCore/html/canvas/WebGLContextAttributes.h
@@ -29,18 +29,19 @@
#include "CanvasContextAttributes.h"
#include "GraphicsContext3D.h"
+#include <wtf/PassRefPtr.h>
namespace WebCore {
-class WebGLContextAttributes final : public CanvasContextAttributes {
+class WebGLContextAttributes : public CanvasContextAttributes {
public:
virtual ~WebGLContextAttributes();
// Create a new attributes object
- static Ref<WebGLContextAttributes> create();
+ static PassRefPtr<WebGLContextAttributes> create();
// Create a new attributes object initialized with preexisting attributes
- static Ref<WebGLContextAttributes> create(GraphicsContext3D::Attributes);
+ static PassRefPtr<WebGLContextAttributes> create(GraphicsContext3D::Attributes attributes);
// Whether or not the drawing buffer has an alpha channel; default=true
bool alpha() const;
diff --git a/Source/WebCore/html/canvas/WebGLContextEvent.h b/Source/WebCore/html/canvas/WebGLContextEvent.h
index 20565e683..fa1ebfbc8 100644
--- a/Source/WebCore/html/canvas/WebGLContextEvent.h
+++ b/Source/WebCore/html/canvas/WebGLContextEvent.h
@@ -36,19 +36,19 @@ struct WebGLContextEventInit : public EventInit {
String statusMessage;
};
-class WebGLContextEvent final : public Event {
+class WebGLContextEvent : public Event {
public:
- static Ref<WebGLContextEvent> create()
+ static PassRefPtr<WebGLContextEvent> create()
{
- return adoptRef(*new WebGLContextEvent);
+ return adoptRef(new WebGLContextEvent);
}
- static Ref<WebGLContextEvent> create(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
+ static PassRefPtr<WebGLContextEvent> create(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
{
- return adoptRef(*new WebGLContextEvent(type, canBubble, cancelable, statusMessage));
+ return adoptRef(new WebGLContextEvent(type, canBubble, cancelable, statusMessage));
}
- static Ref<WebGLContextEvent> create(const AtomicString& type, const WebGLContextEventInit& initializer)
+ static PassRefPtr<WebGLContextEvent> create(const AtomicString& type, const WebGLContextEventInit& initializer)
{
- return adoptRef(*new WebGLContextEvent(type, initializer));
+ return adoptRef(new WebGLContextEvent(type, initializer));
}
virtual ~WebGLContextEvent();
diff --git a/Source/WebCore/html/canvas/WebGLContextGroup.cpp b/Source/WebCore/html/canvas/WebGLContextGroup.cpp
index baa4b21c7..6f182e22d 100644
--- a/Source/WebCore/html/canvas/WebGLContextGroup.cpp
+++ b/Source/WebCore/html/canvas/WebGLContextGroup.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,14 +30,15 @@
#include "WebGLContextGroup.h"
#include "GraphicsContext3D.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
#include "WebGLSharedObject.h"
namespace WebCore {
-Ref<WebGLContextGroup> WebGLContextGroup::create()
+PassRefPtr<WebGLContextGroup> WebGLContextGroup::create()
{
- return adoptRef(*new WebGLContextGroup());
+ RefPtr<WebGLContextGroup> contextGroup = adoptRef(new WebGLContextGroup());
+ return contextGroup.release();
}
WebGLContextGroup::WebGLContextGroup()
@@ -52,16 +53,16 @@ WebGLContextGroup::~WebGLContextGroup()
GraphicsContext3D* WebGLContextGroup::getAGraphicsContext3D()
{
ASSERT(!m_contexts.isEmpty());
- HashSet<WebGLRenderingContextBase*>::iterator it = m_contexts.begin();
+ HashSet<WebGLRenderingContext*>::iterator it = m_contexts.begin();
return (*it)->graphicsContext3D();
}
-void WebGLContextGroup::addContext(WebGLRenderingContextBase* context)
+void WebGLContextGroup::addContext(WebGLRenderingContext* context)
{
m_contexts.add(context);
}
-void WebGLContextGroup::removeContext(WebGLRenderingContextBase* context)
+void WebGLContextGroup::removeContext(WebGLRenderingContext* context)
{
// We must call detachAndRemoveAllObjects before removing the last context.
if (m_contexts.size() == 1 && m_contexts.contains(context))
@@ -88,9 +89,9 @@ void WebGLContextGroup::detachAndRemoveAllObjects()
}
}
-void WebGLContextGroup::loseContextGroup(WebGLRenderingContextBase::LostContextMode mode)
+void WebGLContextGroup::loseContextGroup(WebGLRenderingContext::LostContextMode mode)
{
- for (HashSet<WebGLRenderingContextBase*>::iterator it = m_contexts.begin(); it != m_contexts.end(); ++it)
+ for (HashSet<WebGLRenderingContext*>::iterator it = m_contexts.begin(); it != m_contexts.end(); ++it)
(*it)->loseContextImpl(mode);
detachAndRemoveAllObjects();
diff --git a/Source/WebCore/html/canvas/WebGLContextGroup.h b/Source/WebCore/html/canvas/WebGLContextGroup.h
index 311e28067..aa7036ae6 100644
--- a/Source/WebCore/html/canvas/WebGLContextGroup.h
+++ b/Source/WebCore/html/canvas/WebGLContextGroup.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,8 +26,9 @@
#ifndef WebGLContextGroup_h
#define WebGLContextGroup_h
-#include "WebGLRenderingContextBase.h"
+#include <WebGLRenderingContext.h>
#include <wtf/HashSet.h>
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -35,24 +36,24 @@ namespace WebCore {
class GraphicsContext3D;
class WebGLExtension;
class WebGLSharedObject;
-class WebGLRenderingContextBase;
+class WebGLRenderingContext;
typedef int ExceptionCode;
-class WebGLContextGroup final : public RefCounted<WebGLContextGroup> {
+class WebGLContextGroup : public RefCounted<WebGLContextGroup> {
public:
- static Ref<WebGLContextGroup> create();
- ~WebGLContextGroup();
+ static PassRefPtr<WebGLContextGroup> create();
+ virtual ~WebGLContextGroup();
- void addContext(WebGLRenderingContextBase*);
- void removeContext(WebGLRenderingContextBase*);
+ void addContext(WebGLRenderingContext*);
+ void removeContext(WebGLRenderingContext*);
void addObject(WebGLSharedObject*);
void removeObject(WebGLSharedObject*);
GraphicsContext3D* getAGraphicsContext3D();
- void loseContextGroup(WebGLRenderingContextBase::LostContextMode);
+ void loseContextGroup(WebGLRenderingContext::LostContextMode);
private:
friend class WebGLObject;
@@ -61,7 +62,7 @@ public:
void detachAndRemoveAllObjects();
- HashSet<WebGLRenderingContextBase*> m_contexts;
+ HashSet<WebGLRenderingContext*> m_contexts;
HashSet<WebGLSharedObject*> m_groupObjects;
};
diff --git a/Source/WebCore/html/canvas/WebGLContextObject.cpp b/Source/WebCore/html/canvas/WebGLContextObject.cpp
index 4ff1074b1..9b3ab0b9c 100644
--- a/Source/WebCore/html/canvas/WebGLContextObject.cpp
+++ b/Source/WebCore/html/canvas/WebGLContextObject.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -29,11 +29,11 @@
#include "WebGLContextObject.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-WebGLContextObject::WebGLContextObject(WebGLRenderingContextBase* context)
+WebGLContextObject::WebGLContextObject(WebGLRenderingContext* context)
: WebGLObject(context)
, m_context(context)
{
diff --git a/Source/WebCore/html/canvas/WebGLContextObject.h b/Source/WebCore/html/canvas/WebGLContextObject.h
index 43f02edd7..e674b1c64 100644
--- a/Source/WebCore/html/canvas/WebGLContextObject.h
+++ b/Source/WebCore/html/canvas/WebGLContextObject.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -31,7 +31,7 @@
namespace WebCore {
class GraphicsContext3D;
-class WebGLRenderingContextBase;
+class WebGLRenderingContext;
// WebGLContextObject the base class for objects that are owned by a specific
// WebGLRenderingContext.
@@ -39,9 +39,9 @@ class WebGLContextObject : public WebGLObject {
public:
virtual ~WebGLContextObject();
- WebGLRenderingContextBase* context() const { return m_context; }
+ WebGLRenderingContext* context() const { return m_context; }
- virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContextBase* context) const override
+ virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContext* context) const override
{
return context == m_context;
}
@@ -49,7 +49,7 @@ public:
void detachContext();
protected:
- WebGLContextObject(WebGLRenderingContextBase*);
+ WebGLContextObject(WebGLRenderingContext*);
virtual bool hasGroupOrContext() const override
{
@@ -59,7 +59,7 @@ protected:
virtual GraphicsContext3D* getAGraphicsContext3D() const override;
private:
- WebGLRenderingContextBase* m_context;
+ WebGLRenderingContext* m_context;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp
index 203a5c377..2fe5f171d 100644
--- a/Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp
+++ b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.cpp
@@ -29,11 +29,11 @@
#include "WebGLDebugRendererInfo.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-WebGLDebugRendererInfo::WebGLDebugRendererInfo(WebGLRenderingContextBase* context)
+WebGLDebugRendererInfo::WebGLDebugRendererInfo(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -47,6 +47,11 @@ WebGLExtension::ExtensionName WebGLDebugRendererInfo::getName() const
return WebGLDebugRendererInfoName;
}
+OwnPtr<WebGLDebugRendererInfo> WebGLDebugRendererInfo::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new WebGLDebugRendererInfo(context));
+}
+
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLDebugRendererInfo.h b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.h
index 07b8f7293..4422f84de 100644
--- a/Source/WebCore/html/canvas/WebGLDebugRendererInfo.h
+++ b/Source/WebCore/html/canvas/WebGLDebugRendererInfo.h
@@ -27,20 +27,24 @@
#define WebGLDebugRendererInfo_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLDebugRendererInfo final : public WebGLExtension {
+class WebGLDebugRendererInfo : public WebGLExtension {
public:
enum EnumType {
UNMASKED_VENDOR_WEBGL = 0x9245,
UNMASKED_RENDERER_WEBGL = 0x9246
};
- explicit WebGLDebugRendererInfo(WebGLRenderingContextBase*);
- virtual ~WebGLDebugRendererInfo();
+ static OwnPtr<WebGLDebugRendererInfo> create(WebGLRenderingContext*);
+ virtual ~WebGLDebugRendererInfo();
virtual ExtensionName getName() const override;
+
+private:
+ WebGLDebugRendererInfo(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLDebugShaders.cpp b/Source/WebCore/html/canvas/WebGLDebugShaders.cpp
index 2a96fe26a..0c028265c 100644
--- a/Source/WebCore/html/canvas/WebGLDebugShaders.cpp
+++ b/Source/WebCore/html/canvas/WebGLDebugShaders.cpp
@@ -30,12 +30,12 @@
#include "WebGLDebugShaders.h"
#include "Extensions3D.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
#include "WebGLShader.h"
namespace WebCore {
-WebGLDebugShaders::WebGLDebugShaders(WebGLRenderingContextBase* context)
+WebGLDebugShaders::WebGLDebugShaders(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -49,6 +49,11 @@ WebGLExtension::ExtensionName WebGLDebugShaders::getName() const
return WebGLDebugShadersName;
}
+OwnPtr<WebGLDebugShaders> WebGLDebugShaders::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new WebGLDebugShaders(context));
+}
+
String WebGLDebugShaders::getTranslatedShaderSource(WebGLShader* shader, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
diff --git a/Source/WebCore/html/canvas/WebGLDebugShaders.h b/Source/WebCore/html/canvas/WebGLDebugShaders.h
index 5a9e38b4c..961f488ce 100644
--- a/Source/WebCore/html/canvas/WebGLDebugShaders.h
+++ b/Source/WebCore/html/canvas/WebGLDebugShaders.h
@@ -27,6 +27,7 @@
#define WebGLDebugShaders_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
@@ -34,14 +35,17 @@ class WebGLShader;
typedef int ExceptionCode;
-class WebGLDebugShaders final : public WebGLExtension {
+class WebGLDebugShaders : public WebGLExtension {
public:
- explicit WebGLDebugShaders(WebGLRenderingContextBase*);
- virtual ~WebGLDebugShaders();
+ static OwnPtr<WebGLDebugShaders> create(WebGLRenderingContext*);
+ virtual ~WebGLDebugShaders();
virtual ExtensionName getName() const override;
String getTranslatedShaderSource(WebGLShader*, ExceptionCode&);
+
+private:
+ WebGLDebugShaders(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLDepthTexture.cpp b/Source/WebCore/html/canvas/WebGLDepthTexture.cpp
index 8fd907935..71a8da7d4 100644
--- a/Source/WebCore/html/canvas/WebGLDepthTexture.cpp
+++ b/Source/WebCore/html/canvas/WebGLDepthTexture.cpp
@@ -33,7 +33,7 @@
namespace WebCore {
-WebGLDepthTexture::WebGLDepthTexture(WebGLRenderingContextBase* context)
+WebGLDepthTexture::WebGLDepthTexture(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -47,6 +47,11 @@ WebGLExtension::ExtensionName WebGLDepthTexture::getName() const
return WebGLDepthTextureName;
}
+OwnPtr<WebGLDepthTexture> WebGLDepthTexture::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new WebGLDepthTexture(context));
+}
+
bool WebGLDepthTexture::supported(GraphicsContext3D* context)
{
Extensions3D* extensions = context->getExtensions();
diff --git a/Source/WebCore/html/canvas/WebGLDepthTexture.h b/Source/WebCore/html/canvas/WebGLDepthTexture.h
index 130d0c98a..8687c2543 100644
--- a/Source/WebCore/html/canvas/WebGLDepthTexture.h
+++ b/Source/WebCore/html/canvas/WebGLDepthTexture.h
@@ -27,17 +27,21 @@
#define WebGLDepthTexture_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLDepthTexture final : public WebGLExtension {
+class WebGLDepthTexture : public WebGLExtension {
public:
- explicit WebGLDepthTexture(WebGLRenderingContextBase*);
- virtual ~WebGLDepthTexture();
+ static OwnPtr<WebGLDepthTexture> create(WebGLRenderingContext*);
static bool supported(GraphicsContext3D*);
+ virtual ~WebGLDepthTexture();
virtual ExtensionName getName() const override;
+
+private:
+ WebGLDepthTexture(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLDrawBuffers.idl b/Source/WebCore/html/canvas/WebGLDrawBuffers.idl
deleted file mode 100644
index f8e783e84..000000000
--- a/Source/WebCore/html/canvas/WebGLDrawBuffers.idl
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-typedef unsigned long GLenum;
-
-[
- NoInterfaceObject,
- Conditional=WEBGL,
- GenerateIsReachable=ImplWebGLRenderingContext,
- DoNotCheckConstants,
-] interface WebGLDrawBuffers {
- const GLenum COLOR_ATTACHMENT0_WEBGL = 0x8CE0;
- const GLenum COLOR_ATTACHMENT1_WEBGL = 0x8CE1;
- const GLenum COLOR_ATTACHMENT2_WEBGL = 0x8CE2;
- const GLenum COLOR_ATTACHMENT3_WEBGL = 0x8CE3;
- const GLenum COLOR_ATTACHMENT4_WEBGL = 0x8CE4;
- const GLenum COLOR_ATTACHMENT5_WEBGL = 0x8CE5;
- const GLenum COLOR_ATTACHMENT6_WEBGL = 0x8CE6;
- const GLenum COLOR_ATTACHMENT7_WEBGL = 0x8CE7;
- const GLenum COLOR_ATTACHMENT8_WEBGL = 0x8CE8;
- const GLenum COLOR_ATTACHMENT9_WEBGL = 0x8CE9;
- const GLenum COLOR_ATTACHMENT10_WEBGL = 0x8CEA;
- const GLenum COLOR_ATTACHMENT11_WEBGL = 0x8CEB;
- const GLenum COLOR_ATTACHMENT12_WEBGL = 0x8CEC;
- const GLenum COLOR_ATTACHMENT13_WEBGL = 0x8CED;
- const GLenum COLOR_ATTACHMENT14_WEBGL = 0x8CEE;
- const GLenum COLOR_ATTACHMENT15_WEBGL = 0x8CEF;
-
- const GLenum DRAW_BUFFER0_WEBGL = 0x8825;
- const GLenum DRAW_BUFFER1_WEBGL = 0x8826;
- const GLenum DRAW_BUFFER2_WEBGL = 0x8827;
- const GLenum DRAW_BUFFER3_WEBGL = 0x8828;
- const GLenum DRAW_BUFFER4_WEBGL = 0x8829;
- const GLenum DRAW_BUFFER5_WEBGL = 0x882A;
- const GLenum DRAW_BUFFER6_WEBGL = 0x882B;
- const GLenum DRAW_BUFFER7_WEBGL = 0x882C;
- const GLenum DRAW_BUFFER8_WEBGL = 0x882D;
- const GLenum DRAW_BUFFER9_WEBGL = 0x882E;
- const GLenum DRAW_BUFFER10_WEBGL = 0x882F;
- const GLenum DRAW_BUFFER11_WEBGL = 0x8830;
- const GLenum DRAW_BUFFER12_WEBGL = 0x8831;
- const GLenum DRAW_BUFFER13_WEBGL = 0x8832;
- const GLenum DRAW_BUFFER14_WEBGL = 0x8833;
- const GLenum DRAW_BUFFER15_WEBGL = 0x8834;
-
- const GLenum MAX_COLOR_ATTACHMENTS_WEBGL = 0x8CDF;
- const GLenum MAX_DRAW_BUFFERS_WEBGL = 0x8824;
-
- void drawBuffersWEBGL(sequence<GLenum> buffers);
-};
diff --git a/Source/WebCore/html/canvas/WebGLExtension.cpp b/Source/WebCore/html/canvas/WebGLExtension.cpp
index 09a628801..bf62eecec 100644
--- a/Source/WebCore/html/canvas/WebGLExtension.cpp
+++ b/Source/WebCore/html/canvas/WebGLExtension.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-WebGLExtension::WebGLExtension(WebGLRenderingContextBase* context)
+WebGLExtension::WebGLExtension(WebGLRenderingContext* context)
: m_context(context)
{
}
diff --git a/Source/WebCore/html/canvas/WebGLExtension.h b/Source/WebCore/html/canvas/WebGLExtension.h
index 0edbe9eca..e9100dba0 100644
--- a/Source/WebCore/html/canvas/WebGLExtension.h
+++ b/Source/WebCore/html/canvas/WebGLExtension.h
@@ -26,7 +26,7 @@
#ifndef WebGLExtension_h
#define WebGLExtension_h
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
@@ -36,11 +36,8 @@ public:
// Extension names are needed to properly wrap instances in JavaScript objects.
enum ExtensionName {
WebGLLoseContextName,
- EXTBlendMinMaxName,
- EXTFragDepthName,
- EXTShaderTextureLODName,
+ EXTDrawBuffersName,
EXTTextureFilterAnisotropicName,
- EXTsRGBName,
OESTextureFloatName,
OESTextureFloatLinearName,
OESTextureHalfFloatName,
@@ -51,7 +48,6 @@ public:
WebGLDebugShadersName,
WebGLCompressedTextureS3TCName,
WebGLDepthTextureName,
- WebGLDrawBuffersName,
OESElementIndexUintName,
WebGLCompressedTextureATCName,
WebGLCompressedTexturePVRTCName,
@@ -60,14 +56,14 @@ public:
void ref() { m_context->ref(); }
void deref() { m_context->deref(); }
- WebGLRenderingContextBase* context() { return m_context; }
+ WebGLRenderingContext* context() { return m_context; }
virtual ~WebGLExtension();
virtual ExtensionName getName() const = 0;
protected:
- WebGLExtension(WebGLRenderingContextBase*);
- WebGLRenderingContextBase* m_context;
+ WebGLExtension(WebGLRenderingContext*);
+ WebGLRenderingContext* m_context;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
index 60399a373..7e1dc07f5 100644
--- a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -29,10 +29,10 @@
#include "WebGLFramebuffer.h"
+#include "EXTDrawBuffers.h"
#include "Extensions3D.h"
#include "WebGLContextGroup.h"
-#include "WebGLDrawBuffers.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
@@ -45,7 +45,7 @@ namespace {
class WebGLRenderbufferAttachment : public WebGLFramebuffer::WebGLAttachment {
public:
- static Ref<WebGLFramebuffer::WebGLAttachment> create(WebGLRenderbuffer*);
+ static PassRefPtr<WebGLFramebuffer::WebGLAttachment> create(WebGLRenderbuffer*);
private:
WebGLRenderbufferAttachment(WebGLRenderbuffer*);
@@ -66,9 +66,9 @@ namespace {
RefPtr<WebGLRenderbuffer> m_renderbuffer;
};
- Ref<WebGLFramebuffer::WebGLAttachment> WebGLRenderbufferAttachment::create(WebGLRenderbuffer* renderbuffer)
+ PassRefPtr<WebGLFramebuffer::WebGLAttachment> WebGLRenderbufferAttachment::create(WebGLRenderbuffer* renderbuffer)
{
- return adoptRef(*new WebGLRenderbufferAttachment(renderbuffer));
+ return adoptRef(new WebGLRenderbufferAttachment(renderbuffer));
}
WebGLRenderbufferAttachment::WebGLRenderbufferAttachment(WebGLRenderbuffer* renderbuffer)
@@ -139,7 +139,7 @@ namespace {
class WebGLTextureAttachment : public WebGLFramebuffer::WebGLAttachment {
public:
- static Ref<WebGLFramebuffer::WebGLAttachment> create(WebGLTexture*, GC3Denum target, GC3Dint level);
+ static PassRefPtr<WebGLFramebuffer::WebGLAttachment> create(WebGLTexture*, GC3Denum target, GC3Dint level);
private:
WebGLTextureAttachment(WebGLTexture*, GC3Denum target, GC3Dint level);
@@ -162,9 +162,9 @@ namespace {
GC3Dint m_level;
};
- Ref<WebGLFramebuffer::WebGLAttachment> WebGLTextureAttachment::create(WebGLTexture* texture, GC3Denum target, GC3Dint level)
+ PassRefPtr<WebGLFramebuffer::WebGLAttachment> WebGLTextureAttachment::create(WebGLTexture* texture, GC3Denum target, GC3Dint level)
{
- return adoptRef(*new WebGLTextureAttachment(texture, target, level));
+ return adoptRef(new WebGLTextureAttachment(texture, target, level));
}
WebGLTextureAttachment::WebGLTextureAttachment(WebGLTexture* texture, GC3Denum target, GC3Dint level)
@@ -269,12 +269,12 @@ WebGLFramebuffer::WebGLAttachment::~WebGLAttachment()
{
}
-Ref<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContextBase* ctx)
+PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx)
{
- return adoptRef(*new WebGLFramebuffer(ctx));
+ return adoptRef(new WebGLFramebuffer(ctx));
}
-WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContextBase* ctx)
+WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
: WebGLContextObject(ctx)
, m_hasEverBeenBound(false)
{
@@ -369,7 +369,7 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* a
return;
bool checkMore = true;
- do {
+ while (checkMore) {
checkMore = false;
for (AttachmentMap::iterator it = m_attachments.begin(); it != m_attachments.end(); ++it) {
WebGLAttachment* attachmentObject = it->value.get();
@@ -381,7 +381,7 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* a
break;
}
}
- } while (checkMore);
+ }
}
GC3Dsizei WebGLFramebuffer::getColorBufferWidth() const
@@ -431,13 +431,7 @@ GC3Denum WebGLFramebuffer::checkStatus(const char** reason) const
*reason = "attachment is not valid";
return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
}
- GC3Denum attachmentFormat = attachment->getFormat();
-
- // Attaching an SRGB_EXT format attachment to a framebuffer is invalid.
- if (attachmentFormat == Extensions3D::SRGB_EXT)
- attachmentFormat = 0;
-
- if (!attachmentFormat) {
+ if (!attachment->getFormat()) {
*reason = "attachment is an unsupported format";
return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -607,10 +601,8 @@ void WebGLFramebuffer::drawBuffers(const Vector<GC3Denum>& bufs)
void WebGLFramebuffer::drawBuffersIfNecessary(bool force)
{
-#if ENABLE(WEBGL2)
- if (!context()->m_webglDrawBuffers && !context()->isWebGL2())
+ if (!context()->m_extDrawBuffers)
return;
-#endif
bool reset = force;
// This filtering works around graphics driver bugs on Mac OS X.
for (size_t i = 0; i < m_drawBuffers.size(); ++i) {
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.h b/Source/WebCore/html/canvas/WebGLFramebuffer.h
index e0920d7dc..a0ee31c69 100644
--- a/Source/WebCore/html/canvas/WebGLFramebuffer.h
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -37,7 +37,7 @@ namespace WebCore {
class WebGLRenderbuffer;
class WebGLTexture;
-class WebGLFramebuffer final : public WebGLContextObject {
+class WebGLFramebuffer : public WebGLContextObject {
public:
class WebGLAttachment : public RefCounted<WebGLAttachment> {
public:
@@ -61,7 +61,7 @@ public:
virtual ~WebGLFramebuffer();
- static Ref<WebGLFramebuffer> create(WebGLRenderingContextBase*);
+ static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
void setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture*, GC3Dint level);
void setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer*);
@@ -101,11 +101,13 @@ public:
GC3Denum getDrawBuffer(GC3Denum);
protected:
- WebGLFramebuffer(WebGLRenderingContextBase*);
+ WebGLFramebuffer(WebGLRenderingContext*);
virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
private:
+ virtual bool isFramebuffer() const { return true; }
+
WebGLAttachment* getAttachment(GC3Denum) const;
// Return false if framebuffer is incomplete.
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.idl b/Source/WebCore/html/canvas/WebGLFramebuffer.idl
index 7c6cc4595..e609513b2 100644
--- a/Source/WebCore/html/canvas/WebGLFramebuffer.idl
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.cpp b/Source/WebCore/html/canvas/WebGLGetInfo.cpp
index 4558b8af9..8e27d3b9a 100644
--- a/Source/WebCore/html/canvas/WebGLGetInfo.cpp
+++ b/Source/WebCore/html/canvas/WebGLGetInfo.cpp
@@ -30,6 +30,12 @@
#include "WebGLGetInfo.h"
+#include "WebGLBuffer.h"
+#include "WebGLFramebuffer.h"
+#include "WebGLProgram.h"
+#include "WebGLRenderbuffer.h"
+#include "WebGLTexture.h"
+#include "WebGLVertexArrayObjectOES.h"
#include <runtime/Float32Array.h>
#include <runtime/Int32Array.h>
#include <runtime/Uint32Array.h>
@@ -43,7 +49,6 @@ WebGLGetInfo::WebGLGetInfo(bool value)
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
{
}
@@ -53,7 +58,6 @@ WebGLGetInfo::WebGLGetInfo(const bool* value, int size)
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
{
if (!value || size <=0)
return;
@@ -68,7 +72,6 @@ WebGLGetInfo::WebGLGetInfo(float value)
, m_float(value)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
{
}
@@ -78,7 +81,6 @@ WebGLGetInfo::WebGLGetInfo(int value)
, m_float(0)
, m_int(value)
, m_unsignedInt(0)
- , m_int64(0)
{
}
@@ -88,7 +90,6 @@ WebGLGetInfo::WebGLGetInfo()
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
{
}
@@ -99,7 +100,6 @@ WebGLGetInfo::WebGLGetInfo(const String& value)
, m_int(0)
, m_string(value)
, m_unsignedInt(0)
- , m_int64(0)
{
}
@@ -109,28 +109,15 @@ WebGLGetInfo::WebGLGetInfo(unsigned int value)
, m_float(0)
, m_int(0)
, m_unsignedInt(value)
- , m_int64(0)
{
}
-WebGLGetInfo::WebGLGetInfo(long long value)
- : m_type(kTypeInt64)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
- , m_int64(value)
-{
-}
-
-
WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLBuffer> value)
: m_type(kTypeWebGLBuffer)
, m_bool(false)
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
, m_webglBuffer(value)
{
}
@@ -141,7 +128,6 @@ WebGLGetInfo::WebGLGetInfo(PassRefPtr<Float32Array> value)
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
, m_webglFloatArray(value)
{
}
@@ -152,7 +138,6 @@ WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLFramebuffer> value)
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
, m_webglFramebuffer(value)
{
}
@@ -163,7 +148,6 @@ WebGLGetInfo::WebGLGetInfo(PassRefPtr<Int32Array> value)
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
, m_webglIntArray(value)
{
}
@@ -174,7 +158,6 @@ WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLProgram> value)
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
, m_webglProgram(value)
{
}
@@ -185,7 +168,6 @@ WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLRenderbuffer> value)
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
, m_webglRenderbuffer(value)
{
}
@@ -196,7 +178,6 @@ WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLTexture> value)
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
, m_webglTexture(value)
{
}
@@ -207,7 +188,6 @@ WebGLGetInfo::WebGLGetInfo(PassRefPtr<Uint8Array> value)
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
, m_webglUnsignedByteArray(value)
{
}
@@ -218,7 +198,6 @@ WebGLGetInfo::WebGLGetInfo(PassRefPtr<Uint32Array> value)
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
, m_webglUnsignedIntArray(value)
{
}
@@ -229,23 +208,9 @@ WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES> value)
, m_float(0)
, m_int(0)
, m_unsignedInt(0)
- , m_int64(0)
- , m_webglVertexArrayObjectOES(value)
-{
-}
-
-#if ENABLE(WEBGL2)
-WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLVertexArrayObject> value)
- : m_type(kTypeWebGLVertexArrayObject)
- , m_bool(false)
- , m_float(0)
- , m_int(0)
- , m_unsignedInt(0)
- , m_int64(0)
, m_webglVertexArrayObject(value)
{
}
-#endif
WebGLGetInfo::~WebGLGetInfo()
{
@@ -292,12 +257,6 @@ unsigned int WebGLGetInfo::getUnsignedInt() const
return m_unsignedInt;
}
-long long WebGLGetInfo::getInt64() const
-{
- ASSERT(getType() == kTypeInt64);
- return m_int64;
-}
-
PassRefPtr<WebGLBuffer> WebGLGetInfo::getWebGLBuffer() const
{
ASSERT(getType() == kTypeWebGLBuffer);
@@ -355,16 +314,8 @@ PassRefPtr<Uint32Array> WebGLGetInfo::getWebGLUnsignedIntArray() const
PassRefPtr<WebGLVertexArrayObjectOES> WebGLGetInfo::getWebGLVertexArrayObjectOES() const
{
ASSERT(getType() == kTypeWebGLVertexArrayObjectOES);
- return m_webglVertexArrayObjectOES;
-}
-
-#if ENABLE(WEBGL2)
-PassRefPtr<WebGLVertexArrayObject> WebGLGetInfo::getWebGLVertexArrayObject() const
-{
- ASSERT(getType() == kTypeWebGLVertexArrayObject);
return m_webglVertexArrayObject;
}
-#endif
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.h b/Source/WebCore/html/canvas/WebGLGetInfo.h
index 7b2de77c6..082612ac9 100644
--- a/Source/WebCore/html/canvas/WebGLGetInfo.h
+++ b/Source/WebCore/html/canvas/WebGLGetInfo.h
@@ -32,9 +32,6 @@
#include "WebGLProgram.h"
#include "WebGLRenderbuffer.h"
#include "WebGLTexture.h"
-#if ENABLE(WEBGL2)
-#include "WebGLVertexArrayObject.h"
-#endif
#include "WebGLVertexArrayObjectOES.h"
#include <runtime/Float32Array.h>
#include <runtime/Int32Array.h>
@@ -51,7 +48,7 @@ namespace WebCore {
// similar variants. For reference counted types, increments and
// decrements the reference count of the target object.
-class WebGLGetInfo final {
+class WebGLGetInfo {
public:
enum Type {
kTypeBool,
@@ -61,7 +58,6 @@ public:
kTypeNull,
kTypeString,
kTypeUnsignedInt,
- kTypeInt64,
kTypeWebGLBuffer,
kTypeWebGLFloatArray,
kTypeWebGLFramebuffer,
@@ -73,7 +69,6 @@ public:
kTypeWebGLUnsignedByteArray,
kTypeWebGLUnsignedIntArray,
kTypeWebGLVertexArrayObjectOES,
- kTypeWebGLVertexArrayObject,
};
explicit WebGLGetInfo(bool value);
@@ -84,7 +79,6 @@ public:
WebGLGetInfo();
explicit WebGLGetInfo(const String& value);
explicit WebGLGetInfo(unsigned int value);
- explicit WebGLGetInfo(long long value);
explicit WebGLGetInfo(PassRefPtr<WebGLBuffer> value);
explicit WebGLGetInfo(PassRefPtr<Float32Array> value);
explicit WebGLGetInfo(PassRefPtr<WebGLFramebuffer> value);
@@ -97,11 +91,8 @@ public:
explicit WebGLGetInfo(PassRefPtr<Uint8Array> value);
explicit WebGLGetInfo(PassRefPtr<Uint32Array> value);
explicit WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES> value);
-#if ENABLE(WEBGL2)
- explicit WebGLGetInfo(PassRefPtr<WebGLVertexArrayObject> value);
-#endif
- ~WebGLGetInfo();
+ virtual ~WebGLGetInfo();
Type getType() const;
@@ -111,7 +102,6 @@ public:
int getInt() const;
const String& getString() const;
unsigned int getUnsignedInt() const;
- long long getInt64() const;
PassRefPtr<WebGLBuffer> getWebGLBuffer() const;
PassRefPtr<Float32Array> getWebGLFloatArray() const;
PassRefPtr<WebGLFramebuffer> getWebGLFramebuffer() const;
@@ -124,9 +114,6 @@ public:
PassRefPtr<Uint8Array> getWebGLUnsignedByteArray() const;
PassRefPtr<Uint32Array> getWebGLUnsignedIntArray() const;
PassRefPtr<WebGLVertexArrayObjectOES> getWebGLVertexArrayObjectOES() const;
-#if ENABLE(WEBGL2)
- PassRefPtr<WebGLVertexArrayObject> getWebGLVertexArrayObject() const;
-#endif
private:
Type m_type;
@@ -136,7 +123,6 @@ private:
int m_int;
String m_string;
unsigned int m_unsignedInt;
- long long m_int64;
RefPtr<WebGLBuffer> m_webglBuffer;
RefPtr<Float32Array> m_webglFloatArray;
RefPtr<WebGLFramebuffer> m_webglFramebuffer;
@@ -148,10 +134,7 @@ private:
RefPtr<WebGLTexture> m_webglTexture;
RefPtr<Uint8Array> m_webglUnsignedByteArray;
RefPtr<Uint32Array> m_webglUnsignedIntArray;
- RefPtr<WebGLVertexArrayObjectOES> m_webglVertexArrayObjectOES;
-#if ENABLE(WEBGL2)
- RefPtr<WebGLVertexArrayObject> m_webglVertexArrayObject;
-#endif
+ RefPtr<WebGLVertexArrayObjectOES> m_webglVertexArrayObject;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLLoseContext.cpp b/Source/WebCore/html/canvas/WebGLLoseContext.cpp
index c65ae9088..9f4e0b01e 100644
--- a/Source/WebCore/html/canvas/WebGLLoseContext.cpp
+++ b/Source/WebCore/html/canvas/WebGLLoseContext.cpp
@@ -29,11 +29,11 @@
#include "WebGLLoseContext.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-WebGLLoseContext::WebGLLoseContext(WebGLRenderingContextBase* context)
+WebGLLoseContext::WebGLLoseContext(WebGLRenderingContext* context)
: WebGLExtension(context)
{
}
@@ -47,9 +47,14 @@ WebGLExtension::ExtensionName WebGLLoseContext::getName() const
return WebGLLoseContextName;
}
+OwnPtr<WebGLLoseContext> WebGLLoseContext::create(WebGLRenderingContext* context)
+{
+ return adoptPtr(new WebGLLoseContext(context));
+}
+
void WebGLLoseContext::loseContext()
{
- m_context->forceLostContext(WebGLRenderingContextBase::SyntheticLostContext);
+ m_context->forceLostContext(WebGLRenderingContext::SyntheticLostContext);
}
void WebGLLoseContext::restoreContext()
diff --git a/Source/WebCore/html/canvas/WebGLLoseContext.h b/Source/WebCore/html/canvas/WebGLLoseContext.h
index e6ce15711..edba14a7c 100644
--- a/Source/WebCore/html/canvas/WebGLLoseContext.h
+++ b/Source/WebCore/html/canvas/WebGLLoseContext.h
@@ -27,20 +27,24 @@
#define WebGLLoseContext_h
#include "WebGLExtension.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class WebGLRenderingContextBase;
+class WebGLRenderingContext;
-class WebGLLoseContext final : public WebGLExtension {
+class WebGLLoseContext : public WebGLExtension {
public:
- explicit WebGLLoseContext(WebGLRenderingContextBase*);
- virtual ~WebGLLoseContext();
+ static OwnPtr<WebGLLoseContext> create(WebGLRenderingContext*);
+ virtual ~WebGLLoseContext();
virtual ExtensionName getName() const override;
void loseContext();
void restoreContext();
+
+private:
+ WebGLLoseContext(WebGLRenderingContext*);
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLObject.cpp b/Source/WebCore/html/canvas/WebGLObject.cpp
index acdab979b..502877a0c 100644
--- a/Source/WebCore/html/canvas/WebGLObject.cpp
+++ b/Source/WebCore/html/canvas/WebGLObject.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -29,16 +29,17 @@
#include "WebGLObject.h"
+#include "EXTTextureFilterAnisotropic.h"
#include "WebGLCompressedTextureS3TC.h"
#include "WebGLContextGroup.h"
#include "WebGLDebugRendererInfo.h"
#include "WebGLDebugShaders.h"
#include "WebGLLoseContext.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-WebGLObject::WebGLObject(WebGLRenderingContextBase*)
+WebGLObject::WebGLObject(WebGLRenderingContext*)
: m_object(0)
, m_attachmentCount(0)
, m_deleted(false)
diff --git a/Source/WebCore/html/canvas/WebGLObject.h b/Source/WebCore/html/canvas/WebGLObject.h
index f9f241211..61af64461 100644
--- a/Source/WebCore/html/canvas/WebGLObject.h
+++ b/Source/WebCore/html/canvas/WebGLObject.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -34,7 +34,7 @@ namespace WebCore {
class GraphicsContext3D;
class WebGLContextGroup;
-class WebGLRenderingContextBase;
+class WebGLRenderingContext;
class WebGLObject : public RefCounted<WebGLObject> {
public:
@@ -56,10 +56,10 @@ public:
bool isDeleted() { return m_deleted; }
// True if this object belongs to the group or context.
- virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContextBase*) const = 0;
+ virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContext*) const = 0;
protected:
- WebGLObject(WebGLRenderingContextBase*);
+ WebGLObject(WebGLRenderingContext*);
// setObject should be only called once right after creating a WebGLObject.
void setObject(Platform3DObject);
diff --git a/Source/WebCore/html/canvas/WebGLProgram.cpp b/Source/WebCore/html/canvas/WebGLProgram.cpp
index 1b752e6e0..40d35949e 100644
--- a/Source/WebCore/html/canvas/WebGLProgram.cpp
+++ b/Source/WebCore/html/canvas/WebGLProgram.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,16 +30,16 @@
#include "WebGLProgram.h"
#include "WebGLContextGroup.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-Ref<WebGLProgram> WebGLProgram::create(WebGLRenderingContextBase* ctx)
+PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContext* ctx)
{
- return adoptRef(*new WebGLProgram(ctx));
+ return adoptRef(new WebGLProgram(ctx));
}
-WebGLProgram::WebGLProgram(WebGLRenderingContextBase* ctx)
+WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
: WebGLSharedObject(ctx)
, m_linkStatus(false)
, m_linkCount(0)
@@ -58,11 +58,11 @@ void WebGLProgram::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObje
context3d->deleteProgram(obj);
if (m_vertexShader) {
m_vertexShader->onDetached(context3d);
- m_vertexShader = nullptr;
+ m_vertexShader = 0;
}
if (m_fragmentShader) {
m_fragmentShader->onDetached(context3d);
- m_fragmentShader = nullptr;
+ m_fragmentShader = 0;
}
}
@@ -148,12 +148,12 @@ bool WebGLProgram::detachShader(WebGLShader* shader)
case GraphicsContext3D::VERTEX_SHADER:
if (m_vertexShader != shader)
return false;
- m_vertexShader = nullptr;
+ m_vertexShader = 0;
return true;
case GraphicsContext3D::FRAGMENT_SHADER:
if (m_fragmentShader != shader)
return false;
- m_fragmentShader = nullptr;
+ m_fragmentShader = 0;
return true;
default:
return false;
@@ -169,7 +169,7 @@ void WebGLProgram::cacheActiveAttribLocations(GraphicsContext3D* context3d)
m_activeAttribLocations.resize(static_cast<size_t>(numAttribs));
for (int i = 0; i < numAttribs; ++i) {
ActiveInfo info;
- context3d->getActiveAttribImpl(object(), i, info);
+ context3d->getActiveAttrib(object(), i, info);
m_activeAttribLocations[i] = context3d->getAttribLocation(object(), info.name);
}
}
diff --git a/Source/WebCore/html/canvas/WebGLProgram.h b/Source/WebCore/html/canvas/WebGLProgram.h
index 1d8bba101..718f18498 100644
--- a/Source/WebCore/html/canvas/WebGLProgram.h
+++ b/Source/WebCore/html/canvas/WebGLProgram.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,15 +30,16 @@
#include "WebGLShader.h"
+#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
-class WebGLProgram final : public WebGLSharedObject {
+class WebGLProgram : public WebGLSharedObject {
public:
virtual ~WebGLProgram();
- static Ref<WebGLProgram> create(WebGLRenderingContextBase*);
+ static PassRefPtr<WebGLProgram> create(WebGLRenderingContext*);
unsigned numActiveAttribLocations();
GC3Dint getActiveAttribLocation(GC3Duint index);
@@ -61,7 +62,7 @@ public:
bool detachShader(WebGLShader*);
protected:
- WebGLProgram(WebGLRenderingContextBase*);
+ WebGLProgram(WebGLRenderingContext*);
virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
diff --git a/Source/WebCore/html/canvas/WebGLProgram.idl b/Source/WebCore/html/canvas/WebGLProgram.idl
index 7c180e2b5..d404ebdb8 100644
--- a/Source/WebCore/html/canvas/WebGLProgram.idl
+++ b/Source/WebCore/html/canvas/WebGLProgram.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/WebGLQuery.cpp b/Source/WebCore/html/canvas/WebGLQuery.cpp
deleted file mode 100644
index c7f94349b..000000000
--- a/Source/WebCore/html/canvas/WebGLQuery.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL)
-#include "WebGLQuery.h"
-
-#include "WebGLContextGroup.h"
-#include "WebGLRenderingContextBase.h"
-
-namespace WebCore {
-
-Ref<WebGLQuery> WebGLQuery::create(WebGLRenderingContextBase* ctx)
-{
- return adoptRef(*new WebGLQuery(ctx));
-}
-
-WebGLQuery::~WebGLQuery()
-{
- deleteObject(0);
-}
-
-WebGLQuery::WebGLQuery(WebGLRenderingContextBase* ctx)
- : WebGLSharedObject(ctx)
-{
- // FIXME: Call createQuery from GraphicsContext3D.
-}
-
-void WebGLQuery::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
-{
- UNUSED_PARAM(context3d);
- UNUSED_PARAM(object);
- // FIXME: Call deleteQuery from GraphicsContext3D.
-}
-
-}
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLQuery.h b/Source/WebCore/html/canvas/WebGLQuery.h
deleted file mode 100644
index 107ace9c9..000000000
--- a/Source/WebCore/html/canvas/WebGLQuery.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebGLQuery_h
-#define WebGLQuery_h
-
-#include "WebGLSharedObject.h"
-
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class WebGLQuery final : public WebGLSharedObject {
-public:
- virtual ~WebGLQuery();
-
- static Ref<WebGLQuery> create(WebGLRenderingContextBase*);
-
-protected:
- WebGLQuery(WebGLRenderingContextBase*);
-
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
-
-private:
- virtual bool isQuery() const override { return true; }
-};
-
-} // namespace WebCore
-
-#endif // WebGLQuery_h
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp b/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
index 1d794290d..daaf9d4ee 100644
--- a/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,13 +30,13 @@
#include "WebGLRenderbuffer.h"
#include "WebGLContextGroup.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-Ref<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContextBase* ctx)
+PassRefPtr<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContext* ctx)
{
- return adoptRef(*new WebGLRenderbuffer(ctx));
+ return adoptRef(new WebGLRenderbuffer(ctx));
}
WebGLRenderbuffer::~WebGLRenderbuffer()
@@ -44,7 +44,7 @@ WebGLRenderbuffer::~WebGLRenderbuffer()
deleteObject(0);
}
-WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContextBase* ctx)
+WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
: WebGLSharedObject(ctx)
, m_internalFormat(GraphicsContext3D::RGBA4)
, m_initialized(false)
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.h b/Source/WebCore/html/canvas/WebGLRenderbuffer.h
index 8b67791ec..137953195 100644
--- a/Source/WebCore/html/canvas/WebGLRenderbuffer.h
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,15 +28,16 @@
#include "WebGLSharedObject.h"
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
-class WebGLRenderbuffer final : public WebGLSharedObject {
+class WebGLRenderbuffer : public WebGLSharedObject {
public:
virtual ~WebGLRenderbuffer();
- static Ref<WebGLRenderbuffer> create(WebGLRenderingContextBase*);
+ static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContext*);
void setInternalFormat(GC3Denum internalformat)
{
@@ -64,7 +65,7 @@ public:
void setHasEverBeenBound() { m_hasEverBeenBound = true; }
protected:
- WebGLRenderbuffer(WebGLRenderingContextBase*);
+ WebGLRenderbuffer(WebGLRenderingContext*);
virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.idl b/Source/WebCore/html/canvas/WebGLRenderbuffer.idl
index fb855a56c..618f9c472 100644
--- a/Source/WebCore/html/canvas/WebGLRenderbuffer.idl
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
index 121f1a99e..4cf443716 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2013, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,20 +26,28 @@
#include "config.h"
#if ENABLE(WEBGL)
+
#include "WebGLRenderingContext.h"
#include "ANGLEInstancedArrays.h"
#include "CachedImage.h"
-#include "EXTBlendMinMax.h"
-#include "EXTFragDepth.h"
-#include "EXTShaderTextureLOD.h"
+#include "DOMWindow.h"
+#include "EXTDrawBuffers.h"
#include "EXTTextureFilterAnisotropic.h"
-#include "EXTsRGB.h"
+#include "ExceptionCode.h"
#include "Extensions3D.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
+#include "FrameView.h"
#include "HTMLCanvasElement.h"
#include "HTMLImageElement.h"
#include "HTMLVideoElement.h"
+#include "ImageBuffer.h"
#include "ImageData.h"
+#include "IntSize.h"
+#include "Logging.h"
+#include "NotImplemented.h"
#include "OESElementIndexUint.h"
#include "OESStandardDerivatives.h"
#include "OESTextureFloat.h"
@@ -47,81 +55,2369 @@
#include "OESTextureHalfFloat.h"
#include "OESTextureHalfFloatLinear.h"
#include "OESVertexArrayObject.h"
+#include "Page.h"
#include "RenderBox.h"
+#include "Settings.h"
+#include "WebGLActiveInfo.h"
+#include "WebGLBuffer.h"
#include "WebGLCompressedTextureATC.h"
#include "WebGLCompressedTexturePVRTC.h"
#include "WebGLCompressedTextureS3TC.h"
+#include "WebGLContextAttributes.h"
+#include "WebGLContextEvent.h"
+#include "WebGLContextGroup.h"
#include "WebGLDebugRendererInfo.h"
#include "WebGLDebugShaders.h"
#include "WebGLDepthTexture.h"
-#include "WebGLDrawBuffers.h"
+#include "WebGLFramebuffer.h"
#include "WebGLLoseContext.h"
-#include "WebGLVertexArrayObjectOES.h"
+#include "WebGLProgram.h"
+#include "WebGLRenderbuffer.h"
+#include "WebGLShader.h"
+#include "WebGLShaderPrecisionFormat.h"
+#include "WebGLTexture.h"
+#include "WebGLUniformLocation.h"
+
+#include <runtime/Operations.h>
+#include <runtime/TypedArrayInlines.h>
+#include <runtime/Uint32Array.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+
+#if PLATFORM(WIN) || (PLATFORM(GTK) && OS(WINDOWS))
+#undef NO_ERROR
+#endif
+
+#if PLATFORM(GTK)
+#undef VERSION
+#endif
namespace WebCore {
-WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, GraphicsContext3D::Attributes attributes)
- : WebGLRenderingContextBase(passedCanvas, attributes)
+const double secondsBetweenRestoreAttempts = 1.0;
+const int maxGLErrorsAllowedToConsole = 256;
+
+namespace {
+
+ class ScopedDrawingBufferBinder {
+ public:
+ ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding)
+ : m_drawingBuffer(drawingBuffer)
+ , m_framebufferBinding(framebufferBinding)
+ {
+ // Commit DrawingBuffer if needed (e.g., for multisampling)
+ if (!m_framebufferBinding && m_drawingBuffer)
+ m_drawingBuffer->commit();
+ }
+
+ ~ScopedDrawingBufferBinder()
+ {
+ // Restore DrawingBuffer if needed
+ if (!m_framebufferBinding && m_drawingBuffer)
+ m_drawingBuffer->bind();
+ }
+
+ private:
+ DrawingBuffer* m_drawingBuffer;
+ WebGLFramebuffer* m_framebufferBinding;
+ };
+
+ Platform3DObject objectOrZero(WebGLObject* object)
+ {
+ return object ? object->object() : 0;
+ }
+
+ void clip1D(GC3Dint start, GC3Dsizei range, GC3Dsizei sourceRange, GC3Dint* clippedStart, GC3Dsizei* clippedRange)
+ {
+ ASSERT(clippedStart && clippedRange);
+ if (start < 0) {
+ range += start;
+ start = 0;
+ }
+ GC3Dint end = start + range;
+ if (end > sourceRange)
+ range -= end - sourceRange;
+ *clippedStart = start;
+ *clippedRange = range;
+ }
+
+ // Returns false if no clipping is necessary, i.e., x, y, width, height stay the same.
+ bool clip2D(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height,
+ GC3Dsizei sourceWidth, GC3Dsizei sourceHeight,
+ GC3Dint* clippedX, GC3Dint* clippedY, GC3Dsizei* clippedWidth, GC3Dsizei*clippedHeight)
+ {
+ ASSERT(clippedX && clippedY && clippedWidth && clippedHeight);
+ clip1D(x, width, sourceWidth, clippedX, clippedWidth);
+ clip1D(y, height, sourceHeight, clippedY, clippedHeight);
+ return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height);
+ }
+
+ GC3Dint clamp(GC3Dint value, GC3Dint min, GC3Dint max)
+ {
+ if (value < min)
+ value = min;
+ if (value > max)
+ value = max;
+ return value;
+ }
+
+ // Return true if a character belongs to the ASCII subset as defined in
+ // GLSL ES 1.0 spec section 3.1.
+ bool validateCharacter(unsigned char c)
+ {
+ // Printing characters are valid except " $ ` @ \ ' DEL.
+ if (c >= 32 && c <= 126
+ && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
+ return true;
+ // Horizontal tab, line feed, vertical tab, form feed, carriage return
+ // are also valid.
+ if (c >= 9 && c <= 13)
+ return true;
+ return false;
+ }
+
+ bool isPrefixReserved(const String& name)
+ {
+ if (name.startsWith("gl_") || name.startsWith("webgl_") || name.startsWith("_webgl_"))
+ return true;
+ return false;
+ }
+
+ // Strips comments from shader text. This allows non-ASCII characters
+ // to be used in comments without potentially breaking OpenGL
+ // implementations not expecting characters outside the GLSL ES set.
+ class StripComments {
+ public:
+ StripComments(const String& str)
+ : m_parseState(BeginningOfLine)
+ , m_sourceString(str)
+ , m_length(str.length())
+ , m_position(0)
+ {
+ parse();
+ }
+
+ String result()
+ {
+ return m_builder.toString();
+ }
+
+ private:
+ bool hasMoreCharacters() const
+ {
+ return (m_position < m_length);
+ }
+
+ void parse()
+ {
+ while (hasMoreCharacters()) {
+ process(current());
+ // process() might advance the position.
+ if (hasMoreCharacters())
+ advance();
+ }
+ }
+
+ void process(UChar);
+
+ bool peek(UChar& character) const
+ {
+ if (m_position + 1 >= m_length)
+ return false;
+ character = m_sourceString[m_position + 1];
+ return true;
+ }
+
+ UChar current() const
+ {
+ ASSERT_WITH_SECURITY_IMPLICATION(m_position < m_length);
+ return m_sourceString[m_position];
+ }
+
+ void advance()
+ {
+ ++m_position;
+ }
+
+ bool isNewline(UChar character) const
+ {
+ // Don't attempt to canonicalize newline related characters.
+ return (character == '\n' || character == '\r');
+ }
+
+ void emit(UChar character)
+ {
+ m_builder.append(character);
+ }
+
+ enum ParseState {
+ // Have not seen an ASCII non-whitespace character yet on
+ // this line. Possible that we might see a preprocessor
+ // directive.
+ BeginningOfLine,
+
+ // Have seen at least one ASCII non-whitespace character
+ // on this line.
+ MiddleOfLine,
+
+ // Handling a preprocessor directive. Passes through all
+ // characters up to the end of the line. Disables comment
+ // processing.
+ InPreprocessorDirective,
+
+ // Handling a single-line comment. The comment text is
+ // replaced with a single space.
+ InSingleLineComment,
+
+ // Handling a multi-line comment. Newlines are passed
+ // through to preserve line numbers.
+ InMultiLineComment
+ };
+
+ ParseState m_parseState;
+ String m_sourceString;
+ unsigned m_length;
+ unsigned m_position;
+ StringBuilder m_builder;
+ };
+
+ void StripComments::process(UChar c)
+ {
+ if (isNewline(c)) {
+ // No matter what state we are in, pass through newlines
+ // so we preserve line numbers.
+ emit(c);
+
+ if (m_parseState != InMultiLineComment)
+ m_parseState = BeginningOfLine;
+
+ return;
+ }
+
+ UChar temp = 0;
+ switch (m_parseState) {
+ case BeginningOfLine:
+ if (WTF::isASCIISpace(c)) {
+ emit(c);
+ break;
+ }
+
+ if (c == '#') {
+ m_parseState = InPreprocessorDirective;
+ emit(c);
+ break;
+ }
+
+ // Transition to normal state and re-handle character.
+ m_parseState = MiddleOfLine;
+ process(c);
+ break;
+
+ case MiddleOfLine:
+ if (c == '/' && peek(temp)) {
+ if (temp == '/') {
+ m_parseState = InSingleLineComment;
+ emit(' ');
+ advance();
+ break;
+ }
+
+ if (temp == '*') {
+ m_parseState = InMultiLineComment;
+ // Emit the comment start in case the user has
+ // an unclosed comment and we want to later
+ // signal an error.
+ emit('/');
+ emit('*');
+ advance();
+ break;
+ }
+ }
+
+ emit(c);
+ break;
+
+ case InPreprocessorDirective:
+ // No matter what the character is, just pass it
+ // through. Do not parse comments in this state. This
+ // might not be the right thing to do long term, but it
+ // should handle the #error preprocessor directive.
+ emit(c);
+ break;
+
+ case InSingleLineComment:
+ // The newline code at the top of this function takes care
+ // of resetting our state when we get out of the
+ // single-line comment. Swallow all other characters.
+ break;
+
+ case InMultiLineComment:
+ if (c == '*' && peek(temp) && temp == '/') {
+ emit('*');
+ emit('/');
+ m_parseState = MiddleOfLine;
+ advance();
+ break;
+ }
+
+ // Swallow all other characters. Unclear whether we may
+ // want or need to just emit a space per character to try
+ // to preserve column numbers for debugging purposes.
+ break;
+ }
+ }
+} // namespace anonymous
+
+class WebGLStateRestorer {
+public:
+ WebGLStateRestorer(WebGLRenderingContext* context,
+ bool changed)
+ : m_context(context)
+ , m_changed(changed)
+ {
+ }
+
+ ~WebGLStateRestorer()
+ {
+ m_context->cleanupAfterGraphicsCall(m_changed);
+ }
+
+private:
+ WebGLRenderingContext* m_context;
+ bool m_changed;
+};
+
+class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostCallback {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_context(cb) { }
+ virtual void onContextLost() override { m_context->forceLostContext(WebGLRenderingContext::RealLostContext); }
+ virtual ~WebGLRenderingContextLostCallback() {}
+private:
+ WebGLRenderingContext* m_context;
+};
+
+class WebGLRenderingContextErrorMessageCallback : public GraphicsContext3D::ErrorMessageCallback {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit WebGLRenderingContextErrorMessageCallback(WebGLRenderingContext* cb) : m_context(cb) { }
+ virtual void onErrorMessage(const String& message, GC3Dint) override
+ {
+ if (m_context->m_synthesizedErrorsToConsole)
+ m_context->printGLErrorToConsole(message);
+ }
+ virtual ~WebGLRenderingContextErrorMessageCallback() { }
+private:
+ WebGLRenderingContext* m_context;
+};
+
+OwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
{
+ Document& document = canvas->document();
+ Frame* frame = document.frame();
+ if (!frame)
+ return nullptr;
+
+ // The FrameLoaderClient might creation of a new WebGL context despite the page settings; in
+ // particular, if WebGL contexts were lost one or more times via the GL_ARB_robustness extension.
+ if (!frame->loader().client().allowWebGL(frame->settings().webGLEnabled())) {
+ canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Web page was not allowed to create a WebGL context."));
+ return nullptr;
+ }
+
+ HostWindow* hostWindow = document.view()->root()->hostWindow();
+ GraphicsContext3D::Attributes attributes = attrs ? attrs->attributes() : GraphicsContext3D::Attributes();
+
+ if (attributes.antialias) {
+ if (!frame->settings().openGLMultisamplingEnabled())
+ attributes.antialias = false;
+ }
+
+ attributes.noExtensions = true;
+ attributes.shareResources = false;
+ attributes.preferDiscreteGPU = true;
+
+ if (frame->settings().multithreadedWebGLEnabled())
+ attributes.multithreaded = true;
+
+ if (frame->settings().forceSoftwareWebGLRendering())
+ attributes.forceSoftwareRenderer = true;
+
+ RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes, hostWindow));
+
+ if (!context || !context->makeContextCurrent()) {
+ canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Could not create a WebGL context."));
+ return nullptr;
+ }
+
+ Extensions3D* extensions = context->getExtensions();
+ if (extensions->supports("GL_EXT_debug_marker"))
+ extensions->pushGroupMarkerEXT("WebGLRenderingContext");
+
+ OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRenderingContext(canvas, context, attributes));
+ renderingContext->suspendIfNeeded();
+
+ return renderingContext.release();
}
WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context,
- GraphicsContext3D::Attributes attributes) : WebGLRenderingContextBase(passedCanvas, context, attributes)
+ GraphicsContext3D::Attributes attributes)
+ : CanvasRenderingContext(passedCanvas)
+ , ActiveDOMObject(&passedCanvas->document())
+ , m_context(context)
+ , m_drawingBuffer(0)
+ , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchContextLostEvent)
+ , m_restoreAllowed(false)
+ , m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext)
+ , m_generatedImageCache(4)
+ , m_contextLost(false)
+ , m_contextLostMode(SyntheticLostContext)
+ , m_attributes(attributes)
+ , m_synthesizedErrorsToConsole(true)
+ , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
{
- initializeVertexArrayObjects();
+ ASSERT(m_context);
+ m_contextGroup = WebGLContextGroup::create();
+ m_contextGroup->addContext(this);
+
+ m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDims);
+
+ if (m_drawingBuffer)
+ m_drawingBuffer->bind();
+
+ setupFlags();
+ initializeNewContext();
}
-void WebGLRenderingContext::initializeVertexArrayObjects()
+void WebGLRenderingContext::initializeNewContext()
{
- m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VAOTypeDefault);
+ ASSERT(!m_contextLost);
+ m_needsUpdate = true;
+ m_markedCanvasDirty = false;
+ m_activeTextureUnit = 0;
+ m_packAlignment = 4;
+ m_unpackAlignment = 4;
+ m_unpackFlipY = false;
+ m_unpackPremultiplyAlpha = false;
+ m_unpackColorspaceConversion = GraphicsContext3D::BROWSER_DEFAULT_WEBGL;
+ m_boundArrayBuffer = 0;
+ m_currentProgram = 0;
+ m_framebufferBinding = 0;
+ m_renderbufferBinding = 0;
+ m_depthMask = true;
+ m_stencilEnabled = false;
+ m_stencilMask = 0xFFFFFFFF;
+ m_stencilMaskBack = 0xFFFFFFFF;
+ m_stencilFuncRef = 0;
+ m_stencilFuncRefBack = 0;
+ m_stencilFuncMask = 0xFFFFFFFF;
+ m_stencilFuncMaskBack = 0xFFFFFFFF;
+ m_layerCleared = false;
+ m_numGLErrorsToConsoleAllowed = maxGLErrorsAllowedToConsole;
+
+ m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0;
+ m_scissorEnabled = false;
+ m_clearDepth = 1;
+ m_clearStencil = 0;
+ m_colorMask[0] = m_colorMask[1] = m_colorMask[2] = m_colorMask[3] = true;
+
+ GC3Dint numCombinedTextureImageUnits = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
+ m_textureUnits.clear();
+ m_textureUnits.resize(numCombinedTextureImageUnits);
+
+ GC3Dint numVertexAttribs = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &numVertexAttribs);
+ m_maxVertexAttribs = numVertexAttribs;
+
+ m_maxTextureSize = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize);
+ m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
+ m_maxCubeMapTextureSize = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
+ m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
+ m_maxRenderbufferSize = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_RENDERBUFFER_SIZE, &m_maxRenderbufferSize);
+
+ // These two values from EXT_draw_buffers are lazily queried.
+ m_maxDrawBuffers = 0;
+ m_maxColorAttachments = 0;
+
+ m_backDrawBuffer = GraphicsContext3D::BACK;
+ m_drawBuffersWebGLRequirementsChecked = false;
+ m_drawBuffersSupported = false;
+
+ m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VaoTypeDefault);
addContextObject(m_defaultVertexArrayObject.get());
m_boundVertexArrayObject = m_defaultVertexArrayObject;
+
+ m_vertexAttribValue.resize(m_maxVertexAttribs);
+
+ if (!isGLES2NPOTStrict())
+ createFallbackBlackTextures1x1();
if (!isGLES2Compliant())
initVertexAttrib0();
+
+ IntSize canvasSize = clampedCanvasSize();
+ if (m_drawingBuffer)
+ m_drawingBuffer->reset(canvasSize);
+
+ m_context->reshape(canvasSize.width(), canvasSize.height());
+ m_context->viewport(0, 0, canvasSize.width(), canvasSize.height());
+ m_context->scissor(0, 0, canvasSize.width(), canvasSize.height());
+
+ m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCallback(this)));
+ m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMessageCallback(this)));
}
-WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
+void WebGLRenderingContext::setupFlags()
{
- if (isContextLostOrPending())
- return nullptr;
+ ASSERT(m_context);
+
+ if (Page* page = canvas()->document().page())
+ m_synthesizedErrorsToConsole = page->settings().webGLErrorsToConsoleEnabled();
+
+ m_isGLES2Compliant = m_context->isGLES2Compliant();
+ m_isErrorGeneratedOnOutOfBoundsAccesses = m_context->getExtensions()->isEnabled("GL_CHROMIUM_strict_attribs");
+ m_isResourceSafe = m_context->getExtensions()->isEnabled("GL_CHROMIUM_resource_safe");
+ if (m_isGLES2Compliant) {
+ m_isGLES2NPOTStrict = !m_context->getExtensions()->isEnabled("GL_OES_texture_npot");
+ m_isDepthStencilSupported = m_context->getExtensions()->isEnabled("GL_OES_packed_depth_stencil");
+ } else {
+ m_isGLES2NPOTStrict = !m_context->getExtensions()->isEnabled("GL_ARB_texture_non_power_of_two");
+ m_isDepthStencilSupported = m_context->getExtensions()->isEnabled("GL_EXT_packed_depth_stencil");
+ }
+ m_isRobustnessEXTSupported = m_context->getExtensions()->isEnabled("GL_EXT_robustness");
+}
+
+bool WebGLRenderingContext::allowPrivilegedExtensions() const
+{
+ if (Page* page = canvas()->document().page())
+ return page->settings().privilegedWebGLExtensionsEnabled();
+ return false;
+}
+
+void WebGLRenderingContext::addCompressedTextureFormat(GC3Denum format)
+{
+ if (!m_compressedTextureFormats.contains(format))
+ m_compressedTextureFormats.append(format);
+}
+
+WebGLRenderingContext::~WebGLRenderingContext()
+{
+ // Remove all references to WebGLObjects so if they are the last reference
+ // they will be freed before the last context is removed from the context group.
+ m_boundArrayBuffer = nullptr;
+ m_defaultVertexArrayObject = nullptr;
+ m_boundVertexArrayObject = nullptr;
+ m_vertexAttrib0Buffer = nullptr;
+ m_currentProgram = nullptr;
+ m_framebufferBinding = nullptr;
+ m_renderbufferBinding = nullptr;
+
+ for (size_t i = 0; i < m_textureUnits.size(); ++i) {
+ m_textureUnits[i].texture2DBinding = nullptr;
+ m_textureUnits[i].textureCubeMapBinding = nullptr;
+ }
+
+ m_blackTexture2D = nullptr;
+ m_blackTextureCubeMap = nullptr;
+
+ detachAndRemoveAllObjects();
+ destroyGraphicsContext3D();
+ m_contextGroup->removeContext(this);
+}
+
+void WebGLRenderingContext::destroyGraphicsContext3D()
+{
+ // The drawing buffer holds a context reference. It must also be destroyed
+ // in order for the context to be released.
+ if (m_drawingBuffer)
+ m_drawingBuffer.clear();
+
+ if (m_context) {
+ m_context->setContextLostCallback(nullptr);
+ m_context->setErrorMessageCallback(nullptr);
+ m_context.clear();
+ }
+}
+
+void WebGLRenderingContext::markContextChanged()
+{
+ if (m_framebufferBinding)
+ return;
+
+ m_context->markContextChanged();
+
+ if (m_drawingBuffer)
+ m_drawingBuffer->markContentsChanged();
+
+ m_layerCleared = false;
+#if USE(ACCELERATED_COMPOSITING)
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasAcceleratedCompositing()) {
+ m_markedCanvasDirty = true;
+ canvas()->clearCopiedImage();
+ renderBox->contentChanged(CanvasChanged);
+ } else {
+#endif
+ if (!m_markedCanvasDirty) {
+ m_markedCanvasDirty = true;
+ canvas()->didDraw(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
+ }
+#if USE(ACCELERATED_COMPOSITING)
+ }
+#endif
+}
+
+bool WebGLRenderingContext::clearIfComposited(GC3Dbitfield mask)
+{
+ if (isContextLost())
+ return false;
+
+ if (!m_context->layerComposited() || m_layerCleared
+ || m_attributes.preserveDrawingBuffer || (mask && m_framebufferBinding))
+ return false;
+
+ RefPtr<WebGLContextAttributes> contextAttributes = getContextAttributes();
+
+ // Determine if it's possible to combine the clear the user asked for and this clear.
+ bool combinedClear = mask && !m_scissorEnabled;
+
+ m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+ if (combinedClear && (mask & GraphicsContext3D::COLOR_BUFFER_BIT))
+ m_context->clearColor(m_colorMask[0] ? m_clearColor[0] : 0,
+ m_colorMask[1] ? m_clearColor[1] : 0,
+ m_colorMask[2] ? m_clearColor[2] : 0,
+ m_colorMask[3] ? m_clearColor[3] : 0);
+ else
+ m_context->clearColor(0, 0, 0, 0);
+ m_context->colorMask(true, true, true, true);
+ GC3Dbitfield clearMask = GraphicsContext3D::COLOR_BUFFER_BIT;
+ if (contextAttributes->depth()) {
+ if (!combinedClear || !m_depthMask || !(mask & GraphicsContext3D::DEPTH_BUFFER_BIT))
+ m_context->clearDepth(1.0f);
+ clearMask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
+ m_context->depthMask(true);
+ }
+ if (contextAttributes->stencil()) {
+ if (combinedClear && (mask & GraphicsContext3D::STENCIL_BUFFER_BIT))
+ m_context->clearStencil(m_clearStencil & m_stencilMask);
+ else
+ m_context->clearStencil(0);
+ clearMask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
+ m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, 0xFFFFFFFF);
+ }
+ if (m_drawingBuffer)
+ m_drawingBuffer->clearFramebuffers(clearMask);
+ else {
+ if (m_framebufferBinding)
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
+ m_context->clear(clearMask);
+ }
+
+ restoreStateAfterClear();
+ if (m_framebufferBinding)
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+ m_layerCleared = true;
+
+ return combinedClear;
+}
+
+void WebGLRenderingContext::restoreStateAfterClear()
+{
+ // Restore the state that the context set.
+ if (m_scissorEnabled)
+ m_context->enable(GraphicsContext3D::SCISSOR_TEST);
+ m_context->clearColor(m_clearColor[0], m_clearColor[1],
+ m_clearColor[2], m_clearColor[3]);
+ m_context->colorMask(m_colorMask[0], m_colorMask[1],
+ m_colorMask[2], m_colorMask[3]);
+ m_context->clearDepth(m_clearDepth);
+ m_context->clearStencil(m_clearStencil);
+ m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, m_stencilMask);
+ m_context->depthMask(m_depthMask);
+}
+
+void WebGLRenderingContext::markLayerComposited()
+{
+ m_context->markLayerComposited();
+}
+
+void WebGLRenderingContext::paintRenderingResultsToCanvas()
+{
+ if (canvas()->document().printing())
+ canvas()->clearPresentationCopy();
+
+ // Until the canvas is written to by the application, the clear that
+ // happened after it was composited should be ignored by the compositor.
+ if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer) {
+ m_context->paintCompositedResultsToCanvas(canvas()->buffer());
+
+ canvas()->makePresentationCopy();
+ } else
+ canvas()->clearPresentationCopy();
+ clearIfComposited();
+
+ if (!m_markedCanvasDirty && !m_layerCleared)
+ return;
+
+ canvas()->clearCopiedImage();
+ m_markedCanvasDirty = false;
+
+ if (m_drawingBuffer)
+ m_drawingBuffer->commit();
+ m_context->paintRenderingResultsToCanvas(canvas()->buffer(), m_drawingBuffer.get());
+
+ if (m_drawingBuffer) {
+ if (m_framebufferBinding)
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+ else
+ m_drawingBuffer->bind();
+ }
+}
+
+PassRefPtr<ImageData> WebGLRenderingContext::paintRenderingResultsToImageData()
+{
+ clearIfComposited();
+ if (m_drawingBuffer)
+ m_drawingBuffer->commit();
+ RefPtr<ImageData> imageData = m_context->paintRenderingResultsToImageData(m_drawingBuffer.get());
+
+ if (m_drawingBuffer) {
+ if (m_framebufferBinding)
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+ else
+ m_drawingBuffer->bind();
+ }
+
+ return imageData;
+}
+
+void WebGLRenderingContext::reshape(int width, int height)
+{
+ // This is an approximation because at WebGLRenderingContext level we don't
+ // know if the underlying FBO uses textures or renderbuffers.
+ GC3Dint maxSize = std::min(m_maxTextureSize, m_maxRenderbufferSize);
+ // Limit drawing buffer size to 4k to avoid memory exhaustion.
+ const int sizeUpperLimit = 4096;
+ maxSize = std::min(maxSize, sizeUpperLimit);
+ GC3Dint maxWidth = std::min(maxSize, m_maxViewportDims[0]);
+ GC3Dint maxHeight = std::min(maxSize, m_maxViewportDims[1]);
+ width = clamp(width, 1, maxWidth);
+ height = clamp(height, 1, maxHeight);
+
+ if (m_needsUpdate) {
+#if USE(ACCELERATED_COMPOSITING)
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasAcceleratedCompositing())
+ renderBox->contentChanged(CanvasChanged);
+#endif
+ m_needsUpdate = false;
+ }
+
+ // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off
+ // clear (and this matches what reshape will do).
+ if (m_drawingBuffer) {
+ m_drawingBuffer->reset(IntSize(width, height));
+ restoreStateAfterClear();
+ } else
+ m_context->reshape(width, height);
+
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(m_textureUnits[m_activeTextureUnit].texture2DBinding.get()));
+ m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, objectOrZero(m_renderbufferBinding.get()));
+ if (m_framebufferBinding)
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+}
+
+int WebGLRenderingContext::drawingBufferWidth() const
+{
+ if (m_drawingBuffer)
+ return m_drawingBuffer->size().width();
+
+ return m_context->getInternalFramebufferSize().width();
+}
+
+int WebGLRenderingContext::drawingBufferHeight() const
+{
+ if (m_drawingBuffer)
+ return m_drawingBuffer->size().height();
+
+ return m_context->getInternalFramebufferSize().height();
+}
+
+unsigned int WebGLRenderingContext::sizeInBytes(GC3Denum type)
+{
+ switch (type) {
+ case GraphicsContext3D::BYTE:
+ return sizeof(GC3Dbyte);
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ return sizeof(GC3Dubyte);
+ case GraphicsContext3D::SHORT:
+ return sizeof(GC3Dshort);
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ return sizeof(GC3Dushort);
+ case GraphicsContext3D::INT:
+ return sizeof(GC3Dint);
+ case GraphicsContext3D::UNSIGNED_INT:
+ return sizeof(GC3Duint);
+ case GraphicsContext3D::FLOAT:
+ return sizeof(GC3Dfloat);
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+void WebGLRenderingContext::activeTexture(GC3Denum texture, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "activeTexture", "texture unit out of range");
+ return;
+ }
+ m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0;
+ m_context->activeTexture(texture);
+
+ if (m_drawingBuffer)
+ m_drawingBuffer->setActiveTextureUnit(texture);
+
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
+ return;
+ if (!program->attachShader(shader)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "attachShader", "shader attachment already has shader");
+ return;
+ }
+ m_context->attachShader(objectOrZero(program), objectOrZero(shader));
+ shader->onAttached();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, GC3Duint index, const String& name, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("bindAttribLocation", program))
+ return;
+ if (!validateLocationLength("bindAttribLocation", name))
+ return;
+ if (!validateString("bindAttribLocation", name))
+ return;
+ if (isPrefixReserved(name)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindAttribLocation", "reserved prefix");
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bindAttribLocation", "index out of range");
+ return;
+ }
+ m_context->bindAttribLocation(objectOrZero(program), index, name);
+ cleanupAfterGraphicsCall(false);
+}
+
+bool WebGLRenderingContext::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted)
+{
+ deleted = false;
+ if (isContextLost())
+ return false;
+ if (object) {
+ if (!object->validate(contextGroup(), this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object not from this context");
+ return false;
+ }
+ deleted = !object->object();
+ }
+ return true;
+}
+
+void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ bool deleted;
+ if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
+ return;
+ if (deleted)
+ buffer = 0;
+ if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindBuffer", "buffers can not be used with multiple targets");
+ return;
+ }
+ if (target == GraphicsContext3D::ARRAY_BUFFER)
+ m_boundArrayBuffer = buffer;
+ else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
+ m_boundVertexArrayObject->setElementArrayBuffer(buffer);
+ else {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindBuffer", "invalid target");
+ return;
+ }
+
+ m_context->bindBuffer(target, objectOrZero(buffer));
+ if (buffer)
+ buffer->setTarget(target);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bindFramebuffer(GC3Denum target, WebGLFramebuffer* buffer, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ bool deleted;
+ if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
+ return;
+ if (deleted)
+ buffer = 0;
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindFramebuffer", "invalid target");
+ return;
+ }
+ m_framebufferBinding = buffer;
+ if (m_drawingBuffer)
+ m_drawingBuffer->setFramebufferBinding(objectOrZero(m_framebufferBinding.get()));
+ if (!m_framebufferBinding && m_drawingBuffer) {
+ // Instead of binding fb 0, bind the drawing buffer.
+ m_drawingBuffer->bind();
+ } else
+ m_context->bindFramebuffer(target, objectOrZero(buffer));
+ if (buffer)
+ buffer->setHasEverBeenBound();
+ applyStencilTest();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ bool deleted;
+ if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
+ return;
+ if (deleted)
+ renderBuffer = 0;
+ if (target != GraphicsContext3D::RENDERBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindRenderbuffer", "invalid target");
+ return;
+ }
+ m_renderbufferBinding = renderBuffer;
+ m_context->bindRenderbuffer(target, objectOrZero(renderBuffer));
+ if (renderBuffer)
+ renderBuffer->setHasEverBeenBound();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bindTexture(GC3Denum target, WebGLTexture* texture, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ bool deleted;
+ if (!checkObjectToBeBound("bindTexture", texture, deleted))
+ return;
+ if (deleted)
+ texture = 0;
+ if (texture && texture->getTarget() && texture->getTarget() != target) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
+ return;
+ }
+ GC3Dint maxLevel = 0;
+ if (target == GraphicsContext3D::TEXTURE_2D) {
+ m_textureUnits[m_activeTextureUnit].texture2DBinding = texture;
+ maxLevel = m_maxTextureLevel;
+
+ if (m_drawingBuffer && !m_activeTextureUnit)
+ m_drawingBuffer->setTexture2DBinding(objectOrZero(texture));
+
+ } else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
+ m_textureUnits[m_activeTextureUnit].textureCubeMapBinding = texture;
+ maxLevel = m_maxCubeMapTextureLevel;
+ } else {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindTexture", "invalid target");
+ return;
+ }
+ m_context->bindTexture(target, objectOrZero(texture));
+ if (texture)
+ texture->setTarget(target, maxLevel);
+
+ // Note: previously we used to automatically set the TEXTURE_WRAP_R
+ // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL
+ // ES 2.0 doesn't expose this flag (a bug in the specification) and
+ // otherwise the application has no control over the seams in this
+ // dimension. However, it appears that supporting this properly on all
+ // platforms is fairly involved (will require a HashMap from texture ID
+ // in all ports), and we have not had any complaints, so the logic has
+ // been removed.
+
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha)
+{
+ if (isContextLost())
+ return;
+ m_context->blendColor(red, green, blue, alpha);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::blendEquation(GC3Denum mode)
+{
+ if (isContextLost() || !validateBlendEquation("blendEquation", mode))
+ return;
+ m_context->blendEquation(mode);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
+{
+ if (isContextLost() || !validateBlendEquation("blendEquation", modeRGB) || !validateBlendEquation("blendEquation", modeAlpha))
+ return;
+ m_context->blendEquationSeparate(modeRGB, modeAlpha);
+ cleanupAfterGraphicsCall(false);
+}
+
+
+void WebGLRenderingContext::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
+{
+ if (isContextLost() || !validateBlendFuncFactors("blendFunc", sfactor, dfactor))
+ return;
+ m_context->blendFunc(sfactor, dfactor);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
+{
+ // Note: Alpha does not have the same restrictions as RGB.
+ if (isContextLost() || !validateBlendFuncFactors("blendFunc", srcRGB, dstRGB))
+ return;
+ m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferData(GC3Denum target, long long size, GC3Denum usage, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
+ if (!buffer)
+ return;
+ if (size < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "size < 0");
+ return;
+ }
+ if (!size) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "size == 0");
+ return;
+ }
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferData(static_cast<GC3Dsizeiptr>(size))) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
+ return;
+ }
+ }
+
+ m_context->bufferData(target, static_cast<GC3Dsizeiptr>(size), usage);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
+ if (!buffer)
+ return;
+ if (!data) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "no data");
+ return;
+ }
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferData(data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
+ return;
+ }
+ }
+
+ m_context->bufferData(target, data->byteLength(), data->data(), usage);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
+ if (!buffer)
+ return;
+ if (!data) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "no data");
+ return;
+ }
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferData(data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
+ return;
+ }
+ }
+
+ m_context->bufferData(target, data->byteLength(), data->baseAddress(), usage);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW);
+ if (!buffer)
+ return;
+ if (offset < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset < 0");
+ return;
+ }
+ if (!data)
+ return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferSubData(static_cast<GC3Dintptr>(offset), data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset out of range");
+ return;
+ }
+ }
+
+ m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW);
+ if (!buffer)
+ return;
+ if (offset < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset < 0");
+ return;
+ }
+ if (!data)
+ return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferSubData(static_cast<GC3Dintptr>(offset), data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset out of range");
+ return;
+ }
+ }
+
+ m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->baseAddress());
+ cleanupAfterGraphicsCall(false);
+}
+
+GC3Denum WebGLRenderingContext::checkFramebufferStatus(GC3Denum target)
+{
+ if (isContextLost())
+ return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "checkFramebufferStatus", "invalid target");
+ return 0;
+ }
+ if (!m_framebufferBinding || !m_framebufferBinding->object())
+ return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
+ const char* reason = "framebuffer incomplete";
+ GC3Denum result = m_framebufferBinding->checkStatus(&reason);
+ if (result != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
+ printGLWarningToConsole("checkFramebufferStatus", reason);
+ return result;
+ }
+ result = m_context->checkFramebufferStatus(target);
+ cleanupAfterGraphicsCall(false);
+ return result;
+}
+
+void WebGLRenderingContext::clear(GC3Dbitfield mask)
+{
+ if (isContextLost())
+ return;
+ if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clear", "invalid mask");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
+ return;
+ }
+ if (!clearIfComposited(mask))
+ m_context->clear(mask);
+ cleanupAfterGraphicsCall(true);
+}
+
+void WebGLRenderingContext::clearColor(GC3Dfloat r, GC3Dfloat g, GC3Dfloat b, GC3Dfloat a)
+{
+ if (isContextLost())
+ return;
+ if (std::isnan(r))
+ r = 0;
+ if (std::isnan(g))
+ g = 0;
+ if (std::isnan(b))
+ b = 0;
+ if (std::isnan(a))
+ a = 1;
+ m_clearColor[0] = r;
+ m_clearColor[1] = g;
+ m_clearColor[2] = b;
+ m_clearColor[3] = a;
+ m_context->clearColor(r, g, b, a);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::clearDepth(GC3Dfloat depth)
+{
+ if (isContextLost())
+ return;
+ m_clearDepth = depth;
+ m_context->clearDepth(depth);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::clearStencil(GC3Dint s)
+{
+ if (isContextLost())
+ return;
+ m_clearStencil = s;
+ m_context->clearStencil(s);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha)
+{
+ if (isContextLost())
+ return;
+ m_colorMask[0] = red;
+ m_colorMask[1] = green;
+ m_colorMask[2] = blue;
+ m_colorMask[3] = alpha;
+ m_context->colorMask(red, green, blue, alpha);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("compileShader", shader))
+ return;
+ m_context->compileShader(objectOrZero(shader));
+ GC3Dint value;
+ m_context->getShaderiv(objectOrZero(shader), GraphicsContext3D::COMPILE_STATUS, &value);
+ shader->setValid(value);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
+ GC3Dsizei height, GC3Dint border, ArrayBufferView* data)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncLevel("compressedTexImage2D", target, level))
+ return;
+
+ if (!validateCompressedTexFormat(internalformat)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexImage2D", "invalid internalformat");
+ return;
+ }
+ if (border) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "compressedTexImage2D", "border not 0");
+ return;
+ }
+ if (!validateCompressedTexDimensions("compressedTexImage2D", target, level, width, height, internalformat))
+ return;
+ if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
+ return;
+
+ WebGLTexture* tex = validateTextureBinding("compressedTexImage2D", target, true);
+ if (!tex)
+ return;
+ if (!isGLES2NPOTStrict()) {
+ if (level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "compressedTexImage2D", "level > 0 not power of 2");
+ return;
+ }
+ }
+ graphicsContext3D()->compressedTexImage2D(target, level, internalformat, width, height,
+ border, data->byteLength(), data->baseAddress());
+ tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ tex->setCompressed();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncLevel("compressedTexSubImage2D", target, level))
+ return;
+ if (!validateCompressedTexFormat(format)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexSubImage2D", "invalid format");
+ return;
+ }
+ if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, format, data))
+ return;
+
+ WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target, true);
+ if (!tex)
+ return;
+
+ if (format != tex->getInternalFormat(target, level)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "compressedTexSubImage2D", "format does not match texture format");
+ return;
+ }
+
+ if (!validateCompressedTexSubDimensions("compressedTexSubImage2D", target, level, xoffset, yoffset, width, height, format, tex))
+ return;
+
+ graphicsContext3D()->compressedTexSubImage2D(target, level, xoffset, yoffset,
+ width, height, format, data->byteLength(), data->baseAddress());
+ tex->setCompressed();
+ cleanupAfterGraphicsCall(false);
+}
+
+bool WebGLRenderingContext::validateSettableTexFormat(const char* functionName, GC3Denum format)
+{
+ if (GraphicsContext3D::getClearBitsByFormat(format) & (GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format can not be set, only rendered to");
+ return false;
+ }
+ return true;
+}
+
+void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncParameters("copyTexImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
+ return;
+ if (!validateSettableTexFormat("copyTexImage2D", internalformat))
+ return;
+ WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
+ if (!tex)
+ return;
+ if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
+ return;
+ }
+ if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
+ return;
+ }
+ clearIfComposited();
+ if (isResourceSafe()) {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ } else {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ GC3Dint clippedX, clippedY;
+ GC3Dsizei clippedWidth, clippedHeight;
+ if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
+ m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border,
+ internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);
+ if (clippedWidth > 0 && clippedHeight > 0) {
+ m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
+ clippedX, clippedY, clippedWidth, clippedHeight);
+ }
+ } else
+ m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ }
+ // FIXME: if the framebuffer is not complete, none of the below should be executed.
+ tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
+ return;
+ WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true);
+ if (!tex)
+ return;
+ if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height))
+ return;
+ // Before checking if it is in the range, check if overflow happens first.
+ if (xoffset + width < 0 || yoffset + height < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "bad dimensions");
+ return;
+ }
+ if (xoffset + width > tex->getWidth(target, level) || yoffset + height > tex->getHeight(target, level)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range");
+ return;
+ }
+ GC3Denum internalformat = tex->getInternalFormat(target, level);
+ if (!validateSettableTexFormat("copyTexSubImage2D", internalformat))
+ return;
+ if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
+ return;
+ }
+ clearIfComposited();
+ if (isResourceSafe()) {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+ } else {
+ GC3Dint clippedX, clippedY;
+ GC3Dsizei clippedWidth, clippedHeight;
+ if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
+ GC3Denum format = tex->getInternalFormat(target, level);
+ GC3Denum type = tex->getType(target, level);
+ std::unique_ptr<unsigned char[]> zero;
+ if (width && height) {
+ unsigned int size;
+ GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, 0);
+ if (error != GraphicsContext3D::NO_ERROR) {
+ synthesizeGLError(error, "copyTexSubImage2D", "bad dimensions");
+ return;
+ }
+ zero = std::make_unique<unsigned char[]>(size);
+ if (!zero) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "out of memory");
+ return;
+ }
+ memset(zero.get(), 0, size);
+ }
+ m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, zero.get());
+ if (clippedWidth > 0 && clippedHeight > 0) {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ m_context->copyTexSubImage2D(target, level, xoffset + clippedX - x, yoffset + clippedY - y,
+ clippedX, clippedY, clippedWidth, clippedHeight);
+ }
+ } else {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+ }
+ }
+ cleanupAfterGraphicsCall(false);
+}
+
+PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
+ addSharedObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
+ addContextObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLTexture> o = WebGLTexture::create(this);
+ addSharedObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLProgram> o = WebGLProgram::create(this);
+ addSharedObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
+ addSharedObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(GC3Denum type, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return 0;
+ if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "createShader", "invalid shader type");
+ return 0;
+ }
+
+ RefPtr<WebGLShader> o = WebGLShader::create(this, type);
+ addSharedObject(o.get());
+ return o;
+}
+
+void WebGLRenderingContext::cullFace(GC3Denum mode)
+{
+ if (isContextLost())
+ return;
+ m_context->cullFace(mode);
+ cleanupAfterGraphicsCall(false);
+}
+
+bool WebGLRenderingContext::deleteObject(WebGLObject* object)
+{
+ if (isContextLost() || !object)
+ return false;
+ if (!object->validate(contextGroup(), this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "delete", "object does not belong to this context");
+ return false;
+ }
+ if (object->object())
+ // We need to pass in context here because we want
+ // things in this context unbound.
+ object->deleteObject(graphicsContext3D());
+ return true;
+}
+
+void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
+{
+ if (!deleteObject(buffer))
+ return;
+ if (m_boundArrayBuffer == buffer)
+ m_boundArrayBuffer = 0;
+
+ m_boundVertexArrayObject->unbindBuffer(buffer);
+}
+
+void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
+{
+ if (!deleteObject(framebuffer))
+ return;
+ if (framebuffer == m_framebufferBinding) {
+ m_framebufferBinding = 0;
+ if (m_drawingBuffer) {
+ m_drawingBuffer->setFramebufferBinding(0);
+ // Have to call bindFramebuffer here to bind back to internal fbo.
+ m_drawingBuffer->bind();
+ } else
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
+ }
+}
+
+void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
+{
+ deleteObject(program);
+ // We don't reset m_currentProgram to 0 here because the deletion of the
+ // current program is delayed.
+}
+
+void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
+{
+ if (!deleteObject(renderbuffer))
+ return;
+ if (renderbuffer == m_renderbufferBinding)
+ m_renderbufferBinding = 0;
+ if (m_framebufferBinding)
+ m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer);
+}
+
+void WebGLRenderingContext::deleteShader(WebGLShader* shader)
+{
+ deleteObject(shader);
+}
+
+void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
+{
+ if (!deleteObject(texture))
+ return;
+ for (size_t i = 0; i < m_textureUnits.size(); ++i) {
+ if (texture == m_textureUnits[i].texture2DBinding)
+ m_textureUnits[i].texture2DBinding = nullptr;
+ if (texture == m_textureUnits[i].textureCubeMapBinding)
+ m_textureUnits[i].textureCubeMapBinding = nullptr;
+ }
+ if (m_framebufferBinding)
+ m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
+}
+
+void WebGLRenderingContext::depthFunc(GC3Denum func)
+{
+ if (isContextLost())
+ return;
+ m_context->depthFunc(func);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::depthMask(GC3Dboolean flag)
+{
+ if (isContextLost())
+ return;
+ m_depthMask = flag;
+ m_context->depthMask(flag);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::depthRange(GC3Dfloat zNear, GC3Dfloat zFar)
+{
+ if (isContextLost())
+ return;
+ if (zNear > zFar) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "depthRange", "zNear > zFar");
+ return;
+ }
+ m_context->depthRange(zNear, zFar);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
+ return;
+ if (!program->detachShader(shader)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "detachShader", "shader not attached");
+ return;
+ }
+ m_context->detachShader(objectOrZero(program), objectOrZero(shader));
+ shader->onDetached(graphicsContext3D());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::disable(GC3Denum cap)
+{
+ if (isContextLost() || !validateCapability("disable", cap))
+ return;
+ if (cap == GraphicsContext3D::STENCIL_TEST) {
+ m_stencilEnabled = false;
+ applyStencilTest();
+ cleanupAfterGraphicsCall(false);
+ return;
+ }
+ if (cap == GraphicsContext3D::SCISSOR_TEST) {
+ m_scissorEnabled = false;
+ if (m_drawingBuffer)
+ m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
+ }
+ m_context->disable(cap);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::disableVertexAttribArray(GC3Duint index, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "disableVertexAttribArray", "index out of range");
+ return;
+ }
+
+ WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+ state.enabled = false;
+
+ if (index > 0 || isGLES2Compliant()) {
+ m_context->disableVertexAttribArray(index);
+ cleanupAfterGraphicsCall(false);
+ }
+}
+
+bool WebGLRenderingContext::validateElementArraySize(GC3Dsizei count, GC3Denum type, GC3Dintptr offset)
+{
+ RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
- if (equalIgnoringCase(name, "EXT_blend_minmax")
- && m_context->getExtensions()->supports("GL_EXT_blend_minmax")) {
- if (!m_extBlendMinMax) {
- m_context->getExtensions()->ensureEnabled("GL_EXT_blend_minmax");
- m_extBlendMinMax = std::make_unique<EXTBlendMinMax>(this);
+ if (!elementArrayBuffer)
+ return false;
+
+ if (offset < 0)
+ return false;
+
+ if (type == GraphicsContext3D::UNSIGNED_INT) {
+ // For an unsigned int array, offset must be divisible by 4 for alignment reasons.
+ if (offset % 4)
+ return false;
+
+ // Make uoffset an element offset.
+ offset /= 4;
+
+ GC3Dsizeiptr n = elementArrayBuffer->byteLength() / 4;
+ if (offset > n || count > n - offset)
+ return false;
+ } else if (type == GraphicsContext3D::UNSIGNED_SHORT) {
+ // For an unsigned short array, offset must be divisible by 2 for alignment reasons.
+ if (offset % 2)
+ return false;
+
+ // Make uoffset an element offset.
+ offset /= 2;
+
+ GC3Dsizeiptr n = elementArrayBuffer->byteLength() / 2;
+ if (offset > n || count > n - offset)
+ return false;
+ } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
+ GC3Dsizeiptr n = elementArrayBuffer->byteLength();
+ if (offset > n || count > n - offset)
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired)
+{
+ // Performs conservative validation by caching a maximum index of
+ // the given type per element array buffer. If all of the bound
+ // array buffers have enough elements to satisfy that maximum
+ // index, skips the expensive per-draw-call iteration in
+ // validateIndexArrayPrecise.
+
+ RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
+
+ if (!elementArrayBuffer)
+ return false;
+
+ GC3Dsizeiptr numElements = elementArrayBuffer->byteLength();
+ // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
+ if (!numElements)
+ return false;
+ const ArrayBuffer* buffer = elementArrayBuffer->elementArrayBuffer();
+ ASSERT(buffer);
+
+ int maxIndex = elementArrayBuffer->getCachedMaxIndex(type);
+ if (maxIndex < 0) {
+ // Compute the maximum index in the entire buffer for the given type of index.
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE: {
+ const GC3Dubyte* p = static_cast<const GC3Dubyte*>(buffer->data());
+ for (GC3Dsizeiptr i = 0; i < numElements; i++)
+ maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
+ break;
}
- return m_extBlendMinMax.get();
+ case GraphicsContext3D::UNSIGNED_SHORT: {
+ numElements /= sizeof(GC3Dushort);
+ const GC3Dushort* p = static_cast<const GC3Dushort*>(buffer->data());
+ for (GC3Dsizeiptr i = 0; i < numElements; i++)
+ maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
+ break;
+ }
+ case GraphicsContext3D::UNSIGNED_INT: {
+ if (!m_oesElementIndexUint)
+ return false;
+ numElements /= sizeof(GC3Duint);
+ const GC3Duint* p = static_cast<const GC3Duint*>(buffer->data());
+ for (GC3Dsizeiptr i = 0; i < numElements; i++)
+ maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
+ break;
+ }
+ default:
+ return false;
+ }
+ elementArrayBuffer->setCachedMaxIndex(type, maxIndex);
+ }
+
+ if (maxIndex >= 0) {
+ // The number of required elements is one more than the maximum
+ // index that will be accessed.
+ numElementsRequired = maxIndex + 1;
+ return true;
+ }
+
+ return false;
+}
+
+bool WebGLRenderingContext::validateIndexArrayPrecise(GC3Dsizei count, GC3Denum type, GC3Dintptr offset, unsigned& numElementsRequired)
+{
+ ASSERT(count >= 0 && offset >= 0);
+ unsigned lastIndex = 0;
+
+ RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
+
+ if (!elementArrayBuffer)
+ return false;
+
+ if (!count) {
+ numElementsRequired = 0;
+ return true;
}
- if (equalIgnoringCase(name, "EXT_sRGB")
- && m_context->getExtensions()->supports("GL_EXT_sRGB")) {
- if (!m_extsRGB) {
- m_context->getExtensions()->ensureEnabled("GL_EXT_sRGB");
- m_extsRGB = std::make_unique<EXTsRGB>(this);
+
+ if (!elementArrayBuffer->elementArrayBuffer())
+ return false;
+
+ unsigned long uoffset = offset;
+ unsigned long n = count;
+
+ if (type == GraphicsContext3D::UNSIGNED_INT) {
+ // Make uoffset an element offset.
+ uoffset /= sizeof(GC3Duint);
+ const GC3Duint* p = static_cast<const GC3Duint*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
+ while (n-- > 0) {
+ if (*p > lastIndex)
+ lastIndex = *p;
+ ++p;
+ }
+ } else if (type == GraphicsContext3D::UNSIGNED_SHORT) {
+ // Make uoffset an element offset.
+ uoffset /= sizeof(GC3Dushort);
+ const GC3Dushort* p = static_cast<const GC3Dushort*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
+ while (n-- > 0) {
+ if (*p > lastIndex)
+ lastIndex = *p;
+ ++p;
+ }
+ } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
+ const GC3Dubyte* p = static_cast<const GC3Dubyte*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
+ while (n-- > 0) {
+ if (*p > lastIndex)
+ lastIndex = *p;
+ ++p;
}
- return m_extsRGB.get();
}
- if (equalIgnoringCase(name, "EXT_frag_depth")
- && m_context->getExtensions()->supports("GL_EXT_frag_depth")) {
- if (!m_extFragDepth) {
- m_context->getExtensions()->ensureEnabled("GL_EXT_frag_depth");
- m_extFragDepth = std::make_unique<EXTFragDepth>(this);
+
+ // Then set the last index in the index array and make sure it is valid.
+ numElementsRequired = lastIndex + 1;
+ return numElementsRequired > 0;
+}
+
+bool WebGLRenderingContext::validateVertexAttributes(unsigned elementCount, unsigned primitiveCount)
+{
+ if (!m_currentProgram)
+ return false;
+
+ // Look in each enabled vertex attrib and check if they've been bound to a buffer.
+ for (unsigned i = 0; i < m_maxVertexAttribs; ++i) {
+ if (!m_boundVertexArrayObject->getVertexAttribState(i).validateBinding())
+ return false;
+ }
+
+ if (elementCount <= 0)
+ return true;
+
+
+ // Look in each consumed vertex attrib (by the current program).
+ bool sawNonInstancedAttrib = false;
+ bool sawEnabledAttrib = false;
+ int numActiveAttribLocations = m_currentProgram->numActiveAttribLocations();
+ for (int i = 0; i < numActiveAttribLocations; ++i) {
+ int loc = m_currentProgram->getActiveAttribLocation(i);
+ if (loc >= 0 && loc < static_cast<int>(m_maxVertexAttribs)) {
+ const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(loc);
+ if (state.enabled) {
+ sawEnabledAttrib = true;
+ // Avoid off-by-one errors in numElements computation.
+ // For the last element, we will only touch the data for the
+ // element and nothing beyond it.
+ int bytesRemaining = static_cast<int>(state.bufferBinding->byteLength() - state.offset);
+ unsigned numElements = 0;
+ ASSERT(state.stride > 0);
+ if (bytesRemaining >= state.bytesPerElement)
+ numElements = 1 + (bytesRemaining - state.bytesPerElement) / state.stride;
+ if (!state.divisor)
+ sawNonInstancedAttrib = true;
+ if ((!state.divisor && elementCount > numElements) || (state.divisor && primitiveCount > numElements))
+ return false;
+ }
}
- return m_extFragDepth.get();
}
- if (equalIgnoringCase(name, "EXT_shader_texture_lod")
- && (m_context->getExtensions()->supports("GL_EXT_shader_texture_lod") || m_context->getExtensions()->supports("GL_ARB_shader_texture_lod"))) {
- if (!m_extShaderTextureLOD) {
- m_context->getExtensions()->ensureEnabled("GL_EXT_shader_texture_lod");
- m_extShaderTextureLOD = std::make_unique<EXTShaderTextureLOD>(this);
+
+ if (!sawNonInstancedAttrib && sawEnabledAttrib)
+ return false;
+
+ return true;
+}
+
+bool WebGLRenderingContext::validateWebGLObject(const char* functionName, WebGLObject* object)
+{
+ if (!object || !object->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no object or object deleted");
+ return false;
+ }
+ if (!object->validate(contextGroup(), this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object does not belong to this context");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
+{
+ if (isContextLost() || !validateDrawMode(functionName, mode))
+ return false;
+
+ if (!validateStencilSettings(functionName))
+ return false;
+
+ if (first < 0 || count < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "first or count < 0");
+ return false;
+ }
+
+ if (!count) {
+ cleanupAfterGraphicsCall(true);
+ return false;
+ }
+
+ if (primcount < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "primcount < 0");
+ return false;
+ }
+
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ // Ensure we have a valid rendering state
+ Checked<GC3Dint, RecordOverflow> checkedFirst(first);
+ Checked<GC3Dint, RecordOverflow> checkedCount(count);
+ Checked<GC3Dint, RecordOverflow> checkedSum = checkedFirst + checkedCount;
+ Checked<GC3Dint, RecordOverflow> checkedPrimCount(primcount);
+ if (checkedSum.hasOverflowed() || checkedPrimCount.hasOverflowed() || !validateVertexAttributes(checkedSum.unsafeGet(), checkedPrimCount.unsafeGet())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access out of bounds arrays");
+ return false;
+ }
+ } else {
+ if (!validateVertexAttributes(0)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attribs not setup correctly");
+ return false;
}
- return m_extShaderTextureLOD.get();
}
+
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
+ return false;
+ }
+
+ return true;
+}
+
+void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+
+ if (!validateDrawArrays("drawArrays", mode, first, count, 0))
+ return;
+
+ clearIfComposited();
+
+ bool vertexAttrib0Simulated = false;
+ if (!isGLES2Compliant())
+ vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
+ if (!isGLES2NPOTStrict())
+ checkTextureCompleteness("drawArrays", true);
+ m_context->drawArrays(mode, first, count);
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (!isGLES2NPOTStrict())
+ checkTextureCompleteness("drawArrays", false);
+ cleanupAfterGraphicsCall(true);
+}
+
+bool WebGLRenderingContext::validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned& numElements)
+{
+ if (isContextLost() || !validateDrawMode(functionName, mode))
+ return false;
+
+ if (!validateStencilSettings(functionName))
+ return false;
+
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ break;
+ case GraphicsContext3D::UNSIGNED_INT:
+ if (m_oesElementIndexUint)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid type");
+ return false;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid type");
+ return false;
+ }
+
+ if (count < 0 || offset < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "count or offset < 0");
+ return false;
+ }
+
+ if (!count) {
+ cleanupAfterGraphicsCall(true);
+ return false;
+ }
+
+ if (!m_boundVertexArrayObject->getElementArrayBuffer()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no ELEMENT_ARRAY_BUFFER bound");
+ return false;
+ }
+
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ // Ensure we have a valid rendering state
+ if (!validateElementArraySize(count, type, static_cast<GC3Dintptr>(offset))) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "request out of bounds for current ELEMENT_ARRAY_BUFFER");
+ return false;
+ }
+ if (!count)
+ return false;
+ if (!validateIndexArrayConservative(type, numElements) || !validateVertexAttributes(numElements)) {
+ if (!validateIndexArrayPrecise(count, type, static_cast<GC3Dintptr>(offset), numElements) || !validateVertexAttributes(numElements)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access out of bounds arrays");
+ return false;
+ }
+ }
+ } else {
+ if (!validateVertexAttributes(0)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attribs not setup correctly");
+ return false;
+ }
+ }
+
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
+ return false;
+ }
+
+ return true;
+}
+
+void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+
+ unsigned numElements = 0;
+ if (!validateDrawElements("drawElements", mode, count, type, offset, numElements))
+ return;
+
+ clearIfComposited();
+
+ bool vertexAttrib0Simulated = false;
+ if (!isGLES2Compliant()) {
+ if (!numElements)
+ validateIndexArrayPrecise(count, type, static_cast<GC3Dintptr>(offset), numElements);
+ vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
+ }
+ if (!isGLES2NPOTStrict())
+ checkTextureCompleteness("drawElements", true);
+ m_context->drawElements(mode, count, type, static_cast<GC3Dintptr>(offset));
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (!isGLES2NPOTStrict())
+ checkTextureCompleteness("drawElements", false);
+ cleanupAfterGraphicsCall(true);
+}
+
+void WebGLRenderingContext::enable(GC3Denum cap)
+{
+ if (isContextLost() || !validateCapability("enable", cap))
+ return;
+ if (cap == GraphicsContext3D::STENCIL_TEST) {
+ m_stencilEnabled = true;
+ applyStencilTest();
+ cleanupAfterGraphicsCall(false);
+ return;
+ }
+ if (cap == GraphicsContext3D::SCISSOR_TEST) {
+ m_scissorEnabled = true;
+ if (m_drawingBuffer)
+ m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
+ }
+ m_context->enable(cap);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::enableVertexAttribArray(GC3Duint index, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "enableVertexAttribArray", "index out of range");
+ return;
+ }
+
+ WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+ state.enabled = true;
+
+ m_context->enableVertexAttribArray(index);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::finish()
+{
+ if (isContextLost())
+ return;
+ m_context->finish();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::flush()
+{
+ if (isContextLost())
+ return;
+ m_context->flush();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment))
+ return;
+ if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "framebufferRenderbuffer", "invalid target");
+ return;
+ }
+ if (buffer && !buffer->validate(contextGroup(), this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context");
+ return;
+ }
+ // Don't allow the default framebuffer to be mutated; all current
+ // implementations use an FBO internally in place of the default
+ // FBO.
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no framebuffer bound");
+ return;
+ }
+ Platform3DObject bufferObject = objectOrZero(buffer);
+ switch (attachment) {
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
+ break;
+ default:
+ m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, bufferObject);
+ }
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
+ applyStencilTest();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture* texture, GC3Dint level, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment))
+ return;
+ if (level) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "framebufferTexture2D", "level not 0");
+ return;
+ }
+ if (texture && !texture->validate(contextGroup(), this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context");
+ return;
+ }
+ // Don't allow the default framebuffer to be mutated; all current
+ // implementations use an FBO internally in place of the default
+ // FBO.
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no framebuffer bound");
+ return;
+ }
+ Platform3DObject textureObject = objectOrZero(texture);
+ switch (attachment) {
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ m_context->framebufferTexture2D(target, GraphicsContext3D::DEPTH_ATTACHMENT, textarget, textureObject, level);
+ m_context->framebufferTexture2D(target, GraphicsContext3D::STENCIL_ATTACHMENT, textarget, textureObject, level);
+ break;
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+ break;
+ default:
+ m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+ }
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
+ applyStencilTest();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::frontFace(GC3Denum mode)
+{
+ if (isContextLost())
+ return;
+ m_context->frontFace(mode);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::generateMipmap(GC3Denum target)
+{
+ if (isContextLost())
+ return;
+ WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false);
+ if (!tex)
+ return;
+ if (!tex->canGenerateMipmaps()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "generateMipmap", "level 0 not power of 2 or not all the same size");
+ return;
+ }
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=123916. Compressed textures should be allowed in WebGL 2:
+ if (tex->isCompressed()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "generateMipmap", "trying to generate mipmaps from compressed texture");
+ return;
+ }
+ if (!validateSettableTexFormat("generateMipmap", tex->getInternalFormat(target, 0)))
+ return;
+
+ // generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR
+ // on Mac. Remove the hack once this driver bug is fixed.
+#if OS(DARWIN)
+ bool needToResetMinFilter = false;
+ if (tex->getMinFilter() != GraphicsContext3D::NEAREST_MIPMAP_LINEAR) {
+ m_context->texParameteri(target, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST_MIPMAP_LINEAR);
+ needToResetMinFilter = true;
+ }
+#endif
+ m_context->generateMipmap(target);
+#if OS(DARWIN)
+ if (needToResetMinFilter)
+ m_context->texParameteri(target, GraphicsContext3D::TEXTURE_MIN_FILTER, tex->getMinFilter());
+#endif
+ tex->generateMipmapLevelInfo();
+ cleanupAfterGraphicsCall(false);
+}
+
+PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, GC3Duint index, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("getActiveAttrib", program))
+ return 0;
+ ActiveInfo info;
+ if (!m_context->getActiveAttrib(objectOrZero(program), index, info))
+ return 0;
+
+ LOG(WebGL, "Returning active attribute %d: %s", index, info.name.utf8().data());
+
+ return WebGLActiveInfo::create(info.name, info.type, info.size);
+}
+
+PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, GC3Duint index, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("getActiveUniform", program))
+ return 0;
+ ActiveInfo info;
+ if (!m_context->getActiveUniform(objectOrZero(program), index, info))
+ return 0;
+ if (!isGLES2Compliant())
+ if (info.size > 1 && !info.name.endsWith("[0]"))
+ info.name.append("[0]");
+
+ LOG(WebGL, "Returning active uniform %d: %s", index, info.name.utf8().data());
+
+ return WebGLActiveInfo::create(info.name, info.type, info.size);
+}
+
+bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<RefPtr<WebGLShader>>& shaderObjects, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ shaderObjects.clear();
+ if (isContextLost() || !validateWebGLObject("getAttachedShaders", program))
+ return false;
+
+ const GC3Denum shaderType[] = {
+ GraphicsContext3D::VERTEX_SHADER,
+ GraphicsContext3D::FRAGMENT_SHADER
+ };
+ for (unsigned i = 0; i < sizeof(shaderType) / sizeof(GC3Denum); ++i) {
+ WebGLShader* shader = program->getAttachedShader(shaderType[i]);
+ if (shader)
+ shaderObjects.append(shader);
+ }
+ return true;
+}
+
+GC3Dint WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name)
+{
+ if (isContextLost() || !validateWebGLObject("getAttribLocation", program))
+ return -1;
+ if (!validateLocationLength("getAttribLocation", name))
+ return -1;
+ if (!validateString("getAttribLocation", name))
+ return -1;
+ if (isPrefixReserved(name))
+ return -1;
+ if (!program->getLinkStatus()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getAttribLocation", "program not linked");
+ return -1;
+ }
+ return m_context->getAttribLocation(objectOrZero(program), name);
+}
+
+WebGLGetInfo WebGLRenderingContext::getBufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
+ if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid target");
+ return WebGLGetInfo();
+ }
+
+ if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+
+ WebGLStateRestorer(this, false);
+ GC3Dint value = 0;
+ m_context->getBufferParameteriv(target, pname, &value);
+ if (pname == GraphicsContext3D::BUFFER_SIZE)
+ return WebGLGetInfo(value);
+ return WebGLGetInfo(static_cast<unsigned int>(value));
+}
+
+PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes()
+{
+ if (isContextLost())
+ return 0;
+ // We always need to return a new WebGLContextAttributes object to
+ // prevent the user from mutating any cached version.
+
+ // Also, we need to enforce requested values of "false" for depth
+ // and stencil, regardless of the properties of the underlying
+ // GraphicsContext3D or DrawingBuffer.
+ RefPtr<WebGLContextAttributes> attributes = WebGLContextAttributes::create(m_context->getContextAttributes());
+ if (!m_attributes.depth)
+ attributes->setDepth(false);
+ if (!m_attributes.stencil)
+ attributes->setStencil(false);
+ if (m_drawingBuffer) {
+ // The DrawingBuffer obtains its parameters from GraphicsContext3D::getContextAttributes(),
+ // but it makes its own determination of whether multisampling is supported.
+ attributes->setAntialias(m_drawingBuffer->multisample());
+ }
+ return attributes.release();
+}
+
+GC3Denum WebGLRenderingContext::getError()
+{
+ return m_context->getError();
+}
+
+WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
+{
+ if (isContextLost())
+ return 0;
+
if (equalIgnoringCase(name, "WEBKIT_EXT_texture_filter_anisotropic")
&& m_context->getExtensions()->supports("GL_EXT_texture_filter_anisotropic")) {
if (!m_extTextureFilterAnisotropic) {
m_context->getExtensions()->ensureEnabled("GL_EXT_texture_filter_anisotropic");
- m_extTextureFilterAnisotropic = std::make_unique<EXTTextureFilterAnisotropic>(this);
+ m_extTextureFilterAnisotropic = EXTTextureFilterAnisotropic::create(this);
}
return m_extTextureFilterAnisotropic.get();
}
@@ -129,7 +2425,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
&& m_context->getExtensions()->supports("GL_OES_standard_derivatives")) {
if (!m_oesStandardDerivatives) {
m_context->getExtensions()->ensureEnabled("GL_OES_standard_derivatives");
- m_oesStandardDerivatives = std::make_unique<OESStandardDerivatives>(this);
+ m_oesStandardDerivatives = OESStandardDerivatives::create(this);
}
return m_oesStandardDerivatives.get();
}
@@ -137,7 +2433,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
&& m_context->getExtensions()->supports("GL_OES_texture_float")) {
if (!m_oesTextureFloat) {
m_context->getExtensions()->ensureEnabled("GL_OES_texture_float");
- m_oesTextureFloat = std::make_unique<OESTextureFloat>(this);
+ m_oesTextureFloat = OESTextureFloat::create(this);
}
return m_oesTextureFloat.get();
}
@@ -145,7 +2441,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
&& m_context->getExtensions()->supports("GL_OES_texture_float_linear")) {
if (!m_oesTextureFloatLinear) {
m_context->getExtensions()->ensureEnabled("GL_OES_texture_float_linear");
- m_oesTextureFloatLinear = std::make_unique<OESTextureFloatLinear>(this);
+ m_oesTextureFloatLinear = OESTextureFloatLinear::create(this);
}
return m_oesTextureFloatLinear.get();
}
@@ -153,7 +2449,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
&& m_context->getExtensions()->supports("GL_OES_texture_half_float")) {
if (!m_oesTextureHalfFloat) {
m_context->getExtensions()->ensureEnabled("GL_OES_texture_half_float");
- m_oesTextureHalfFloat = std::make_unique<OESTextureHalfFloat>(this);
+ m_oesTextureHalfFloat = OESTextureHalfFloat::create(this);
}
return m_oesTextureHalfFloat.get();
}
@@ -161,7 +2457,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
&& m_context->getExtensions()->supports("GL_OES_texture_half_float_linear")) {
if (!m_oesTextureHalfFloatLinear) {
m_context->getExtensions()->ensureEnabled("GL_OES_texture_half_float_linear");
- m_oesTextureHalfFloatLinear = std::make_unique<OESTextureHalfFloatLinear>(this);
+ m_oesTextureHalfFloatLinear = OESTextureHalfFloatLinear::create(this);
}
return m_oesTextureHalfFloatLinear.get();
}
@@ -169,7 +2465,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
&& m_context->getExtensions()->supports("GL_OES_vertex_array_object")) {
if (!m_oesVertexArrayObject) {
m_context->getExtensions()->ensureEnabled("GL_OES_vertex_array_object");
- m_oesVertexArrayObject = std::make_unique<OESVertexArrayObject>(this);
+ m_oesVertexArrayObject = OESVertexArrayObject::create(this);
}
return m_oesVertexArrayObject.get();
}
@@ -177,85 +2473,548 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
&& m_context->getExtensions()->supports("GL_OES_element_index_uint")) {
if (!m_oesElementIndexUint) {
m_context->getExtensions()->ensureEnabled("GL_OES_element_index_uint");
- m_oesElementIndexUint = std::make_unique<OESElementIndexUint>(this);
+ m_oesElementIndexUint = OESElementIndexUint::create(this);
}
return m_oesElementIndexUint.get();
}
if (equalIgnoringCase(name, "WEBGL_lose_context")) {
if (!m_webglLoseContext)
- m_webglLoseContext = std::make_unique<WebGLLoseContext>(this);
+ m_webglLoseContext = WebGLLoseContext::create(this);
return m_webglLoseContext.get();
}
if ((equalIgnoringCase(name, "WEBKIT_WEBGL_compressed_texture_atc"))
&& WebGLCompressedTextureATC::supported(this)) {
if (!m_webglCompressedTextureATC)
- m_webglCompressedTextureATC = std::make_unique<WebGLCompressedTextureATC>(this);
+ m_webglCompressedTextureATC = WebGLCompressedTextureATC::create(this);
return m_webglCompressedTextureATC.get();
}
if ((equalIgnoringCase(name, "WEBKIT_WEBGL_compressed_texture_pvrtc"))
&& WebGLCompressedTexturePVRTC::supported(this)) {
if (!m_webglCompressedTexturePVRTC)
- m_webglCompressedTexturePVRTC = std::make_unique<WebGLCompressedTexturePVRTC>(this);
- return m_webglCompressedTexturePVRTC.get();
+ m_webglCompressedTexturePVRTC = WebGLCompressedTexturePVRTC::create(this);
}
if (equalIgnoringCase(name, "WEBGL_compressed_texture_s3tc")
&& WebGLCompressedTextureS3TC::supported(this)) {
if (!m_webglCompressedTextureS3TC)
- m_webglCompressedTextureS3TC = std::make_unique<WebGLCompressedTextureS3TC>(this);
+ m_webglCompressedTextureS3TC = WebGLCompressedTextureS3TC::create(this);
return m_webglCompressedTextureS3TC.get();
}
if (equalIgnoringCase(name, "WEBGL_depth_texture")
&& WebGLDepthTexture::supported(graphicsContext3D())) {
if (!m_webglDepthTexture) {
m_context->getExtensions()->ensureEnabled("GL_CHROMIUM_depth_texture");
- m_webglDepthTexture = std::make_unique<WebGLDepthTexture>(this);
+ m_webglDepthTexture = WebGLDepthTexture::create(this);
}
return m_webglDepthTexture.get();
}
- if (equalIgnoringCase(name, "WEBGL_draw_buffers") && supportsDrawBuffers()) {
- if (!m_webglDrawBuffers) {
+ if (equalIgnoringCase(name, "EXT_draw_buffers") && supportsDrawBuffers()) {
+ if (!m_extDrawBuffers) {
m_context->getExtensions()->ensureEnabled("GL_EXT_draw_buffers");
- m_webglDrawBuffers = std::make_unique<WebGLDrawBuffers>(this);
+ m_extDrawBuffers = EXTDrawBuffers::create(this);
}
- return m_webglDrawBuffers.get();
+ return m_extDrawBuffers.get();
}
if (equalIgnoringCase(name, "ANGLE_instanced_arrays") && ANGLEInstancedArrays::supported(this)) {
if (!m_angleInstancedArrays) {
m_context->getExtensions()->ensureEnabled("GL_ANGLE_instanced_arrays");
- m_angleInstancedArrays = std::make_unique<ANGLEInstancedArrays>(this);
+ m_angleInstancedArrays = ANGLEInstancedArrays::create(this);
}
return m_angleInstancedArrays.get();
}
if (allowPrivilegedExtensions()) {
if (equalIgnoringCase(name, "WEBGL_debug_renderer_info")) {
if (!m_webglDebugRendererInfo)
- m_webglDebugRendererInfo = std::make_unique<WebGLDebugRendererInfo>(this);
+ m_webglDebugRendererInfo = WebGLDebugRendererInfo::create(this);
return m_webglDebugRendererInfo.get();
}
if (equalIgnoringCase(name, "WEBGL_debug_shaders")
&& m_context->getExtensions()->supports("GL_ANGLE_translated_shader_source")) {
if (!m_webglDebugShaders)
- m_webglDebugShaders = std::make_unique<WebGLDebugShaders>(this);
+ m_webglDebugShaders = WebGLDebugShaders::create(this);
return m_webglDebugShaders.get();
}
}
-
- return nullptr;
+
+ return 0;
+}
+
+WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
+ return WebGLGetInfo();
+
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound");
+ return WebGLGetInfo();
+ }
+
+ WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(attachment);
+ if (!object) {
+ if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
+ return WebGLGetInfo(GraphicsContext3D::NONE);
+ // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
+ // specifies INVALID_OPERATION.
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+
+ ASSERT(object->isTexture() || object->isRenderbuffer());
+ if (object->isTexture()) {
+ switch (pname) {
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return WebGLGetInfo(GraphicsContext3D::TEXTURE);
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(reinterpret_cast<WebGLTexture*>(object)));
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ {
+ WebGLStateRestorer(this, false);
+ GC3Dint value = 0;
+ m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
+ return WebGLGetInfo(value);
+ }
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment");
+ return WebGLGetInfo();
+ }
+ } else {
+ switch (pname) {
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return WebGLGetInfo(GraphicsContext3D::RENDERBUFFER);
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(reinterpret_cast<WebGLRenderbuffer*>(object)));
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
+ return WebGLGetInfo();
+ }
+ }
+}
+
+WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
+ const int intZero = 0;
+ WebGLStateRestorer(this, false);
+ switch (pname) {
+ case GraphicsContext3D::ACTIVE_TEXTURE:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::ALPHA_BITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::ARRAY_BUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
+ case GraphicsContext3D::BLEND:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::BLEND_COLOR:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::BLEND_DST_ALPHA:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::BLEND_DST_RGB:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::BLEND_EQUATION_ALPHA:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::BLEND_EQUATION_RGB:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::BLEND_SRC_ALPHA:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::BLEND_SRC_RGB:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::BLUE_BITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::COLOR_CLEAR_VALUE:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::COLOR_WRITEMASK:
+ return getBooleanArrayParameter(pname);
+ case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS:
+ return WebGLGetInfo(Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size()));
+ case GraphicsContext3D::CULL_FACE:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::CULL_FACE_MODE:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::CURRENT_PROGRAM:
+ return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
+ case GraphicsContext3D::DEPTH_BITS:
+ if (!m_framebufferBinding && !m_attributes.depth)
+ return WebGLGetInfo(intZero);
+ return getIntParameter(pname);
+ case GraphicsContext3D::DEPTH_CLEAR_VALUE:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::DEPTH_FUNC:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::DEPTH_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::DEPTH_TEST:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::DEPTH_WRITEMASK:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::DITHER:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundVertexArrayObject->getElementArrayBuffer()));
+ case GraphicsContext3D::FRAMEBUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
+ case GraphicsContext3D::FRONT_FACE:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::GENERATE_MIPMAP_HINT:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::GREEN_BITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::LINE_WIDTH:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_RENDERBUFFER_SIZE:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_TEXTURE_SIZE:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VARYING_VECTORS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VERTEX_ATTRIBS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::MAX_VIEWPORT_DIMS:
+ return getWebGLIntArrayParameter(pname);
+ case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
+ // FIXME: should we always return 0 for this?
+ return getIntParameter(pname);
+ case GraphicsContext3D::PACK_ALIGNMENT:
+ return getIntParameter(pname);
+ case GraphicsContext3D::POLYGON_OFFSET_FACTOR:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::POLYGON_OFFSET_FILL:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::POLYGON_OFFSET_UNITS:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::RED_BITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::RENDERBUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
+ case GraphicsContext3D::RENDERER:
+ return WebGLGetInfo(String("WebKit WebGL"));
+ case GraphicsContext3D::SAMPLE_BUFFERS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::SAMPLE_COVERAGE_INVERT:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::SAMPLE_COVERAGE_VALUE:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::SAMPLES:
+ return getIntParameter(pname);
+ case GraphicsContext3D::SCISSOR_BOX:
+ return getWebGLIntArrayParameter(pname);
+ case GraphicsContext3D::SCISSOR_TEST:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::SHADING_LANGUAGE_VERSION:
+ return WebGLGetInfo("WebGL GLSL ES 1.0 (" + m_context->getString(GraphicsContext3D::SHADING_LANGUAGE_VERSION) + ")");
+ case GraphicsContext3D::STENCIL_BACK_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_FUNC:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_REF:
+ return getIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_VALUE_MASK:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_WRITEMASK:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_BITS:
+ if (!m_framebufferBinding && !m_attributes.stencil)
+ return WebGLGetInfo(intZero);
+ return getIntParameter(pname);
+ case GraphicsContext3D::STENCIL_CLEAR_VALUE:
+ return getIntParameter(pname);
+ case GraphicsContext3D::STENCIL_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_FUNC:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_REF:
+ return getIntParameter(pname);
+ case GraphicsContext3D::STENCIL_TEST:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::STENCIL_VALUE_MASK:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::STENCIL_WRITEMASK:
+ return getUnsignedIntParameter(pname);
+ case GraphicsContext3D::SUBPIXEL_BITS:
+ return getIntParameter(pname);
+ case GraphicsContext3D::TEXTURE_BINDING_2D:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].texture2DBinding));
+ case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].textureCubeMapBinding));
+ case GraphicsContext3D::UNPACK_ALIGNMENT:
+ return getIntParameter(pname);
+ case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
+ return WebGLGetInfo(m_unpackFlipY);
+ case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+ return WebGLGetInfo(m_unpackPremultiplyAlpha);
+ case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL:
+ return WebGLGetInfo(m_unpackColorspaceConversion);
+ case GraphicsContext3D::VENDOR:
+ return WebGLGetInfo(String("WebKit"));
+ case GraphicsContext3D::VERSION:
+ return WebGLGetInfo("WebGL 1.0 (" + m_context->getString(GraphicsContext3D::VERSION) + ")");
+ case GraphicsContext3D::VIEWPORT:
+ return getWebGLIntArrayParameter(pname);
+ case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
+ if (m_oesStandardDerivatives)
+ return getUnsignedIntParameter(Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled");
+ return WebGLGetInfo();
+ case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
+ if (m_webglDebugRendererInfo)
+ return WebGLGetInfo(m_context->getString(GraphicsContext3D::RENDERER));
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
+ return WebGLGetInfo();
+ case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
+ if (m_webglDebugRendererInfo)
+ return WebGLGetInfo(m_context->getString(GraphicsContext3D::VENDOR));
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
+ return WebGLGetInfo();
+ case Extensions3D::VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object
+ if (m_oesVertexArrayObject) {
+ if (!m_boundVertexArrayObject->isDefaultObject())
+ return WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES>(m_boundVertexArrayObject));
+ return WebGLGetInfo();
+ }
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled");
+ return WebGLGetInfo();
+ case Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+ if (m_extTextureFilterAnisotropic)
+ return getUnsignedIntParameter(Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
+ return WebGLGetInfo();
+ case Extensions3D::MAX_COLOR_ATTACHMENTS_EXT: // EXT_draw_buffers BEGIN
+ if (m_extDrawBuffers)
+ return WebGLGetInfo(getMaxColorAttachments());
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, EXT_draw_buffers not enabled");
+ return WebGLGetInfo();
+ case Extensions3D::MAX_DRAW_BUFFERS_EXT:
+ if (m_extDrawBuffers)
+ return WebGLGetInfo(getMaxDrawBuffers());
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, EXT_draw_buffers not enabled");
+ return WebGLGetInfo();
+ default:
+ if (m_extDrawBuffers
+ && pname >= Extensions3D::DRAW_BUFFER0_EXT
+ && pname < static_cast<GC3Denum>(Extensions3D::DRAW_BUFFER0_EXT + getMaxDrawBuffers())) {
+ GC3Dint value = GraphicsContext3D::NONE;
+ if (m_framebufferBinding)
+ value = m_framebufferBinding->getDrawBuffer(pname);
+ else // emulated backbuffer
+ value = m_backDrawBuffer;
+ return WebGLGetInfo(value);
+ }
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, GC3Denum pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("getProgramParameter", program))
+ return WebGLGetInfo();
+
+ WebGLStateRestorer(this, false);
+ GC3Dint value = 0;
+ switch (pname) {
+ case GraphicsContext3D::DELETE_STATUS:
+ return WebGLGetInfo(program->isDeleted());
+ case GraphicsContext3D::VALIDATE_STATUS:
+ m_context->getProgramiv(objectOrZero(program), pname, &value);
+ return WebGLGetInfo(static_cast<bool>(value));
+ case GraphicsContext3D::LINK_STATUS:
+ return WebGLGetInfo(program->getLinkStatus());
+ case GraphicsContext3D::ATTACHED_SHADERS:
+ m_context->getProgramiv(objectOrZero(program), pname, &value);
+ return WebGLGetInfo(value);
+ case GraphicsContext3D::ACTIVE_ATTRIBUTES:
+ case GraphicsContext3D::ACTIVE_UNIFORMS:
+ m_context->getNonBuiltInActiveSymbolCount(objectOrZero(program), pname, &value);
+ return WebGLGetInfo(value);
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getProgramParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject("getProgramInfoLog", program))
+ return "";
+ WebGLStateRestorer(this, false);
+ return ensureNotNull(m_context->getProgramInfoLog(objectOrZero(program)));
+}
+
+WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
+ if (target != GraphicsContext3D::RENDERBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid target");
+ return WebGLGetInfo();
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound");
+ return WebGLGetInfo();
+ }
+
+ if (m_renderbufferBinding->getInternalFormat() == GraphicsContext3D::DEPTH_STENCIL
+ && !m_renderbufferBinding->isValid()) {
+ ASSERT(!isDepthStencilSupported());
+ int value = 0;
+ switch (pname) {
+ case GraphicsContext3D::RENDERBUFFER_WIDTH:
+ value = m_renderbufferBinding->getWidth();
+ break;
+ case GraphicsContext3D::RENDERBUFFER_HEIGHT:
+ value = m_renderbufferBinding->getHeight();
+ break;
+ case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
+ value = 0;
+ break;
+ case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
+ value = 24;
+ break;
+ case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
+ value = 8;
+ break;
+ case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
+ return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+ return WebGLGetInfo(value);
+ }
+
+ WebGLStateRestorer(this, false);
+ GC3Dint value = 0;
+ switch (pname) {
+ case GraphicsContext3D::RENDERBUFFER_WIDTH:
+ case GraphicsContext3D::RENDERBUFFER_HEIGHT:
+ case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
+ m_context->getRenderbufferParameteriv(target, pname, &value);
+ return WebGLGetInfo(value);
+ case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
+ return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, GC3Denum pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("getShaderParameter", shader))
+ return WebGLGetInfo();
+ WebGLStateRestorer(this, false);
+ GC3Dint value = 0;
+ switch (pname) {
+ case GraphicsContext3D::DELETE_STATUS:
+ return WebGLGetInfo(shader->isDeleted());
+ case GraphicsContext3D::COMPILE_STATUS:
+ m_context->getShaderiv(objectOrZero(shader), pname, &value);
+ return WebGLGetInfo(static_cast<bool>(value));
+ case GraphicsContext3D::SHADER_TYPE:
+ m_context->getShaderiv(objectOrZero(shader), pname, &value);
+ return WebGLGetInfo(static_cast<unsigned int>(value));
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject("getShaderInfoLog", shader))
+ return "";
+ WebGLStateRestorer(this, false);
+ return ensureNotNull(m_context->getShaderInfoLog(objectOrZero(shader)));
+}
+
+PassRefPtr<WebGLShaderPrecisionFormat> WebGLRenderingContext::getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return 0;
+ switch (shaderType) {
+ case GraphicsContext3D::VERTEX_SHADER:
+ case GraphicsContext3D::FRAGMENT_SHADER:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderPrecisionFormat", "invalid shader type");
+ return 0;
+ }
+ switch (precisionType) {
+ case GraphicsContext3D::LOW_FLOAT:
+ case GraphicsContext3D::MEDIUM_FLOAT:
+ case GraphicsContext3D::HIGH_FLOAT:
+ case GraphicsContext3D::LOW_INT:
+ case GraphicsContext3D::MEDIUM_INT:
+ case GraphicsContext3D::HIGH_INT:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderPrecisionFormat", "invalid precision type");
+ return 0;
+ }
+
+ GC3Dint range[2] = {0, 0};
+ GC3Dint precision = 0;
+ m_context->getShaderPrecisionFormat(shaderType, precisionType, range, &precision);
+ return WebGLShaderPrecisionFormat::create(range[0], range[1], precision);
+}
+
+String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject("getShaderSource", shader))
+ return "";
+ return ensureNotNull(shader->getSource());
}
Vector<String> WebGLRenderingContext::getSupportedExtensions()
{
Vector<String> result;
-
- if (m_isPendingPolicyResolution)
- return result;
-
- if (m_context->getExtensions()->supports("GL_EXT_blend_minmax"))
- result.append("EXT_blend_minmax");
- if (m_context->getExtensions()->supports("GL_EXT_sRGB"))
- result.append("EXT_sRGB");
- if (m_context->getExtensions()->supports("GL_EXT_frag_depth"))
- result.append("EXT_frag_depth");
if (m_context->getExtensions()->supports("GL_OES_texture_float"))
result.append("OES_texture_float");
if (m_context->getExtensions()->supports("GL_OES_texture_float_linear"))
@@ -266,8 +3025,6 @@ Vector<String> WebGLRenderingContext::getSupportedExtensions()
result.append("OES_texture_half_float_linear");
if (m_context->getExtensions()->supports("GL_OES_standard_derivatives"))
result.append("OES_standard_derivatives");
- if (m_context->getExtensions()->supports("GL_EXT_shader_texture_lod") || m_context->getExtensions()->supports("GL_ARB_shader_texture_lod"))
- result.append("EXT_shader_texture_lod");
if (m_context->getExtensions()->supports("GL_EXT_texture_filter_anisotropic"))
result.append("WEBKIT_EXT_texture_filter_anisotropic");
if (m_context->getExtensions()->supports("GL_OES_vertex_array_object"))
@@ -284,109 +3041,543 @@ Vector<String> WebGLRenderingContext::getSupportedExtensions()
if (WebGLDepthTexture::supported(graphicsContext3D()))
result.append("WEBGL_depth_texture");
if (supportsDrawBuffers())
- result.append("WEBGL_draw_buffers");
+ result.append("EXT_draw_buffers");
if (ANGLEInstancedArrays::supported(this))
result.append("ANGLE_instanced_arrays");
-
+
if (allowPrivilegedExtensions()) {
if (m_context->getExtensions()->supports("GL_ANGLE_translated_shader_source"))
result.append("WEBGL_debug_shaders");
result.append("WEBGL_debug_renderer_info");
}
-
+
return result;
}
-WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode& ec)
+WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
+ if (isContextLost())
return WebGLGetInfo();
-
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound");
+ WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false);
+ if (!tex)
+ return WebGLGetInfo();
+ WebGLStateRestorer(this, false);
+ GC3Dint value = 0;
+ switch (pname) {
+ case GraphicsContext3D::TEXTURE_MAG_FILTER:
+ case GraphicsContext3D::TEXTURE_MIN_FILTER:
+ case GraphicsContext3D::TEXTURE_WRAP_S:
+ case GraphicsContext3D::TEXTURE_WRAP_T:
+ m_context->getTexParameteriv(target, pname, &value);
+ return WebGLGetInfo(static_cast<unsigned int>(value));
+ case Extensions3D::TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+ if (m_extTextureFilterAnisotropic) {
+ m_context->getTexParameteriv(target, pname, &value);
+ return WebGLGetInfo(static_cast<unsigned int>(value));
+ }
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getTexParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
+ return WebGLGetInfo();
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getTexParameter", "invalid parameter name");
return WebGLGetInfo();
}
-
- WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(attachment);
- if (!object) {
- if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
- return WebGLGetInfo(GraphicsContext3D::NONE);
- // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
- // specifies INVALID_OPERATION.
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name");
+}
+
+WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("getUniform", program))
+ return WebGLGetInfo();
+ if (!uniformLocation || uniformLocation->program() != program) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program");
return WebGLGetInfo();
}
-
- ASSERT(object->isTexture() || object->isRenderbuffer());
- if (object->isTexture()) {
- switch (pname) {
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- return WebGLGetInfo(GraphicsContext3D::TEXTURE);
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(reinterpret_cast<WebGLTexture*>(object)));
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
- case Extensions3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: {
- GC3Dint value = 0;
- m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
- return WebGLGetInfo(value);
+ GC3Dint location = uniformLocation->location();
+
+ WebGLStateRestorer(this, false);
+ GC3Denum baseType;
+ unsigned length;
+ switch (uniformLocation->type()) {
+ case GraphicsContext3D::BOOL:
+ baseType = GraphicsContext3D::BOOL;
+ length = 1;
+ break;
+ case GraphicsContext3D::BOOL_VEC2:
+ baseType = GraphicsContext3D::BOOL;
+ length = 2;
+ break;
+ case GraphicsContext3D::BOOL_VEC3:
+ baseType = GraphicsContext3D::BOOL;
+ length = 3;
+ break;
+ case GraphicsContext3D::BOOL_VEC4:
+ baseType = GraphicsContext3D::BOOL;
+ length = 4;
+ break;
+ case GraphicsContext3D::INT:
+ baseType = GraphicsContext3D::INT;
+ length = 1;
+ break;
+ case GraphicsContext3D::INT_VEC2:
+ baseType = GraphicsContext3D::INT;
+ length = 2;
+ break;
+ case GraphicsContext3D::INT_VEC3:
+ baseType = GraphicsContext3D::INT;
+ length = 3;
+ break;
+ case GraphicsContext3D::INT_VEC4:
+ baseType = GraphicsContext3D::INT;
+ length = 4;
+ break;
+ case GraphicsContext3D::FLOAT:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 1;
+ break;
+ case GraphicsContext3D::FLOAT_VEC2:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 2;
+ break;
+ case GraphicsContext3D::FLOAT_VEC3:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 3;
+ break;
+ case GraphicsContext3D::FLOAT_VEC4:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 4;
+ break;
+ case GraphicsContext3D::FLOAT_MAT2:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 4;
+ break;
+ case GraphicsContext3D::FLOAT_MAT3:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 9;
+ break;
+ case GraphicsContext3D::FLOAT_MAT4:
+ baseType = GraphicsContext3D::FLOAT;
+ length = 16;
+ break;
+ case GraphicsContext3D::SAMPLER_2D:
+ case GraphicsContext3D::SAMPLER_CUBE:
+ baseType = GraphicsContext3D::INT;
+ length = 1;
+ break;
+ default:
+ // Can't handle this type
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getUniform", "unhandled type");
+ return WebGLGetInfo();
+ }
+ switch (baseType) {
+ case GraphicsContext3D::FLOAT: {
+ GC3Dfloat value[16] = {0};
+ if (m_isRobustnessEXTSupported)
+ m_context->getExtensions()->getnUniformfvEXT(objectOrZero(program), location, 16 * sizeof(GC3Dfloat), value);
+ else
+ m_context->getUniformfv(objectOrZero(program), location, value);
+ if (length == 1)
+ return WebGLGetInfo(value[0]);
+ return WebGLGetInfo(Float32Array::create(value, length));
+ }
+ case GraphicsContext3D::INT: {
+ GC3Dint value[4] = {0};
+ if (m_isRobustnessEXTSupported)
+ m_context->getExtensions()->getnUniformivEXT(objectOrZero(program), location, 4 * sizeof(GC3Dint), value);
+ else
+ m_context->getUniformiv(objectOrZero(program), location, value);
+ if (length == 1)
+ return WebGLGetInfo(value[0]);
+ return WebGLGetInfo(Int32Array::create(value, length));
+ }
+ case GraphicsContext3D::BOOL: {
+ GC3Dint value[4] = {0};
+ if (m_isRobustnessEXTSupported)
+ m_context->getExtensions()->getnUniformivEXT(objectOrZero(program), location, 4 * sizeof(GC3Dint), value);
+ else
+ m_context->getUniformiv(objectOrZero(program), location, value);
+ if (length > 1) {
+ bool boolValue[16] = {0};
+ for (unsigned j = 0; j < length; j++)
+ boolValue[j] = static_cast<bool>(value[j]);
+ return WebGLGetInfo(boolValue, length);
}
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment");
+ return WebGLGetInfo(static_cast<bool>(value[0]));
+ }
+ default:
+ notImplemented();
+ }
+
+ // If we get here, something went wrong in our unfortunately complex logic above
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getUniform", "unknown error");
+ return WebGLGetInfo();
+}
+
+PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("getUniformLocation", program))
+ return nullptr;
+ if (!validateLocationLength("getUniformLocation", name))
+ return nullptr;
+ if (!validateString("getUniformLocation", name))
+ return nullptr;
+ if (isPrefixReserved(name))
+ return nullptr;
+ if (!program->getLinkStatus()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getUniformLocation", "program not linked");
+ return nullptr;
+ }
+ WebGLStateRestorer(this, false);
+ GC3Dint uniformLocation = m_context->getUniformLocation(objectOrZero(program), name);
+ if (uniformLocation == -1)
+ return nullptr;
+
+ GC3Dint activeUniforms = 0;
+ m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::ACTIVE_UNIFORMS, &activeUniforms);
+ for (GC3Dint i = 0; i < activeUniforms; i++) {
+ ActiveInfo info;
+ if (!m_context->getActiveUniform(objectOrZero(program), i, info))
+ return 0;
+ // Strip "[0]" from the name if it's an array.
+ if (info.name.endsWith("[0]"))
+ info.name = info.name.left(info.name.length() - 3);
+ // If it's an array, we need to iterate through each element, appending "[index]" to the name.
+ for (GC3Dint index = 0; index < info.size; ++index) {
+ String uniformName = info.name + "[" + String::number(index) + "]";
+
+ if (name == uniformName || name == info.name)
+ return WebGLUniformLocation::create(program, uniformLocation, info.type);
+ }
+ }
+ return nullptr;
+}
+
+WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GC3Duint index, GC3Denum pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+
+ if (isContextLost())
+ return WebGLGetInfo();
+
+ WebGLStateRestorer(this, false);
+
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getVertexAttrib", "index out of range");
+ return WebGLGetInfo();
+ }
+
+ const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+
+ if (m_angleInstancedArrays && pname == GraphicsContext3D::VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE)
+ return WebGLGetInfo(state.divisor);
+
+ switch (pname) {
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+ if ((!isGLES2Compliant() && !index && m_boundVertexArrayObject->getVertexAttribState(0).bufferBinding == m_vertexAttrib0Buffer)
+ || !state.bufferBinding
+ || !state.bufferBinding->object())
return WebGLGetInfo();
+ return WebGLGetInfo(PassRefPtr<WebGLBuffer>(state.bufferBinding));
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_ENABLED:
+ return WebGLGetInfo(state.enabled);
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_NORMALIZED:
+ return WebGLGetInfo(state.normalized);
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE:
+ return WebGLGetInfo(state.size);
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE:
+ return WebGLGetInfo(state.originalStride);
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE:
+ return WebGLGetInfo(state.type);
+ case GraphicsContext3D::CURRENT_VERTEX_ATTRIB:
+ return WebGLGetInfo(Float32Array::create(m_vertexAttribValue[index].value, 4));
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getVertexAttrib", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+long long WebGLRenderingContext::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
+{
+ if (isContextLost())
+ return 0;
+ GC3Dsizeiptr result = m_context->getVertexAttribOffset(index, pname);
+ cleanupAfterGraphicsCall(false);
+ return static_cast<long long>(result);
+}
+
+void WebGLRenderingContext::hint(GC3Denum target, GC3Denum mode)
+{
+ if (isContextLost())
+ return;
+ bool isValid = false;
+ switch (target) {
+ case GraphicsContext3D::GENERATE_MIPMAP_HINT:
+ isValid = true;
+ break;
+ case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
+ if (m_oesStandardDerivatives)
+ isValid = true;
+ break;
+ }
+ if (!isValid) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "hint", "invalid target");
+ return;
+ }
+ m_context->hint(target, mode);
+ cleanupAfterGraphicsCall(false);
+}
+
+GC3Dboolean WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
+{
+ if (!buffer || isContextLost())
+ return 0;
+
+ if (!buffer->hasEverBeenBound())
+ return 0;
+
+ return m_context->isBuffer(buffer->object());
+}
+
+bool WebGLRenderingContext::isContextLost() const
+{
+ return m_contextLost;
+}
+
+GC3Dboolean WebGLRenderingContext::isEnabled(GC3Denum cap)
+{
+ if (isContextLost() || !validateCapability("isEnabled", cap))
+ return 0;
+ if (cap == GraphicsContext3D::STENCIL_TEST)
+ return m_stencilEnabled;
+ return m_context->isEnabled(cap);
+}
+
+GC3Dboolean WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
+{
+ if (!framebuffer || isContextLost())
+ return 0;
+
+ if (!framebuffer->hasEverBeenBound())
+ return 0;
+
+ return m_context->isFramebuffer(framebuffer->object());
+}
+
+GC3Dboolean WebGLRenderingContext::isProgram(WebGLProgram* program)
+{
+ if (!program || isContextLost())
+ return 0;
+
+ return m_context->isProgram(program->object());
+}
+
+GC3Dboolean WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
+{
+ if (!renderbuffer || isContextLost())
+ return 0;
+
+ if (!renderbuffer->hasEverBeenBound())
+ return 0;
+
+ return m_context->isRenderbuffer(renderbuffer->object());
+}
+
+GC3Dboolean WebGLRenderingContext::isShader(WebGLShader* shader)
+{
+ if (!shader || isContextLost())
+ return 0;
+
+ return m_context->isShader(shader->object());
+}
+
+GC3Dboolean WebGLRenderingContext::isTexture(WebGLTexture* texture)
+{
+ if (!texture || isContextLost())
+ return 0;
+
+ if (!texture->hasEverBeenBound())
+ return 0;
+
+ return m_context->isTexture(texture->object());
+}
+
+void WebGLRenderingContext::lineWidth(GC3Dfloat width)
+{
+ if (isContextLost())
+ return;
+ m_context->lineWidth(width);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("linkProgram", program))
+ return;
+ if (!isGLES2Compliant()) {
+ WebGLShader* vertexShader = program->getAttachedShader(GraphicsContext3D::VERTEX_SHADER);
+ WebGLShader* fragmentShader = program->getAttachedShader(GraphicsContext3D::FRAGMENT_SHADER);
+ if (!vertexShader || !vertexShader->isValid() || !fragmentShader || !fragmentShader->isValid() || !m_context->precisionsMatch(objectOrZero(vertexShader), objectOrZero(fragmentShader))) {
+ program->setLinkStatus(false);
+ return;
}
- } else {
- switch (pname) {
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- return WebGLGetInfo(GraphicsContext3D::RENDERBUFFER);
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(reinterpret_cast<WebGLRenderbuffer*>(object)));
- case Extensions3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: {
- if (!m_extsRGB) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
- return WebGLGetInfo();
- }
- WebGLRenderbuffer* renderBuffer = reinterpret_cast<WebGLRenderbuffer*>(object);
- GC3Denum renderBufferFormat = renderBuffer->getInternalFormat();
- ASSERT(renderBufferFormat != Extensions3D::SRGB_EXT && renderBufferFormat != Extensions3D::SRGB_ALPHA_EXT);
- if (renderBufferFormat == Extensions3D::SRGB8_ALPHA8_EXT)
- return WebGLGetInfo(Extensions3D::SRGB_EXT);
- return WebGLGetInfo(GraphicsContext3D::LINEAR);
+ }
+
+ m_context->linkProgram(objectOrZero(program));
+ program->increaseLinkCount();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::pixelStorei(GC3Denum pname, GC3Dint param)
+{
+ if (isContextLost())
+ return;
+ switch (pname) {
+ case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
+ m_unpackFlipY = param;
+ break;
+ case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+ m_unpackPremultiplyAlpha = param;
+ break;
+ case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL:
+ if (param == GraphicsContext3D::BROWSER_DEFAULT_WEBGL || param == GraphicsContext3D::NONE)
+ m_unpackColorspaceConversion = static_cast<GC3Denum>(param);
+ else {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "pixelStorei", "invalid parameter for UNPACK_COLORSPACE_CONVERSION_WEBGL");
+ return;
}
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
- return WebGLGetInfo();
+ break;
+ case GraphicsContext3D::PACK_ALIGNMENT:
+ case GraphicsContext3D::UNPACK_ALIGNMENT:
+ if (param == 1 || param == 2 || param == 4 || param == 8) {
+ if (pname == GraphicsContext3D::PACK_ALIGNMENT)
+ m_packAlignment = param;
+ else // GraphicsContext3D::UNPACK_ALIGNMENT:
+ m_unpackAlignment = param;
+ m_context->pixelStorei(pname, param);
+ cleanupAfterGraphicsCall(false);
+ } else {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "pixelStorei", "invalid parameter for alignment");
+ return;
}
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "pixelStorei", "invalid parameter name");
+ return;
}
}
-bool WebGLRenderingContext::validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment)
+void WebGLRenderingContext::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
{
- if (target != GraphicsContext3D::FRAMEBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
- return false;
+ if (isContextLost())
+ return;
+ m_context->polygonOffset(factor, units);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&)
+{
+ if (isContextLost())
+ return;
+ // Due to WebGL's same-origin restrictions, it is not possible to
+ // taint the origin using the WebGL API.
+ ASSERT(canvas()->originClean());
+ // Validate input parameters.
+ if (!pixels) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "readPixels", "no destination ArrayBufferView");
+ return;
}
- switch (attachment) {
- case GraphicsContext3D::COLOR_ATTACHMENT0:
- case GraphicsContext3D::DEPTH_ATTACHMENT:
- case GraphicsContext3D::STENCIL_ATTACHMENT:
- case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ switch (format) {
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::RGBA:
break;
default:
- if (m_webglDrawBuffers
- && attachment > GraphicsContext3D::COLOR_ATTACHMENT0
- && attachment < static_cast<GC3Denum>(GraphicsContext3D::COLOR_ATTACHMENT0 + getMaxColorAttachments()))
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid attachment");
- return false;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "invalid format");
+ return;
}
- return true;
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+ case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "invalid type");
+ return;
+ }
+ if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "format not RGBA or type not UNSIGNED_BYTE");
+ return;
+ }
+ // Validate array type against pixel type.
+ if (pixels->getType() != JSC::TypeUint8) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "ArrayBufferView not Uint8Array");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
+ return;
+ }
+ // Calculate array size, taking into consideration of PACK_ALIGNMENT.
+ unsigned int totalBytesRequired = 0;
+ unsigned int padding = 0;
+ if (!m_isRobustnessEXTSupported) {
+ GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
+ if (error != GraphicsContext3D::NO_ERROR) {
+ synthesizeGLError(error, "readPixels", "invalid dimensions");
+ return;
+ }
+ if (pixels->byteLength() < totalBytesRequired) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
+ return;
+ }
+ }
+
+ clearIfComposited();
+ void* data = pixels->baseAddress();
+
+ {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ if (m_isRobustnessEXTSupported)
+ m_context->getExtensions()->readnPixelsEXT(x, y, width, height, format, type, pixels->byteLength(), data);
+ else
+ m_context->readPixels(x, y, width, height, format, type, data);
+ }
+
+#if OS(DARWIN)
+ if (m_isRobustnessEXTSupported) // we haven't computed padding
+ m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
+ // FIXME: remove this section when GL driver bug on Mac AND the GLES driver bug
+ // on QC is fixed, i.e., when alpha is off, readPixels should
+ // set alpha to 255 instead of 0.
+ if (!m_framebufferBinding && !m_context->getContextAttributes().alpha) {
+ unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
+ for (GC3Dsizei iy = 0; iy < height; ++iy) {
+ for (GC3Dsizei ix = 0; ix < width; ++ix) {
+ pixels[3] = 255;
+ pixels += 4;
+ }
+ pixels += padding;
+ }
+ }
+#endif
+ cleanupAfterGraphicsCall(false);
}
-
+
+void WebGLRenderingContext::releaseShaderCompiler()
+{
+ if (isContextLost())
+ return;
+ m_context->releaseShaderCompiler();
+ cleanupAfterGraphicsCall(false);
+}
+
void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
{
- if (isContextLostOrPending())
+ if (isContextLost())
return;
if (target != GraphicsContext3D::RENDERBUFFER) {
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid target");
@@ -404,19 +3595,17 @@ void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum intern
case GraphicsContext3D::RGB5_A1:
case GraphicsContext3D::RGB565:
case GraphicsContext3D::STENCIL_INDEX8:
- case Extensions3D::SRGB8_ALPHA8_EXT:
- if (internalformat == Extensions3D::SRGB8_ALPHA8_EXT && !m_extsRGB) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
- return;
- }
m_context->renderbufferStorage(target, internalformat, width, height);
m_renderbufferBinding->setInternalFormat(internalformat);
m_renderbufferBinding->setIsValid(true);
m_renderbufferBinding->setSize(width, height);
+ cleanupAfterGraphicsCall(false);
break;
case GraphicsContext3D::DEPTH_STENCIL:
- if (isDepthStencilSupported())
+ if (isDepthStencilSupported()) {
m_context->renderbufferStorage(target, Extensions3D::DEPTH24_STENCIL8, width, height);
+ cleanupAfterGraphicsCall(false);
+ }
m_renderbufferBinding->setSize(width, height);
m_renderbufferBinding->setIsValid(isDepthStencilSupported());
m_renderbufferBinding->setInternalFormat(internalformat);
@@ -428,96 +3617,451 @@ void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum intern
applyStencilTest();
}
-void WebGLRenderingContext::hint(GC3Denum target, GC3Denum mode)
+void WebGLRenderingContext::sampleCoverage(GC3Dfloat value, GC3Dboolean invert)
{
- if (isContextLostOrPending())
+ if (isContextLost())
return;
- bool isValid = false;
- switch (target) {
- case GraphicsContext3D::GENERATE_MIPMAP_HINT:
- isValid = true;
+ m_context->sampleCoverage(value, invert);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+ if (isContextLost())
+ return;
+ if (!validateSize("scissor", width, height))
+ return;
+ m_context->scissor(x, y, width, height);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("shaderSource", shader))
+ return;
+ String stringWithoutComments = StripComments(string).result();
+ if (!validateString("shaderSource", stringWithoutComments))
+ return;
+ shader->setSource(string);
+ m_context->shaderSource(objectOrZero(shader), stringWithoutComments);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
+{
+ if (isContextLost())
+ return;
+ if (!validateStencilFunc("stencilFunc", func))
+ return;
+ m_stencilFuncRef = ref;
+ m_stencilFuncRefBack = ref;
+ m_stencilFuncMask = mask;
+ m_stencilFuncMaskBack = mask;
+ m_context->stencilFunc(func, ref, mask);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
+{
+ if (isContextLost())
+ return;
+ if (!validateStencilFunc("stencilFuncSeparate", func))
+ return;
+ switch (face) {
+ case GraphicsContext3D::FRONT_AND_BACK:
+ m_stencilFuncRef = ref;
+ m_stencilFuncRefBack = ref;
+ m_stencilFuncMask = mask;
+ m_stencilFuncMaskBack = mask;
break;
- case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
- if (m_oesStandardDerivatives)
- isValid = true;
+ case GraphicsContext3D::FRONT:
+ m_stencilFuncRef = ref;
+ m_stencilFuncMask = mask;
break;
+ case GraphicsContext3D::BACK:
+ m_stencilFuncRefBack = ref;
+ m_stencilFuncMaskBack = mask;
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "stencilFuncSeparate", "invalid face");
+ return;
}
- if (!isValid) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "hint", "invalid target");
+ m_context->stencilFuncSeparate(face, func, ref, mask);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::stencilMask(GC3Duint mask)
+{
+ if (isContextLost())
+ return;
+ m_stencilMask = mask;
+ m_stencilMaskBack = mask;
+ m_context->stencilMask(mask);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
+{
+ if (isContextLost())
+ return;
+ switch (face) {
+ case GraphicsContext3D::FRONT_AND_BACK:
+ m_stencilMask = mask;
+ m_stencilMaskBack = mask;
+ break;
+ case GraphicsContext3D::FRONT:
+ m_stencilMask = mask;
+ break;
+ case GraphicsContext3D::BACK:
+ m_stencilMaskBack = mask;
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "stencilMaskSeparate", "invalid face");
return;
}
- m_context->hint(target, mode);
+ m_context->stencilMaskSeparate(face, mask);
+ cleanupAfterGraphicsCall(false);
}
-
-void WebGLRenderingContext::clear(GC3Dbitfield mask)
+
+void WebGLRenderingContext::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
{
- if (isContextLostOrPending())
+ if (isContextLost())
return;
- if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clear", "invalid mask");
+ m_context->stencilOp(fail, zfail, zpass);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
+{
+ if (isContextLost())
return;
+ m_context->stencilOpSeparate(face, fail, zfail, zpass);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec)
+{
+ // FIXME: For now we ignore any errors returned
+ ec = 0;
+ WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
+ ASSERT(validateTexFuncParameters("texImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, format, type));
+ ASSERT(tex);
+ ASSERT(!level || !WebGLTexture::isNPOT(width, height));
+ if (!pixels) {
+ // Note: Chromium's OpenGL implementation clears textures and isResourceSafe() is therefore true.
+ // For other implementations, if they are using ANGLE_depth_texture, ANGLE depth textures
+ // can not be cleared with texImage2D and must be cleared by binding to an fbo and calling
+ // clear.
+ if (isResourceSafe())
+ m_context->texImage2D(target, level, internalformat, width, height, border, format, type, 0);
+ else {
+ bool succeed = m_context->texImage2DResourceSafe(target, level, internalformat, width, height,
+ border, format, type, m_unpackAlignment);
+ if (!succeed)
+ return;
+ }
+ } else {
+ ASSERT(validateSettableTexFormat("texImage2D", internalformat));
+ m_context->texImage2D(target, level, internalformat, width, height,
+ border, format, type, pixels);
}
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
+ tex->setLevelInfo(target, level, internalformat, width, height, type);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
+{
+ ec = 0;
+ Vector<uint8_t> data;
+ GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
+ if (!imageExtractor.extractSucceeded()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
return;
}
- if (!clearIfComposited(mask))
- m_context->clear(mask);
- markContextChanged();
+ GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
+ GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
+ const void* imagePixelData = imageExtractor.imagePixelData();
+
+ bool needConversion = true;
+ if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
+ needConversion = false;
+ else {
+ if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "packImage error");
+ return;
+ }
+ }
+
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, image->width(), image->height(), 0, format, type, needConversion ? data.data() : imagePixelData, ec);
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
}
-void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
+bool WebGLRenderingContext::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset)
+{
+ if (!validateTexFuncParameters(functionName, functionType, target, level, internalformat, width, height, border, format, type))
+ return false;
+
+ WebGLTexture* texture = validateTextureBinding(functionName, target, true);
+ if (!texture)
+ return false;
+
+ if (functionType == NotTexSubImage2D) {
+ if (level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level > 0 not power of 2");
+ return false;
+ }
+ // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
+ // by checking if the ArrayBufferView is null or not.
+ if (sourceType != SourceArrayBufferView) {
+ if (!validateSettableTexFormat(functionName, format))
+ return false;
+ }
+ } else {
+ if (!validateSettableTexFormat(functionName, format))
+ return false;
+ if (!validateSize(functionName, xoffset, yoffset))
+ return false;
+ // Before checking if it is in the range, check if overflow happens first.
+ if (xoffset + width < 0 || yoffset + height < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "bad dimensions");
+ return false;
+ }
+ if (xoffset + width > texture->getWidth(target, level) || yoffset + height > texture->getHeight(target, level)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "dimensions out of range");
+ return false;
+ }
+ if (texture->getInternalFormat(target, level) != format || texture->getType(target, level) != type) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type and format do not match texture");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
{
- if (isContextLostOrPending())
+ if (isContextLost() || !validateTexFuncData("texImage2D", level, width, height, format, type, pixels, NullAllowed)
+ || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))
return;
- if (!validateTexFuncParameters("copyTexImage2D", CopyTexImage, target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
+ void* data = pixels ? pixels->baseAddress() : 0;
+ Vector<uint8_t> tempData;
+ bool changeUnpackAlignment = false;
+ if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+ if (!m_context->extractTextureData(width, height, format, type,
+ m_unpackAlignment,
+ m_unpackFlipY, m_unpackPremultiplyAlpha,
+ data,
+ tempData))
+ return;
+ data = tempData.data();
+ changeUnpackAlignment = true;
+ }
+ if (changeUnpackAlignment)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, width, height, border,
+ format, type, data, ec);
+ if (changeUnpackAlignment)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost() || !pixels || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
return;
- if (!validateSettableTexFormat("copyTexImage2D", internalformat))
+ Vector<uint8_t> data;
+ bool needConversion = true;
+ // The data from ImageData is always of format RGBA8.
+ // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
+ if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE)
+ needConversion = false;
+ else {
+ if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
+ return;
+ }
+ }
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data(), ec);
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+PassRefPtr<Image> WebGLRenderingContext::drawImageIntoBuffer(Image* image, int width, int height, int deviceScaleFactor)
+{
+ IntSize size(width, height);
+ size.scale(deviceScaleFactor);
+ ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
+ if (!buf) {
+ synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "texImage2D", "out of memory");
+ return 0;
+ }
+
+ IntRect srcRect(IntPoint(), image->size());
+ IntRect destRect(IntPoint(), size);
+ buf->context()->drawImage(image, ColorSpaceDeviceRGB, destRect, srcRect);
+ return buf->copyImage(ImageBuffer::fastCopyImageMode());
+}
+
+void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost() || !validateHTMLImageElement("texImage2D", image, ec))
return;
- WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
- if (!tex)
+
+ RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
+ if (imageForRender->isSVGImage())
+ imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), canvas()->deviceScaleFactor());
+
+ if (!imageForRender || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
return;
- if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
+
+ texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost() || !validateHTMLCanvasElement("texImage2D", canvas, ec) || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
return;
+
+ WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
+ // If possible, copy from the canvas element directly to the texture
+ // via the GPU, without a read-back to system memory.
+ //
+ // FIXME: restriction of (RGB || RGBA)/UNSIGNED_BYTE should be lifted when
+ // ImageBuffer::copyToPlatformTexture implementations are fully functional.
+ if (GraphicsContext3D::TEXTURE_2D == target && texture && type == texture->getType(target, level)
+ && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA) && type == GraphicsContext3D::UNSIGNED_BYTE) {
+ ImageBuffer* buffer = canvas->buffer();
+ if (buffer && buffer->copyToPlatformTexture(*m_context.get(), texture->object(), internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
+ cleanupAfterGraphicsCall(false);
+ return;
+ }
}
- if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
+
+ RefPtr<ImageData> imageData = canvas->getImageData();
+ if (imageData)
+ texImage2D(target, level, internalformat, format, type, imageData.get(), ec);
+ else
+ texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+#if ENABLE(VIDEO)
+PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy, ExceptionCode&)
+{
+ IntSize size(video->videoWidth(), video->videoHeight());
+ ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
+ if (!buf) {
+ synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "texImage2D", "out of memory");
+ return 0;
+ }
+ IntRect destRect(0, 0, size.width(), size.height());
+ // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
+ video->paintCurrentFrameInContext(buf->context(), destRect);
+ return buf->copyImage(backingStoreCopy);
+}
+
+void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost() || !validateHTMLVideoElement("texImage2D", video, ec)
+ || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
return;
+
+ // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
+ // Otherwise, it will fall back to the normal SW path.
+ // FIXME: The current restrictions require that format shoud be RGB or RGBA,
+ // type should be UNSIGNED_BYTE and level should be 0. It may be lifted in the future.
+ WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
+ if (GraphicsContext3D::TEXTURE_2D == target && texture
+ && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
+ && type == GraphicsContext3D::UNSIGNED_BYTE
+ && (texture->getType(target, level) == GraphicsContext3D::UNSIGNED_BYTE || !texture->isValid(target, level))
+ && !level) {
+ if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), level, type, internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
+ cleanupAfterGraphicsCall(false);
+ return;
+ }
}
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
+
+ // Normal pure SW path.
+ RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);
+ if (!image)
+ return;
+ texImage2DImpl(target, level, internalformat, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+#endif
+
+void WebGLRenderingContext::texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat paramf, GC3Dint parami, bool isFloat)
+{
+ if (isContextLost())
+ return;
+ WebGLTexture* tex = validateTextureBinding("texParameter", target, false);
+ if (!tex)
+ return;
+ switch (pname) {
+ case GraphicsContext3D::TEXTURE_MIN_FILTER:
+ case GraphicsContext3D::TEXTURE_MAG_FILTER:
+ break;
+ case GraphicsContext3D::TEXTURE_WRAP_S:
+ case GraphicsContext3D::TEXTURE_WRAP_T:
+ if ((isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT)
+ || (!isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter");
+ return;
+ }
+ break;
+ case Extensions3D::TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+ if (!m_extTextureFilterAnisotropic) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter, EXT_texture_filter_anisotropic not enabled");
+ return;
+ }
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter name");
return;
}
- clearIfComposited();
- if (isResourceSafe())
- m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
- else {
- GC3Dint clippedX, clippedY;
- GC3Dsizei clippedWidth, clippedHeight;
- if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
- m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border,
- internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);
- if (clippedWidth > 0 && clippedHeight > 0) {
- m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
- clippedX, clippedY, clippedWidth, clippedHeight);
- }
- } else
- m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ if (isFloat) {
+ tex->setParameterf(pname, paramf);
+ m_context->texParameterf(target, pname, paramf);
+ } else {
+ tex->setParameteri(pname, parami);
+ m_context->texParameteri(target, pname, parami);
}
- // FIXME: if the framebuffer is not complete, none of the below should be executed.
- tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ cleanupAfterGraphicsCall(false);
}
-void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec)
+void WebGLRenderingContext::texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param)
+{
+ texParameter(target, pname, param, 0, true);
+}
+
+void WebGLRenderingContext::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param)
+{
+ texParameter(target, pname, 0, param, false);
+}
+
+void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec)
{
- UNUSED_PARAM(internalformat);
// FIXME: For now we ignore any errors returned
ec = 0;
ASSERT(!isContextLost());
- ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage, target, level, format, width, height, 0, format, type));
+ ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage2D, target, level, format, width, height, 0, format, type));
ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
ASSERT(validateSettableTexFormat("texSubImage2D", format));
WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
@@ -532,13 +4076,14 @@ void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC
ASSERT(tex->getInternalFormat(target, level) == format);
ASSERT(tex->getType(target, level) == type);
m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+ cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
{
ec = 0;
Vector<uint8_t> data;
- GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
+ GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
if (!imageExtractor.extractSucceeded()) {
synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image");
return;
@@ -546,7 +4091,7 @@ void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC
GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
const void* imagePixelData = imageExtractor.imagePixelData();
-
+
bool needConversion = true;
if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
needConversion = false;
@@ -556,47 +4101,48 @@ void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC
return;
}
}
-
+
if (m_unpackAlignment != 1)
m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
-
- texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), format, format, type, needConversion ? data.data() : imagePixelData, ec);
+ texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), format, type, needConversion ? data.data() : imagePixelData, ec);
if (m_unpackAlignment != 1)
m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
}
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
{
- if (isContextLostOrPending() || !validateTexFuncData("texSubImage2D", level, width, height, format, format, type, pixels, NullNotAllowed) || !validateTexFunc("texSubImage2D", TexSubImage, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))
+ if (isContextLost() || !validateTexFuncData("texSubImage2D", level, width, height, format, type, pixels, NullNotAllowed)
+ || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))
return;
-
void* data = pixels->baseAddress();
Vector<uint8_t> tempData;
bool changeUnpackAlignment = false;
if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
if (!m_context->extractTextureData(width, height, format, type,
- m_unpackAlignment,
- m_unpackFlipY, m_unpackPremultiplyAlpha,
- data,
- tempData))
+ m_unpackAlignment,
+ m_unpackFlipY, m_unpackPremultiplyAlpha,
+ data,
+ tempData))
return;
data = tempData.data();
changeUnpackAlignment = true;
}
if (changeUnpackAlignment)
m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
-
- texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, format, type, data, ec);
+ texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, ec);
if (changeUnpackAlignment)
m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
}
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)
{
ec = 0;
- if (isContextLostOrPending() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage, SourceImageData, target, level, format, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
+ if (isContextLost() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceImageData, target, level, format, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
return;
-
+
Vector<uint8_t> data;
bool needConversion = true;
// The data from ImageData is always of format RGBA8.
@@ -611,35 +4157,36 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
}
if (m_unpackAlignment != 1)
m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
-
- texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, format, type, needConversion ? data.data() : pixels->data()->data(), ec);
+ texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data(), ec);
if (m_unpackAlignment != 1)
m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
}
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
{
ec = 0;
- if (isContextLostOrPending() || !validateHTMLImageElement("texSubImage2D", image, ec))
+ if (isContextLost() || !validateHTMLImageElement("texSubImage2D", image, ec))
return;
-
+
RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
if (imageForRender->isSVGImage())
- imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), 1);
-
- if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
+ imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), canvas()->deviceScaleFactor());
+
+ if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
return;
-
+
texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)
{
ec = 0;
- if (isContextLostOrPending() || !validateHTMLCanvasElement("texSubImage2D", canvas, ec)
- || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
+ if (isContextLost() || !validateHTMLCanvasElement("texSubImage2D", canvas, ec)
+ || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
return;
-
+
RefPtr<ImageData> imageData = canvas->getImageData();
if (imageData)
texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec);
@@ -648,13 +4195,14 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
}
#if ENABLE(VIDEO)
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)
{
ec = 0;
- if (isContextLostOrPending() || !validateHTMLVideoElement("texSubImage2D", video, ec)
- || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
+ if (isContextLost() || !validateHTMLVideoElement("texSubImage2D", video, ec)
+ || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
return;
-
+
RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);
if (!image)
return;
@@ -662,31 +4210,812 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
}
#endif
-bool WebGLRenderingContext::validateTexFuncParameters(const char* functionName,
- TexFuncValidationFunctionType functionType,
- GC3Denum target, GC3Dint level,
- GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type)
+void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode& ec)
{
- // We absolutely have to validate the format and type combination.
- // The texImage2D entry points taking HTMLImage, etc. will produce
- // temporary data based on this combination, so it must be legal.
- if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level) || !validateTexFuncLevel(functionName, target, level))
- return false;
-
- if (width < 0 || height < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
- return false;
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform1f", "location not for current program");
+ return;
}
-
- GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);
+
+ m_context->uniform1f(location->location(), x);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, 1))
+ return;
+
+ m_context->uniform1fv(location->location(), v->length(), v->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, size, 1))
+ return;
+
+ m_context->uniform1fv(location->location(), size, v);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, GC3Dint x, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform1i", "location not for current program");
+ return;
+ }
+
+ if ((location->type() == GraphicsContext3D::SAMPLER_2D || location->type() == GraphicsContext3D::SAMPLER_CUBE) && x >= (int)m_textureUnits.size()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "uniform1i", "invalid texture unit");
+ return;
+ }
+
+ m_context->uniform1i(location->location(), x);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, 1))
+ return;
+
+ if (location->type() == GraphicsContext3D::SAMPLER_2D || location->type() == GraphicsContext3D::SAMPLER_CUBE)
+ for (unsigned i = 0; i < v->length(); ++i) {
+ if (v->data()[i] >= static_cast<int>(m_textureUnits.size())) {
+ LOG(WebGL, "Texture unit size=%zu, v[%d]=%d. Location type = %04X.", m_textureUnits.size(), i, v->data()[i], location->type());
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "uniform1iv", "invalid texture unit");
+ return;
+ }
+ }
+
+ m_context->uniform1iv(location->location(), v->length(), v->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, size, 1))
+ return;
+
+ if (location->type() == GraphicsContext3D::SAMPLER_2D || location->type() == GraphicsContext3D::SAMPLER_CUBE)
+ for (unsigned i = 0; i < static_cast<unsigned>(size); ++i) {
+ if (((GC3Dint*)v)[i] >= static_cast<int>(m_textureUnits.size())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "uniform1iv", "invalid texture unit");
+ return;
+ }
+ }
+
+ m_context->uniform1iv(location->location(), size, v);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2f", "location not for current program");
+ return;
+ }
+
+ m_context->uniform2f(location->location(), x, y);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, 2))
+ return;
+
+ m_context->uniform2fv(location->location(), v->length() / 2, v->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, size, 2))
+ return;
+
+ m_context->uniform2fv(location->location(), size / 2, v);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2i", "location not for current program");
+ return;
+ }
+
+ m_context->uniform2i(location->location(), x, y);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, 2))
+ return;
+
+ m_context->uniform2iv(location->location(), v->length() / 2, v->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, size, 2))
+ return;
+
+ m_context->uniform2iv(location->location(), size / 2, v);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3f", "location not for current program");
+ return;
+ }
+
+ m_context->uniform3f(location->location(), x, y, z);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, 3))
+ return;
+
+ m_context->uniform3fv(location->location(), v->length() / 3, v->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, size, 3))
+ return;
+
+ m_context->uniform3fv(location->location(), size / 3, v);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3i", "location not for current program");
+ return;
+ }
+
+ m_context->uniform3i(location->location(), x, y, z);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, 3))
+ return;
+
+ m_context->uniform3iv(location->location(), v->length() / 3, v->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, size, 3))
+ return;
+
+ m_context->uniform3iv(location->location(), size / 3, v);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4f", "location not for current program");
+ return;
+ }
+
+ m_context->uniform4f(location->location(), x, y, z, w);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, 4))
+ return;
+
+ m_context->uniform4fv(location->location(), v->length() / 4, v->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, size, 4))
+ return;
+
+ m_context->uniform4fv(location->location(), size / 4, v);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4i", "location not for current program");
+ return;
+ }
+
+ m_context->uniform4i(location->location(), x, y, z, w);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, 4))
+ return;
+
+ m_context->uniform4iv(location->location(), v->length() / 4, v->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, size, 4))
+ return;
+
+ m_context->uniform4iv(location->location(), size / 4, v);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4))
+ return;
+ m_context->uniformMatrix2fv(location->location(), v->length() / 4, transpose, v->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, size, 4))
+ return;
+ m_context->uniformMatrix2fv(location->location(), size / 4, transpose, v);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9))
+ return;
+ m_context->uniformMatrix3fv(location->location(), v->length() / 9, transpose, v->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, size, 9))
+ return;
+ m_context->uniformMatrix3fv(location->location(), size / 9, transpose, v);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16))
+ return;
+ m_context->uniformMatrix4fv(location->location(), v->length() / 16, transpose, v->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, size, 16))
+ return;
+ m_context->uniformMatrix4fv(location->location(), size / 16, transpose, v);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ bool deleted;
+ if (!checkObjectToBeBound("useProgram", program, deleted))
+ return;
+ if (deleted)
+ program = 0;
+ if (program && !program->getLinkStatus()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "useProgram", "program not valid");
+ cleanupAfterGraphicsCall(false);
+ return;
+ }
+ if (m_currentProgram != program) {
+ if (m_currentProgram)
+ m_currentProgram->onDetached(graphicsContext3D());
+ m_currentProgram = program;
+ m_context->useProgram(objectOrZero(program));
+ if (program)
+ program->onAttached();
+ }
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject("validateProgram", program))
+ return;
+ m_context->validateProgram(objectOrZero(program));
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::vertexAttrib1f(GC3Duint index, GC3Dfloat v0)
+{
+ vertexAttribfImpl("vertexAttrib1f", index, 1, v0, 0.0f, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, Float32Array* v)
+{
+ vertexAttribfvImpl("vertexAttrib1fv", index, v, 1);
+}
+
+void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
+{
+ vertexAttribfvImpl("vertexAttrib1fv", index, v, size, 1);
+}
+
+void WebGLRenderingContext::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1)
+{
+ vertexAttribfImpl("vertexAttrib2f", index, 2, v0, v1, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, Float32Array* v)
+{
+ vertexAttribfvImpl("vertexAttrib2fv", index, v, 2);
+}
+
+void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
+{
+ vertexAttribfvImpl("vertexAttrib2fv", index, v, size, 2);
+}
+
+void WebGLRenderingContext::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
+{
+ vertexAttribfImpl("vertexAttrib3f", index, 3, v0, v1, v2, 1.0f);
+}
+
+void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, Float32Array* v)
+{
+ vertexAttribfvImpl("vertexAttrib3fv", index, v, 3);
+}
+
+void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
+{
+ vertexAttribfvImpl("vertexAttrib3fv", index, v, size, 3);
+}
+
+void WebGLRenderingContext::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
+{
+ vertexAttribfImpl("vertexAttrib4f", index, 4, v0, v1, v2, v3);
+}
+
+void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, Float32Array* v)
+{
+ vertexAttribfvImpl("vertexAttrib4fv", index, v, 4);
+}
+
+void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
+{
+ vertexAttribfvImpl("vertexAttrib4fv", index, v, size, 4);
+}
+
+void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, long long offset, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ switch (type) {
+ case GraphicsContext3D::BYTE:
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ case GraphicsContext3D::SHORT:
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ case GraphicsContext3D::FLOAT:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "vertexAttribPointer", "invalid type");
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribPointer", "index out of range");
+ return;
+ }
+ if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribPointer", "bad size, stride or offset");
+ return;
+ }
+ if (!m_boundArrayBuffer) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER");
+ return;
+ }
+ // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
+ unsigned int typeSize = sizeInBytes(type);
+ if (!typeSize) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "vertexAttribPointer", "invalid type");
+ return;
+ }
+ if ((stride % typeSize) || (static_cast<GC3Dintptr>(offset) % typeSize)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "vertexAttribPointer", "stride or offset not valid for type");
+ return;
+ }
+ GC3Dsizei bytesPerElement = size * typeSize;
+
+ m_boundVertexArrayObject->setVertexAttribState(index, bytesPerElement, size, type, normalized, stride, static_cast<GC3Dintptr>(offset), m_boundArrayBuffer);
+ m_context->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GC3Dintptr>(offset));
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+ if (isContextLost())
+ return;
+ if (!validateSize("viewport", width, height))
+ return;
+ m_context->viewport(x, y, width, height);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextMode mode)
+{
+ if (isContextLost()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "loseContext", "context already lost");
+ return;
+ }
+
+ m_contextGroup->loseContextGroup(mode);
+}
+
+void WebGLRenderingContext::loseContextImpl(WebGLRenderingContext::LostContextMode mode)
+{
+ if (isContextLost())
+ return;
+
+ m_contextLost = true;
+ m_contextLostMode = mode;
+
+ if (mode == RealLostContext) {
+ // Inform the embedder that a lost context was received. In response, the embedder might
+ // decide to take action such as asking the user for permission to use WebGL again.
+ if (Frame* frame = canvas()->document().frame())
+ frame->loader().client().didLoseWebGLContext(m_context->getExtensions()->getGraphicsResetStatusARB());
+ }
+
+ detachAndRemoveAllObjects();
+
+ if (m_drawingBuffer) {
+ // Make absolutely sure we do not refer to an already-deleted texture or framebuffer.
+ m_drawingBuffer->setTexture2DBinding(0);
+ m_drawingBuffer->setFramebufferBinding(0);
+ }
+
+ // There is no direct way to clear errors from a GL implementation and
+ // looping until getError() becomes NO_ERROR might cause an infinite loop if
+ // the driver or context implementation had a bug. So, loop a reasonably
+ // large number of times to clear any existing errors.
+ for (int i = 0; i < 100; ++i) {
+ if (m_context->getError() == GraphicsContext3D::NO_ERROR)
+ break;
+ }
+ ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInConsole: DontDisplayInConsole;
+ synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL, "loseContext", "context lost", display);
+
+ // Don't allow restoration unless the context lost event has both been
+ // dispatched and its default behavior prevented.
+ m_restoreAllowed = false;
+
+ // Always defer the dispatch of the context lost event, to implement
+ // the spec behavior of queueing a task.
+ m_dispatchContextLostEventTimer.startOneShot(0);
+}
+
+void WebGLRenderingContext::forceRestoreContext()
+{
+ if (!isContextLost()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "restoreContext", "context not lost");
+ return;
+ }
+
+ if (!m_restoreAllowed) {
+ if (m_contextLostMode == SyntheticLostContext)
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "restoreContext", "context restoration not allowed");
+ return;
+ }
+
+ if (!m_restoreTimer.isActive())
+ m_restoreTimer.startOneShot(0);
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+PlatformLayer* WebGLRenderingContext::platformLayer() const
+{
+ return (!isContextLost()) ? m_context->platformLayer() : 0;
+}
+#endif
+
+void WebGLRenderingContext::removeSharedObject(WebGLSharedObject* object)
+{
+ m_contextGroup->removeObject(object);
+}
+
+void WebGLRenderingContext::addSharedObject(WebGLSharedObject* object)
+{
+ ASSERT(!isContextLost());
+ m_contextGroup->addObject(object);
+}
+
+void WebGLRenderingContext::removeContextObject(WebGLContextObject* object)
+{
+ m_contextObjects.remove(object);
+}
+
+void WebGLRenderingContext::addContextObject(WebGLContextObject* object)
+{
+ ASSERT(!isContextLost());
+ m_contextObjects.add(object);
+}
+
+void WebGLRenderingContext::detachAndRemoveAllObjects()
+{
+ while (m_contextObjects.size() > 0) {
+ HashSet<WebGLContextObject*>::iterator it = m_contextObjects.begin();
+ (*it)->detachContext();
+ }
+}
+
+bool WebGLRenderingContext::hasPendingActivity() const
+{
+ return false;
+}
+
+void WebGLRenderingContext::stop()
+{
+ if (!isContextLost()) {
+ forceLostContext(SyntheticLostContext);
+ destroyGraphicsContext3D();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContext::getBooleanParameter(GC3Denum pname)
+{
+ GC3Dboolean value = 0;
+ m_context->getBooleanv(pname, &value);
+ return WebGLGetInfo(static_cast<bool>(value));
+}
+
+WebGLGetInfo WebGLRenderingContext::getBooleanArrayParameter(GC3Denum pname)
+{
+ if (pname != GraphicsContext3D::COLOR_WRITEMASK) {
+ notImplemented();
+ return WebGLGetInfo(0, 0);
+ }
+ GC3Dboolean value[4] = {0};
+ m_context->getBooleanv(pname, value);
+ bool boolValue[4];
+ for (int ii = 0; ii < 4; ++ii)
+ boolValue[ii] = static_cast<bool>(value[ii]);
+ return WebGLGetInfo(boolValue, 4);
+}
+
+WebGLGetInfo WebGLRenderingContext::getFloatParameter(GC3Denum pname)
+{
+ GC3Dfloat value = 0;
+ m_context->getFloatv(pname, &value);
+ return WebGLGetInfo(value);
+}
+
+WebGLGetInfo WebGLRenderingContext::getIntParameter(GC3Denum pname)
+{
+ GC3Dint value = 0;
+ m_context->getIntegerv(pname, &value);
+ return WebGLGetInfo(value);
+}
+
+WebGLGetInfo WebGLRenderingContext::getUnsignedIntParameter(GC3Denum pname)
+{
+ GC3Dint value = 0;
+ m_context->getIntegerv(pname, &value);
+ return WebGLGetInfo(static_cast<unsigned int>(value));
+}
+
+WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(GC3Denum pname)
+{
+ GC3Dfloat value[4] = {0};
+ m_context->getFloatv(pname, value);
+ unsigned length = 0;
+ switch (pname) {
+ case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
+ case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
+ case GraphicsContext3D::DEPTH_RANGE:
+ length = 2;
+ break;
+ case GraphicsContext3D::BLEND_COLOR:
+ case GraphicsContext3D::COLOR_CLEAR_VALUE:
+ length = 4;
+ break;
+ default:
+ notImplemented();
+ }
+ return WebGLGetInfo(Float32Array::create(value, length));
+}
+
+WebGLGetInfo WebGLRenderingContext::getWebGLIntArrayParameter(GC3Denum pname)
+{
+ GC3Dint value[4] = {0};
+ m_context->getIntegerv(pname, value);
+ unsigned length = 0;
+ switch (pname) {
+ case GraphicsContext3D::MAX_VIEWPORT_DIMS:
+ length = 2;
+ break;
+ case GraphicsContext3D::SCISSOR_BOX:
+ case GraphicsContext3D::VIEWPORT:
+ length = 4;
+ break;
+ default:
+ notImplemented();
+ }
+ return WebGLGetInfo(Int32Array::create(value, length));
+}
+
+void WebGLRenderingContext::checkTextureCompleteness(const char* functionName, bool prepareToDraw)
+{
+ bool resetActiveUnit = false;
+ WebGLTexture::TextureExtensionFlag extensions = static_cast<WebGLTexture::TextureExtensionFlag>((m_oesTextureFloatLinear ? WebGLTexture::TextureExtensionFloatLinearEnabled : 0) | (m_oesTextureHalfFloatLinear ? WebGLTexture::TextureExtensionHalfFloatLinearEnabled : 0));
+
+ for (unsigned ii = 0; ii < m_textureUnits.size(); ++ii) {
+ if ((m_textureUnits[ii].texture2DBinding && m_textureUnits[ii].texture2DBinding->needToUseBlackTexture(extensions))
+ || (m_textureUnits[ii].textureCubeMapBinding && m_textureUnits[ii].textureCubeMapBinding->needToUseBlackTexture(extensions))) {
+ if (ii != m_activeTextureUnit) {
+ m_context->activeTexture(ii);
+ resetActiveUnit = true;
+ } else if (resetActiveUnit) {
+ m_context->activeTexture(ii);
+ resetActiveUnit = false;
+ }
+ WebGLTexture* tex2D;
+ WebGLTexture* texCubeMap;
+ if (prepareToDraw) {
+ String msg(String("texture bound to texture unit ") + String::number(ii)
+ + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete',"
+ + " or it is a float/half-float type with linear filtering and without the relevant float/half-float linear extension enabled.");
+ printGLWarningToConsole(functionName, msg.utf8().data());
+ tex2D = m_blackTexture2D.get();
+ texCubeMap = m_blackTextureCubeMap.get();
+ } else {
+ tex2D = m_textureUnits[ii].texture2DBinding.get();
+ texCubeMap = m_textureUnits[ii].textureCubeMapBinding.get();
+ }
+ if (m_textureUnits[ii].texture2DBinding && m_textureUnits[ii].texture2DBinding->needToUseBlackTexture(extensions))
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(tex2D));
+ if (m_textureUnits[ii].textureCubeMapBinding && m_textureUnits[ii].textureCubeMapBinding->needToUseBlackTexture(extensions))
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
+ }
+ }
+ if (resetActiveUnit)
+ m_context->activeTexture(m_activeTextureUnit);
+}
+
+void WebGLRenderingContext::createFallbackBlackTextures1x1()
+{
+ unsigned char black[] = {0, 0, 0, 255};
+ m_blackTexture2D = createTexture();
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_blackTexture2D->object());
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
+ m_blackTextureCubeMap = createTexture();
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, m_blackTextureCubeMap->object());
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
+ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, 0);
+}
+
+bool WebGLRenderingContext::isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat,
+ GC3Denum colorBufferFormat)
+{
+ unsigned need = GraphicsContext3D::getChannelBitsByFormat(texInternalFormat);
+ unsigned have = GraphicsContext3D::getChannelBitsByFormat(colorBufferFormat);
+ return (need & have) == need;
+}
+
+GC3Denum WebGLRenderingContext::getBoundFramebufferColorFormat()
+{
+ if (m_framebufferBinding && m_framebufferBinding->object())
+ return m_framebufferBinding->getColorBufferFormat();
+ if (m_attributes.alpha)
+ return GraphicsContext3D::RGBA;
+ return GraphicsContext3D::RGB;
+}
+
+int WebGLRenderingContext::getBoundFramebufferWidth()
+{
+ if (m_framebufferBinding && m_framebufferBinding->object())
+ return m_framebufferBinding->getColorBufferWidth();
+ return m_drawingBuffer ? m_drawingBuffer->size().width() : m_context->getInternalFramebufferSize().width();
+}
+
+int WebGLRenderingContext::getBoundFramebufferHeight()
+{
+ if (m_framebufferBinding && m_framebufferBinding->object())
+ return m_framebufferBinding->getColorBufferHeight();
+ return m_drawingBuffer ? m_drawingBuffer->size().height() : m_context->getInternalFramebufferSize().height();
+}
+
+WebGLTexture* WebGLRenderingContext::validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap)
+{
+ WebGLTexture* texture = nullptr;
switch (target) {
case GraphicsContext3D::TEXTURE_2D:
- if (width > maxTextureSizeForLevel || height > maxTextureSizeForLevel) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range");
- return false;
- }
+ texture = m_textureUnits[m_activeTextureUnit].texture2DBinding.get();
break;
case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
@@ -694,38 +5023,60 @@ bool WebGLRenderingContext::validateTexFuncParameters(const char* functionName,
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (functionType != TexSubImage && width != height) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");
- return false;
+ if (!useSixEnumsForCubeMap) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
+ return nullptr;
}
- // No need to check height here. For texImage width == height.
- // For texSubImage that will be checked when checking yoffset + height is in range.
- if (width > maxTextureSizeForLevel) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range for cube map");
- return false;
+ texture = m_textureUnits[m_activeTextureUnit].textureCubeMapBinding.get();
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP:
+ if (useSixEnumsForCubeMap) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
+ return nullptr;
}
+ texture = m_textureUnits[m_activeTextureUnit].textureCubeMapBinding.get();
break;
default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
- return false;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
+ return nullptr;
}
+ if (!texture)
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no texture");
+ return texture;
+}
- if (format != internalformat) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format != internalformat");
+bool WebGLRenderingContext::validateLocationLength(const char* functionName, const String& string)
+{
+ const unsigned maxWebGLLocationLength = 256;
+ if (string.length() > maxWebGLLocationLength) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "location length > 256");
return false;
}
-
- if (border) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0");
+ return true;
+}
+
+bool WebGLRenderingContext::validateSize(const char* functionName, GC3Dint x, GC3Dint y)
+{
+ if (x < 0 || y < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "size < 0");
return false;
}
-
return true;
}
-bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level)
+bool WebGLRenderingContext::validateString(const char* functionName, const String& string)
+{
+ for (size_t i = 0; i < string.length(); ++i) {
+ if (!validateCharacter(string[i])) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "string not ASCII");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level)
{
- UNUSED_PARAM(internalformat);
switch (format) {
case GraphicsContext3D::ALPHA:
case GraphicsContext3D::LUMINANCE:
@@ -739,16 +5090,11 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionNam
break;
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled");
return false;
- case Extensions3D::SRGB_EXT:
- case Extensions3D::SRGB_ALPHA_EXT:
default:
- if ((format == Extensions3D::SRGB_EXT || format == Extensions3D::SRGB_ALPHA_EXT)
- && m_extsRGB)
- break;
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format");
return false;
}
-
+
switch (type) {
case GraphicsContext3D::UNSIGNED_BYTE:
case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
@@ -776,7 +5122,7 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionNam
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
return false;
}
-
+
// Verify that the combination of format and type is supported.
switch (format) {
case GraphicsContext3D::ALPHA:
@@ -790,7 +5136,6 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionNam
}
break;
case GraphicsContext3D::RGB:
- case Extensions3D::SRGB_EXT:
if (type != GraphicsContext3D::UNSIGNED_BYTE
&& type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5
&& type != GraphicsContext3D::FLOAT
@@ -800,7 +5145,6 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionNam
}
break;
case GraphicsContext3D::RGBA:
- case Extensions3D::SRGB_ALPHA_EXT:
if (type != GraphicsContext3D::UNSIGNED_BYTE
&& type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
&& type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1
@@ -821,8 +5165,8 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionNam
return false;
}
if (level > 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
- return false;
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
+ return false;
}
break;
case GraphicsContext3D::DEPTH_STENCIL:
@@ -835,18 +5179,113 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionNam
return false;
}
if (level > 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format");
- return false;
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format");
+ return false;
}
break;
default:
ASSERT_NOT_REACHED();
}
-
+
+ return true;
+}
+
+bool WebGLRenderingContext::validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level)
+{
+ if (level < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level < 0");
+ return false;
+ }
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ if (level >= m_maxTextureLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level out of range");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (level >= m_maxCubeMapTextureLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level out of range");
+ return false;
+ }
+ break;
+ }
+ // This function only checks if level is legal, so we return true and don't
+ // generate INVALID_ENUM if target is illegal.
+ return true;
+}
+
+bool WebGLRenderingContext::validateTexFuncParameters(const char* functionName,
+ TexFuncValidationFunctionType functionType,
+ GC3Denum target, GC3Dint level,
+ GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type)
+{
+ // We absolutely have to validate the format and type combination.
+ // The texImage2D entry points taking HTMLImage, etc. will produce
+ // temporary data based on this combination, so it must be legal.
+ if (!validateTexFuncFormatAndType(functionName, format, type, level) || !validateTexFuncLevel(functionName, target, level))
+ return false;
+
+ if (width < 0 || height < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
+ return false;
+ }
+
+ GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ if (width > maxTextureSizeForLevel || height > maxTextureSizeForLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (functionType != TexSubImage2D && width != height) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");
+ return false;
+ }
+ // No need to check height here. For texImage width == height.
+ // For texSubImage that will be checked when checking yoffset + height is in range.
+ if (width > maxTextureSizeForLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range for cube map");
+ return false;
+ }
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
+ return false;
+ }
+
+ if (format != internalformat) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format != internalformat");
+ return false;
+ }
+
+ if (border) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0");
+ return false;
+ }
+
return true;
}
-bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, NullDisposition disposition)
+bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GC3Dint level,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type,
+ ArrayBufferView* pixels,
+ NullDisposition disposition)
{
if (!pixels) {
if (disposition == NullAllowed)
@@ -855,11 +5294,11 @@ bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GC3Din
return false;
}
- if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level))
+ if (!validateTexFuncFormatAndType(functionName, format, type, level))
return false;
if (!validateSettableTexFormat(functionName, format))
return false;
-
+
switch (type) {
case GraphicsContext3D::UNSIGNED_BYTE:
if (pixels->getType() != JSC::TypeUint8) {
@@ -892,8 +5331,8 @@ bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GC3Din
default:
ASSERT_NOT_REACHED();
}
-
- unsigned totalBytesRequired;
+
+ unsigned int totalBytesRequired;
GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
if (error != GraphicsContext3D::NO_ERROR) {
synthesizeGLError(error, functionName, "invalid texture dimensions");
@@ -901,11 +5340,11 @@ bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GC3Din
}
if (pixels->byteLength() < totalBytesRequired) {
if (m_unpackAlignment != 1) {
- m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
- if (pixels->byteLength() == totalBytesRequired) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
- return false;
- }
+ error = m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
+ if (pixels->byteLength() == totalBytesRequired) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
+ return false;
+ }
}
synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
return false;
@@ -913,328 +5352,222 @@ bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GC3Din
return true;
}
-WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& ec)
+bool WebGLRenderingContext::validateCompressedTexFormat(GC3Denum format)
{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return WebGLGetInfo();
- const int intZero = 0;
- switch (pname) {
- case GraphicsContext3D::ACTIVE_TEXTURE:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
- return getWebGLFloatArrayParameter(pname);
- case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
- return getWebGLFloatArrayParameter(pname);
- case GraphicsContext3D::ALPHA_BITS:
- return getIntParameter(pname);
- case GraphicsContext3D::ARRAY_BUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
- case GraphicsContext3D::BLEND:
- return getBooleanParameter(pname);
- case GraphicsContext3D::BLEND_COLOR:
- return getWebGLFloatArrayParameter(pname);
- case GraphicsContext3D::BLEND_DST_ALPHA:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::BLEND_DST_RGB:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::BLEND_EQUATION_ALPHA:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::BLEND_EQUATION_RGB:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::BLEND_SRC_ALPHA:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::BLEND_SRC_RGB:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::BLUE_BITS:
- return getIntParameter(pname);
- case GraphicsContext3D::COLOR_CLEAR_VALUE:
- return getWebGLFloatArrayParameter(pname);
- case GraphicsContext3D::COLOR_WRITEMASK:
- return getBooleanArrayParameter(pname);
- case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS:
- return WebGLGetInfo(Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size()).release());
- case GraphicsContext3D::CULL_FACE:
- return getBooleanParameter(pname);
- case GraphicsContext3D::CULL_FACE_MODE:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::CURRENT_PROGRAM:
- return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
- case GraphicsContext3D::DEPTH_BITS:
- if (!m_framebufferBinding && !m_attributes.depth)
- return WebGLGetInfo(intZero);
- return getIntParameter(pname);
- case GraphicsContext3D::DEPTH_CLEAR_VALUE:
- return getFloatParameter(pname);
- case GraphicsContext3D::DEPTH_FUNC:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::DEPTH_RANGE:
- return getWebGLFloatArrayParameter(pname);
- case GraphicsContext3D::DEPTH_TEST:
- return getBooleanParameter(pname);
- case GraphicsContext3D::DEPTH_WRITEMASK:
- return getBooleanParameter(pname);
- case GraphicsContext3D::DITHER:
- return getBooleanParameter(pname);
- case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundVertexArrayObject->getElementArrayBuffer()));
- case GraphicsContext3D::FRAMEBUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
- case GraphicsContext3D::FRONT_FACE:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::GENERATE_MIPMAP_HINT:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::GREEN_BITS:
- return getIntParameter(pname);
- case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT:
- return getIntParameter(pname);
- case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE:
- return getIntParameter(pname);
- case GraphicsContext3D::LINE_WIDTH:
- return getFloatParameter(pname);
- case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_RENDERBUFFER_SIZE:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_TEXTURE_SIZE:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VARYING_VECTORS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VERTEX_ATTRIBS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS:
- return getIntParameter(pname);
- case GraphicsContext3D::MAX_VIEWPORT_DIMS:
- return getWebGLIntArrayParameter(pname);
- case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
- return getIntParameter(pname);
- case GraphicsContext3D::PACK_ALIGNMENT:
- return getIntParameter(pname);
- case GraphicsContext3D::POLYGON_OFFSET_FACTOR:
- return getFloatParameter(pname);
- case GraphicsContext3D::POLYGON_OFFSET_FILL:
- return getBooleanParameter(pname);
- case GraphicsContext3D::POLYGON_OFFSET_UNITS:
- return getFloatParameter(pname);
- case GraphicsContext3D::RED_BITS:
- return getIntParameter(pname);
- case GraphicsContext3D::RENDERBUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
- case GraphicsContext3D::RENDERER:
- return WebGLGetInfo(String("WebKit WebGL"));
- case GraphicsContext3D::SAMPLE_BUFFERS:
- return getIntParameter(pname);
- case GraphicsContext3D::SAMPLE_COVERAGE_INVERT:
- return getBooleanParameter(pname);
- case GraphicsContext3D::SAMPLE_COVERAGE_VALUE:
- return getFloatParameter(pname);
- case GraphicsContext3D::SAMPLES:
- return getIntParameter(pname);
- case GraphicsContext3D::SCISSOR_BOX:
- return getWebGLIntArrayParameter(pname);
- case GraphicsContext3D::SCISSOR_TEST:
- return getBooleanParameter(pname);
- case GraphicsContext3D::SHADING_LANGUAGE_VERSION:
- return WebGLGetInfo("WebGL GLSL ES 1.0 (" + m_context->getString(GraphicsContext3D::SHADING_LANGUAGE_VERSION) + ")");
- case GraphicsContext3D::STENCIL_BACK_FAIL:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_BACK_FUNC:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_BACK_REF:
- return getIntParameter(pname);
- case GraphicsContext3D::STENCIL_BACK_VALUE_MASK:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_BACK_WRITEMASK:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_BITS:
- if (!m_framebufferBinding && !m_attributes.stencil)
- return WebGLGetInfo(intZero);
- return getIntParameter(pname);
- case GraphicsContext3D::STENCIL_CLEAR_VALUE:
- return getIntParameter(pname);
- case GraphicsContext3D::STENCIL_FAIL:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_FUNC:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_REF:
- return getIntParameter(pname);
- case GraphicsContext3D::STENCIL_TEST:
- return getBooleanParameter(pname);
- case GraphicsContext3D::STENCIL_VALUE_MASK:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::STENCIL_WRITEMASK:
- return getUnsignedIntParameter(pname);
- case GraphicsContext3D::SUBPIXEL_BITS:
- return getIntParameter(pname);
- case GraphicsContext3D::TEXTURE_BINDING_2D:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].texture2DBinding));
- case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].textureCubeMapBinding));
- case GraphicsContext3D::UNPACK_ALIGNMENT:
- return getIntParameter(pname);
- case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
- return WebGLGetInfo(m_unpackFlipY);
- case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
- return WebGLGetInfo(m_unpackPremultiplyAlpha);
- case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL:
- return WebGLGetInfo(m_unpackColorspaceConversion);
- case GraphicsContext3D::VENDOR:
- return WebGLGetInfo(String("WebKit"));
- case GraphicsContext3D::VERSION:
- return WebGLGetInfo("WebGL 1.0 (" + m_context->getString(GraphicsContext3D::VERSION) + ")");
- case GraphicsContext3D::VIEWPORT:
- return getWebGLIntArrayParameter(pname);
- case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
- if (m_oesStandardDerivatives)
- return getUnsignedIntParameter(Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled");
- return WebGLGetInfo();
- case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
- if (m_webglDebugRendererInfo)
- return WebGLGetInfo(m_context->getString(GraphicsContext3D::RENDERER));
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
- return WebGLGetInfo();
- case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
- if (m_webglDebugRendererInfo)
- return WebGLGetInfo(m_context->getString(GraphicsContext3D::VENDOR));
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
- return WebGLGetInfo();
- case Extensions3D::VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object
- if (m_oesVertexArrayObject) {
- if (!m_boundVertexArrayObject->isDefaultObject())
- return WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES>(static_cast<WebGLVertexArrayObjectOES*>(m_boundVertexArrayObject.get())));
- return WebGLGetInfo();
+ return m_compressedTextureFormats.contains(format);
+}
+
+bool WebGLRenderingContext::validateCompressedTexFuncData(const char* functionName,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, ArrayBufferView* pixels)
+{
+ if (!pixels) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels");
+ return false;
+ }
+ if (width < 0 || height < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
+ return false;
+ }
+
+ unsigned int bytesRequired = 0;
+
+ switch (format) {
+ case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_ATC_RGB_AMD:
+ {
+ const int kBlockSize = 8;
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
+ int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
+ bytesRequired = numBlocksAcross * numBlocksDown * kBlockSize;
}
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled");
- return WebGLGetInfo();
- case Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
- if (m_extTextureFilterAnisotropic)
- return getUnsignedIntParameter(Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT);
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
- return WebGLGetInfo();
- case Extensions3D::MAX_COLOR_ATTACHMENTS_EXT: // EXT_draw_buffers BEGIN
- if (m_webglDrawBuffers)
- return WebGLGetInfo(getMaxColorAttachments());
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
- return WebGLGetInfo();
- case Extensions3D::MAX_DRAW_BUFFERS_EXT:
- if (m_webglDrawBuffers)
- return WebGLGetInfo(getMaxDrawBuffers());
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
- return WebGLGetInfo();
+ break;
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case Extensions3D::COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
+ case Extensions3D::COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
+ {
+ const int kBlockSize = 16;
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
+ int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
+ bytesRequired = numBlocksAcross * numBlocksDown * kBlockSize;
+ }
+ break;
+ case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ {
+ const int kBlockSize = 8;
+ const int kBlockWidth = 8;
+ const int kBlockHeight = 8;
+ bytesRequired = (std::max(width, kBlockWidth) * std::max(height, kBlockHeight) * 4 + 7) / kBlockSize;
+ }
+ break;
+ case Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ case Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
+ {
+ const int kBlockSize = 8;
+ const int kBlockWidth = 16;
+ const int kBlockHeight = 8;
+ bytesRequired = (std::max(width, kBlockWidth) * std::max(height, kBlockHeight) * 2 + 7) / kBlockSize;
+ }
+ break;
default:
- if (m_webglDrawBuffers
- && pname >= Extensions3D::DRAW_BUFFER0_EXT
- && pname < static_cast<GC3Denum>(Extensions3D::DRAW_BUFFER0_EXT + getMaxDrawBuffers())) {
- GC3Dint value = GraphicsContext3D::NONE;
- if (m_framebufferBinding)
- value = m_framebufferBinding->getDrawBuffer(pname);
- else // emulated backbuffer
- value = m_backDrawBuffer;
- return WebGLGetInfo(value);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format");
+ return false;
+ }
+
+ if (pixels->byteLength() != bytesRequired) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "length of ArrayBufferView is not correct for dimensions");
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContext::validateCompressedTexDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format)
+{
+ switch (format) {
+ case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT: {
+ const GC3Dsizei kBlockWidth = 4;
+ const GC3Dsizei kBlockHeight = 4;
+ const GC3Dint maxTextureSize = target ? m_maxTextureSize : m_maxCubeMapTextureSize;
+ const GC3Dsizei maxCompressedDimension = maxTextureSize >> level;
+ bool widthValid = (level && width == 1) || (level && width == 2) || (!(width % kBlockWidth) && width <= maxCompressedDimension);
+ bool heightValid = (level && height == 1) || (level && height == 2) || (!(height % kBlockHeight) && height <= maxCompressedDimension);
+ if (!widthValid || !heightValid) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "width or height invalid for level");
+ return false;
}
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name");
- return WebGLGetInfo();
+ return true;
+ }
+ default:
+ return false;
}
}
-GC3Dint WebGLRenderingContext::getMaxDrawBuffers()
+bool WebGLRenderingContext::validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture* tex)
{
- if (!supportsDrawBuffers())
- return 0;
- if (!m_maxDrawBuffers)
- m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &m_maxDrawBuffers);
- if (!m_maxColorAttachments)
- m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
- // WEBGL_draw_buffers requires MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
- return std::min(m_maxDrawBuffers, m_maxColorAttachments);
+ if (xoffset < 0 || yoffset < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "xoffset or yoffset < 0");
+ return false;
+ }
+
+ switch (format) {
+ case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT: {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "xoffset or yoffset not multiple of 4");
+ return false;
+ }
+ if (width - xoffset > tex->getWidth(target, level)
+ || height - yoffset > tex->getHeight(target, level)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "dimensions out of range");
+ return false;
+ }
+ return validateCompressedTexDimensions(functionName, target, level, width, height, format);
+ }
+ default:
+ return false;
+ }
}
-GC3Dint WebGLRenderingContext::getMaxColorAttachments()
+bool WebGLRenderingContext::validateDrawMode(const char* functionName, GC3Denum mode)
{
- if (!supportsDrawBuffers())
- return 0;
- if (!m_maxColorAttachments)
- m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
- return m_maxColorAttachments;
+ switch (mode) {
+ case GraphicsContext3D::POINTS:
+ case GraphicsContext3D::LINE_STRIP:
+ case GraphicsContext3D::LINE_LOOP:
+ case GraphicsContext3D::LINES:
+ case GraphicsContext3D::TRIANGLE_STRIP:
+ case GraphicsContext3D::TRIANGLE_FAN:
+ case GraphicsContext3D::TRIANGLES:
+ return true;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid draw mode");
+ return false;
+ }
}
-
-bool WebGLRenderingContext::validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired)
+
+bool WebGLRenderingContext::validateStencilSettings(const char* functionName)
{
- // Performs conservative validation by caching a maximum index of
- // the given type per element array buffer. If all of the bound
- // array buffers have enough elements to satisfy that maximum
- // index, skips the expensive per-draw-call iteration in
- // validateIndexArrayPrecise.
-
- RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
-
- if (!elementArrayBuffer)
+ if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "front and back stencils settings do not match");
return false;
-
- GC3Dsizeiptr numElements = elementArrayBuffer->byteLength();
- // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
- if (!numElements)
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateStencilFunc(const char* functionName, GC3Denum func)
+{
+ switch (func) {
+ case GraphicsContext3D::NEVER:
+ case GraphicsContext3D::LESS:
+ case GraphicsContext3D::LEQUAL:
+ case GraphicsContext3D::GREATER:
+ case GraphicsContext3D::GEQUAL:
+ case GraphicsContext3D::EQUAL:
+ case GraphicsContext3D::NOTEQUAL:
+ case GraphicsContext3D::ALWAYS:
+ return true;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid function");
return false;
- const ArrayBuffer* buffer = elementArrayBuffer->elementArrayBuffer();
- ASSERT(buffer);
-
- int maxIndex = elementArrayBuffer->getCachedMaxIndex(type);
- if (maxIndex < 0) {
- // Compute the maximum index in the entire buffer for the given type of index.
- switch (type) {
- case GraphicsContext3D::UNSIGNED_BYTE: {
- const GC3Dubyte* p = static_cast<const GC3Dubyte*>(buffer->data());
- for (GC3Dsizeiptr i = 0; i < numElements; i++)
- maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
- break;
- }
- case GraphicsContext3D::UNSIGNED_SHORT: {
- numElements /= sizeof(GC3Dushort);
- const GC3Dushort* p = static_cast<const GC3Dushort*>(buffer->data());
- for (GC3Dsizeiptr i = 0; i < numElements; i++)
- maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
- break;
- }
- case GraphicsContext3D::UNSIGNED_INT: {
- if (!m_oesElementIndexUint)
- return false;
- numElements /= sizeof(GC3Duint);
- const GC3Duint* p = static_cast<const GC3Duint*>(buffer->data());
- for (GC3Dsizeiptr i = 0; i < numElements; i++)
- maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
- break;
- }
- default:
- return false;
}
- elementArrayBuffer->setCachedMaxIndex(type, maxIndex);
+}
+
+void WebGLRenderingContext::printGLErrorToConsole(const String& message)
+{
+ if (!m_numGLErrorsToConsoleAllowed)
+ return;
+
+ --m_numGLErrorsToConsoleAllowed;
+ printWarningToConsole(message);
+
+ if (!m_numGLErrorsToConsoleAllowed)
+ printWarningToConsole("WebGL: too many errors, no more errors will be reported to the console for this context.");
+}
+
+void WebGLRenderingContext::printWarningToConsole(const String& message)
+{
+ if (!canvas())
+ return;
+ canvas()->document().addConsoleMessage(RenderingMessageSource, WarningMessageLevel, message);
+}
+
+bool WebGLRenderingContext::validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment)
+{
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
+ return false;
}
-
- if (maxIndex >= 0) {
- // The number of required elements is one more than the maximum
- // index that will be accessed.
- numElementsRequired = maxIndex + 1;
- return true;
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ break;
+ default:
+ if (m_extDrawBuffers
+ && attachment > GraphicsContext3D::COLOR_ATTACHMENT0
+ && attachment < static_cast<GC3Denum>(GraphicsContext3D::COLOR_ATTACHMENT0 + getMaxColorAttachments()))
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid attachment");
+ return false;
}
-
- return false;
+ return true;
}
bool WebGLRenderingContext::validateBlendEquation(const char* functionName, GC3Denum mode)
@@ -1243,20 +5576,25 @@ bool WebGLRenderingContext::validateBlendEquation(const char* functionName, GC3D
case GraphicsContext3D::FUNC_ADD:
case GraphicsContext3D::FUNC_SUBTRACT:
case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
- case Extensions3D::MIN_EXT:
- case Extensions3D::MAX_EXT:
- if ((mode == Extensions3D::MIN_EXT || mode == Extensions3D::MAX_EXT) && !m_extBlendMinMax) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid mode");
- return false;
- }
return true;
- break;
default:
synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid mode");
return false;
}
}
+bool WebGLRenderingContext::validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst)
+{
+ if (((src == GraphicsContext3D::CONSTANT_COLOR || src == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
+ && (dst == GraphicsContext3D::CONSTANT_ALPHA || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))
+ || ((dst == GraphicsContext3D::CONSTANT_COLOR || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
+ && (src == GraphicsContext3D::CONSTANT_ALPHA || src == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "incompatible src and dst");
+ return false;
+ }
+ return true;
+}
+
bool WebGLRenderingContext::validateCapability(const char* functionName, GC3Denum cap)
{
switch (cap) {
@@ -1276,6 +5614,628 @@ bool WebGLRenderingContext::validateCapability(const char* functionName, GC3Denu
}
}
+bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei requiredMinSize)
+{
+ if (!v) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei requiredMinSize)
+{
+ if (!v) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
+{
+ return validateUniformMatrixParameters(functionName, location, false, v, size, requiredMinSize);
+}
+
+bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, GC3Dsizei requiredMinSize)
+{
+ if (!v) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ return validateUniformMatrixParameters(functionName, location, transpose, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
+{
+ if (!location)
+ return false;
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "location is not from current program");
+ return false;
+ }
+ if (!v) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ if (transpose) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "transpose not FALSE");
+ return false;
+ }
+ if (size < requiredMinSize || (size % requiredMinSize)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid size");
+ return false;
+ }
+ return true;
+}
+
+WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage)
+{
+ WebGLBuffer* buffer = 0;
+ switch (target) {
+ case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
+ buffer = m_boundVertexArrayObject->getElementArrayBuffer().get();
+ break;
+ case GraphicsContext3D::ARRAY_BUFFER:
+ buffer = m_boundArrayBuffer.get();
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
+ return 0;
+ }
+ if (!buffer) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no buffer");
+ return 0;
+ }
+ switch (usage) {
+ case GraphicsContext3D::STREAM_DRAW:
+ case GraphicsContext3D::STATIC_DRAW:
+ case GraphicsContext3D::DYNAMIC_DRAW:
+ return buffer;
+ }
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid usage");
+ return 0;
+}
+
+bool WebGLRenderingContext::validateHTMLImageElement(const char* functionName, HTMLImageElement* image, ExceptionCode& ec)
+{
+ if (!image || !image->cachedImage()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no image");
+ return false;
+ }
+ const URL& url = image->cachedImage()->response().url();
+ if (url.isNull() || url.isEmpty() || !url.isValid()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid image");
+ return false;
+ }
+ if (wouldTaintOrigin(image)) {
+ ec = SECURITY_ERR;
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement* canvas, ExceptionCode& ec)
+{
+ if (!canvas || !canvas->buffer()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no canvas");
+ return false;
+ }
+ if (wouldTaintOrigin(canvas)) {
+ ec = SECURITY_ERR;
+ return false;
+ }
+ return true;
+}
+
+#if ENABLE(VIDEO)
+bool WebGLRenderingContext::validateHTMLVideoElement(const char* functionName, HTMLVideoElement* video, ExceptionCode& ec)
+{
+ if (!video || !video->videoWidth() || !video->videoHeight()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no video");
+ return false;
+ }
+ if (wouldTaintOrigin(video)) {
+ ec = SECURITY_ERR;
+ return false;
+ }
+ return true;
+}
+#endif
+
+void WebGLRenderingContext::vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
+{
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "index out of range");
+ return;
+ }
+ // In GL, we skip setting vertexAttrib0 values.
+ if (index || isGLES2Compliant()) {
+ switch (expectedSize) {
+ case 1:
+ m_context->vertexAttrib1f(index, v0);
+ break;
+ case 2:
+ m_context->vertexAttrib2f(index, v0, v1);
+ break;
+ case 3:
+ m_context->vertexAttrib3f(index, v0, v1, v2);
+ break;
+ case 4:
+ m_context->vertexAttrib4f(index, v0, v1, v2, v3);
+ break;
+ }
+ cleanupAfterGraphicsCall(false);
+ }
+ VertexAttribValue& attribValue = m_vertexAttribValue[index];
+ attribValue.value[0] = v0;
+ attribValue.value[1] = v1;
+ attribValue.value[2] = v2;
+ attribValue.value[3] = v3;
+}
+
+void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array* v, GC3Dsizei expectedSize)
+{
+ if (isContextLost())
+ return;
+ if (!v) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
+ return;
+ }
+ vertexAttribfvImpl(functionName, index, v->data(), v->length(), expectedSize);
+}
+
+void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat* v, GC3Dsizei size, GC3Dsizei expectedSize)
+{
+ if (isContextLost())
+ return;
+ if (!v) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
+ return;
+ }
+ if (size < expectedSize) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid size");
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "index out of range");
+ return;
+ }
+ // In GL, we skip setting vertexAttrib0 values.
+ if (index || isGLES2Compliant()) {
+ switch (expectedSize) {
+ case 1:
+ m_context->vertexAttrib1fv(index, v);
+ break;
+ case 2:
+ m_context->vertexAttrib2fv(index, v);
+ break;
+ case 3:
+ m_context->vertexAttrib3fv(index, v);
+ break;
+ case 4:
+ m_context->vertexAttrib4fv(index, v);
+ break;
+ }
+ cleanupAfterGraphicsCall(false);
+ }
+ VertexAttribValue& attribValue = m_vertexAttribValue[index];
+ attribValue.initValue();
+ for (int ii = 0; ii < expectedSize; ++ii)
+ attribValue.value[ii] = v[ii];
+}
+
+void WebGLRenderingContext::initVertexAttrib0()
+{
+ WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0);
+
+ m_vertexAttrib0Buffer = createBuffer();
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer->object());
+ m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, 0, GraphicsContext3D::DYNAMIC_DRAW);
+ m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, false, 0, 0);
+ state.bufferBinding = m_vertexAttrib0Buffer;
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0);
+ m_context->enableVertexAttribArray(0);
+ m_vertexAttrib0BufferSize = 0;
+ m_vertexAttrib0BufferValue[0] = 0.0f;
+ m_vertexAttrib0BufferValue[1] = 0.0f;
+ m_vertexAttrib0BufferValue[2] = 0.0f;
+ m_vertexAttrib0BufferValue[3] = 1.0f;
+ m_forceAttrib0BufferRefill = false;
+ m_vertexAttrib0UsedBefore = false;
+}
+
+bool WebGLRenderingContext::simulateVertexAttrib0(GC3Dsizei numVertex)
+{
+ const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0);
+ const VertexAttribValue& attribValue = m_vertexAttribValue[0];
+ if (!m_currentProgram)
+ return false;
+ bool usingVertexAttrib0 = m_currentProgram->isUsingVertexAttrib0();
+ if (usingVertexAttrib0)
+ m_vertexAttrib0UsedBefore = true;
+ if (state.enabled && usingVertexAttrib0)
+ return false;
+ if (!usingVertexAttrib0 && !m_vertexAttrib0UsedBefore)
+ return false;
+ m_vertexAttrib0UsedBefore = true;
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer->object());
+ GC3Dsizeiptr bufferDataSize = (numVertex + 1) * 4 * sizeof(GC3Dfloat);
+ if (bufferDataSize > m_vertexAttrib0BufferSize) {
+ m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, bufferDataSize, 0, GraphicsContext3D::DYNAMIC_DRAW);
+ m_vertexAttrib0BufferSize = bufferDataSize;
+ m_forceAttrib0BufferRefill = true;
+ }
+ if (usingVertexAttrib0
+ && (m_forceAttrib0BufferRefill
+ || attribValue.value[0] != m_vertexAttrib0BufferValue[0]
+ || attribValue.value[1] != m_vertexAttrib0BufferValue[1]
+ || attribValue.value[2] != m_vertexAttrib0BufferValue[2]
+ || attribValue.value[3] != m_vertexAttrib0BufferValue[3])) {
+ auto bufferData = std::make_unique<GC3Dfloat[]>((numVertex + 1) * 4);
+ for (GC3Dsizei ii = 0; ii < numVertex + 1; ++ii) {
+ bufferData[ii * 4] = attribValue.value[0];
+ bufferData[ii * 4 + 1] = attribValue.value[1];
+ bufferData[ii * 4 + 2] = attribValue.value[2];
+ bufferData[ii * 4 + 3] = attribValue.value[3];
+ }
+ m_vertexAttrib0BufferValue[0] = attribValue.value[0];
+ m_vertexAttrib0BufferValue[1] = attribValue.value[1];
+ m_vertexAttrib0BufferValue[2] = attribValue.value[2];
+ m_vertexAttrib0BufferValue[3] = attribValue.value[3];
+ m_forceAttrib0BufferRefill = false;
+ m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, 0, bufferDataSize, bufferData.get());
+ }
+ m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, 0, 0, 0);
+ return true;
+}
+
+void WebGLRenderingContext::restoreStatesAfterVertexAttrib0Simulation()
+{
+ const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0);
+ if (state.bufferBinding != m_vertexAttrib0Buffer) {
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(state.bufferBinding.get()));
+ m_context->vertexAttribPointer(0, state.size, state.type, state.normalized, state.originalStride, state.offset);
+ }
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundArrayBuffer.get()));
+}
+
+void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext>*)
+{
+ RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, "");
+ canvas()->dispatchEvent(event);
+ m_restoreAllowed = event->defaultPrevented();
+ if (m_contextLostMode == RealLostContext && m_restoreAllowed)
+ m_restoreTimer.startOneShot(0);
+}
+
+void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*)
+{
+ ASSERT(m_contextLost);
+ if (!m_contextLost)
+ return;
+
+ // The rendering context is not restored unless the default behavior of the
+ // webglcontextlost event was prevented earlier.
+ //
+ // Because of the way m_restoreTimer is set up for real vs. synthetic lost
+ // context events, we don't have to worry about this test short-circuiting
+ // the retry loop for real context lost events.
+ if (!m_restoreAllowed)
+ return;
+
+ int contextLostReason = m_context->getExtensions()->getGraphicsResetStatusARB();
+
+ switch (contextLostReason) {
+ case GraphicsContext3D::NO_ERROR:
+ // The GraphicsContext3D implementation might not fully
+ // support GL_ARB_robustness semantics yet. Alternatively, the
+ // WEBGL_lose_context extension might have been used to force
+ // a lost context.
+ break;
+ case Extensions3D::GUILTY_CONTEXT_RESET_ARB:
+ // The rendering context is not restored if this context was
+ // guilty of causing the graphics reset.
+ printWarningToConsole("WARNING: WebGL content on the page caused the graphics card to reset; not restoring the context");
+ return;
+ case Extensions3D::INNOCENT_CONTEXT_RESET_ARB:
+ // Always allow the context to be restored.
+ break;
+ case Extensions3D::UNKNOWN_CONTEXT_RESET_ARB:
+ // Warn. Ideally, prompt the user telling them that WebGL
+ // content on the page might have caused the graphics card to
+ // reset and ask them whether they want to continue running
+ // the content. Only if they say "yes" should we start
+ // attempting to restore the context.
+ printWarningToConsole("WARNING: WebGL content on the page might have caused the graphics card to reset");
+ break;
+ }
+
+ Frame* frame = canvas()->document().frame();
+ if (!frame)
+ return;
+
+ if (!frame->loader().client().allowWebGL(frame->settings().webGLEnabled()))
+ return;
+
+ FrameView* view = frame->view();
+ if (!view)
+ return;
+ ScrollView* root = view->root();
+ if (!root)
+ return;
+ HostWindow* hostWindow = root->hostWindow();
+ if (!hostWindow)
+ return;
+
+ RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, hostWindow));
+ if (!context) {
+ if (m_contextLostMode == RealLostContext)
+ m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
+ else
+ // This likely shouldn't happen but is the best way to report it to the WebGL app.
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "", "error restoring context");
+ return;
+ }
+
+ // Construct a new drawing buffer with the new GraphicsContext3D.
+ if (m_drawingBuffer) {
+ m_drawingBuffer->discardResources();
+ DrawingBuffer::PreserveDrawingBuffer preserve = m_attributes.preserveDrawingBuffer ? DrawingBuffer::Preserve : DrawingBuffer::Discard;
+ DrawingBuffer::AlphaRequirement alpha = m_attributes.alpha ? DrawingBuffer::Alpha : DrawingBuffer::Opaque;
+ m_drawingBuffer = DrawingBuffer::create(context.get(), m_drawingBuffer->size(), preserve, alpha);
+ m_drawingBuffer->bind();
+ }
+
+ m_context = context;
+ m_contextLost = false;
+ setupFlags();
+ initializeNewContext();
+ canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, false, true, ""));
+}
+
+String WebGLRenderingContext::ensureNotNull(const String& text) const
+{
+ if (text.isNull())
+ return WTF::emptyString();
+ return text;
+}
+
+WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache(int capacity)
+ : m_buffers(std::make_unique<std::unique_ptr<ImageBuffer>[]>(capacity))
+ , m_capacity(capacity)
+{
+}
+
+ImageBuffer* WebGLRenderingContext::LRUImageBufferCache::imageBuffer(const IntSize& size)
+{
+ int i;
+ for (i = 0; i < m_capacity; ++i) {
+ ImageBuffer* buf = m_buffers[i].get();
+ if (!buf)
+ break;
+ if (buf->logicalSize() != size)
+ continue;
+ bubbleToFront(i);
+ return buf;
+ }
+
+ std::unique_ptr<ImageBuffer> temp = ImageBuffer::create(size, 1);
+ if (!temp)
+ return 0;
+ i = std::min(m_capacity - 1, i);
+ m_buffers[i] = std::move(temp);
+
+ ImageBuffer* buf = m_buffers[i].get();
+ bubbleToFront(i);
+ return buf;
+}
+
+void WebGLRenderingContext::LRUImageBufferCache::bubbleToFront(int idx)
+{
+ for (int i = idx; i > 0; --i)
+ m_buffers[i].swap(m_buffers[i-1]);
+}
+
+namespace {
+
+ String GetErrorString(GC3Denum error)
+ {
+ switch (error) {
+ case GraphicsContext3D::INVALID_ENUM:
+ return "INVALID_ENUM";
+ case GraphicsContext3D::INVALID_VALUE:
+ return "INVALID_VALUE";
+ case GraphicsContext3D::INVALID_OPERATION:
+ return "INVALID_OPERATION";
+ case GraphicsContext3D::OUT_OF_MEMORY:
+ return "OUT_OF_MEMORY";
+ case GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION:
+ return "INVALID_FRAMEBUFFER_OPERATION";
+ case GraphicsContext3D::CONTEXT_LOST_WEBGL:
+ return "CONTEXT_LOST_WEBGL";
+ default:
+ return String::format("WebGL ERROR(%04x)", error);
+ }
+ }
+
+} // namespace anonymous
+
+void WebGLRenderingContext::synthesizeGLError(GC3Denum error, const char* functionName, const char* description, ConsoleDisplayPreference display)
+{
+ if (m_synthesizedErrorsToConsole && display == DisplayInConsole) {
+ String str = String("WebGL: ") + GetErrorString(error) + ": " + String(functionName) + ": " + String(description);
+ printGLErrorToConsole(str);
+ }
+ m_context->synthesizeGLError(error);
+}
+
+
+void WebGLRenderingContext::printGLWarningToConsole(const char* functionName, const char* description)
+{
+ if (m_synthesizedErrorsToConsole) {
+ String str = String("WebGL: ") + String(functionName) + ": " + String(description);
+ printGLErrorToConsole(str);
+ }
+}
+
+void WebGLRenderingContext::applyStencilTest()
+{
+ bool haveStencilBuffer = false;
+
+ if (m_framebufferBinding)
+ haveStencilBuffer = m_framebufferBinding->hasStencilBuffer();
+ else {
+ RefPtr<WebGLContextAttributes> attributes = getContextAttributes();
+ haveStencilBuffer = attributes->stencil();
+ }
+ enableOrDisable(GraphicsContext3D::STENCIL_TEST,
+ m_stencilEnabled && haveStencilBuffer);
+}
+
+void WebGLRenderingContext::enableOrDisable(GC3Denum capability, bool enable)
+{
+ if (enable)
+ m_context->enable(capability);
+ else
+ m_context->disable(capability);
+}
+
+IntSize WebGLRenderingContext::clampedCanvasSize()
+{
+ return IntSize(clamp(canvas()->width(), 1, m_maxViewportDims[0]),
+ clamp(canvas()->height(), 1, m_maxViewportDims[1]));
+}
+
+GC3Dint WebGLRenderingContext::getMaxDrawBuffers()
+{
+ if (!supportsDrawBuffers())
+ return 0;
+ if (!m_maxDrawBuffers)
+ m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &m_maxDrawBuffers);
+ if (!m_maxColorAttachments)
+ m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
+ // WEBGL_draw_buffers requires MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
+ return std::min(m_maxDrawBuffers, m_maxColorAttachments);
+}
+
+GC3Dint WebGLRenderingContext::getMaxColorAttachments()
+{
+ if (!supportsDrawBuffers())
+ return 0;
+ if (!m_maxColorAttachments)
+ m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
+ return m_maxColorAttachments;
+}
+
+void WebGLRenderingContext::setBackDrawBuffer(GC3Denum buf)
+{
+ m_backDrawBuffer = buf;
+}
+
+void WebGLRenderingContext::restoreCurrentFramebuffer()
+{
+ ExceptionCode ec;
+ bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_framebufferBinding.get(), ec);
+}
+
+void WebGLRenderingContext::restoreCurrentTexture2D()
+{
+ ExceptionCode ec;
+ bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureUnits[m_activeTextureUnit].texture2DBinding.get(), ec);
+}
+
+bool WebGLRenderingContext::supportsDrawBuffers()
+{
+ if (!m_drawBuffersWebGLRequirementsChecked) {
+ m_drawBuffersWebGLRequirementsChecked = true;
+ m_drawBuffersSupported = EXTDrawBuffers::supported(this);
+ }
+ return m_drawBuffersSupported;
+}
+
+void WebGLRenderingContext::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
+{
+ if (!validateDrawArrays("drawArraysInstanced", mode, first, count, primcount))
+ return;
+
+ if (primcount < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawArraysInstanced", "primcount < 0");
+ return;
+ }
+
+ if (!primcount) {
+ cleanupAfterGraphicsCall(true);
+ return;
+ }
+
+ clearIfComposited();
+
+ bool vertexAttrib0Simulated = false;
+ if (!isGLES2Compliant())
+ vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
+ if (!isGLES2NPOTStrict())
+ checkTextureCompleteness("drawArraysInstanced", true);
+ UNUSED_PARAM(primcount);
+ m_context->drawArraysInstanced(mode, first, count, primcount);
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (!isGLES2NPOTStrict())
+ checkTextureCompleteness("drawArraysInstanced", false);
+ cleanupAfterGraphicsCall(true);
+}
+
+void WebGLRenderingContext::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount)
+{
+ unsigned numElements = 0;
+ if (!validateDrawElements("drawElementsInstanced", mode, count, type, offset, numElements))
+ return;
+
+ if (primcount < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawElementsInstanced", "primcount < 0");
+ return;
+ }
+
+ if (!primcount) {
+ cleanupAfterGraphicsCall(true);
+ return;
+ }
+
+ clearIfComposited();
+
+ bool vertexAttrib0Simulated = false;
+ if (!isGLES2Compliant()) {
+ if (!numElements)
+ validateIndexArrayPrecise(count, type, static_cast<GC3Dintptr>(offset), numElements);
+ vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
+ }
+ if (!isGLES2NPOTStrict())
+ checkTextureCompleteness("drawElementsInstanced", true);
+ m_context->drawElementsInstanced(mode, count, type, static_cast<GC3Dintptr>(offset), primcount);
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (!isGLES2NPOTStrict())
+ checkTextureCompleteness("drawElementsInstanced", false);
+ cleanupAfterGraphicsCall(true);
+}
+
+void WebGLRenderingContext::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
+{
+ if (isContextLost())
+ return;
+
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribDivisor", "index out of range");
+ return;
+ }
+
+ m_boundVertexArrayObject->setVertexAttribDivisor(index, divisor);
+ m_context->vertexAttribDivisor(index, divisor);
+}
+
+
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h
index 204788de2..88999d80e 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,63 +26,779 @@
#ifndef WebGLRenderingContext_h
#define WebGLRenderingContext_h
-#include "WebGLRenderingContextBase.h"
+#include "ActiveDOMObject.h"
+#include "CanvasRenderingContext.h"
+#include "DrawingBuffer.h"
+#include "GraphicsContext3D.h"
+#include "ImageBuffer.h"
+#include "Timer.h"
+#include "WebGLGetInfo.h"
+
+#include <memory>
+#include <runtime/Float32Array.h>
+#include <runtime/Int32Array.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
-class WebGLRenderingContext final : public WebGLRenderingContextBase {
+class ANGLEInstancedArrays;
+class EXTDrawBuffers;
+class EXTTextureFilterAnisotropic;
+class HTMLImageElement;
+class HTMLVideoElement;
+class ImageBuffer;
+class ImageData;
+class IntSize;
+class OESStandardDerivatives;
+class OESTextureFloat;
+class OESTextureFloatLinear;
+class OESTextureHalfFloat;
+class OESTextureHalfFloatLinear;
+class OESVertexArrayObject;
+class OESElementIndexUint;
+class WebGLActiveInfo;
+class WebGLBuffer;
+class WebGLContextGroup;
+class WebGLContextObject;
+class WebGLCompressedTextureATC;
+class WebGLCompressedTexturePVRTC;
+class WebGLCompressedTextureS3TC;
+class WebGLContextAttributes;
+class WebGLDebugRendererInfo;
+class WebGLDebugShaders;
+class WebGLDepthTexture;
+class WebGLExtension;
+class WebGLFramebuffer;
+class WebGLLoseContext;
+class WebGLObject;
+class WebGLProgram;
+class WebGLRenderbuffer;
+class WebGLShader;
+class WebGLSharedObject;
+class WebGLShaderPrecisionFormat;
+class WebGLTexture;
+class WebGLUniformLocation;
+class WebGLVertexArrayObjectOES;
+
+typedef int ExceptionCode;
+
+class WebGLRenderingContext : public CanvasRenderingContext, public ActiveDOMObject {
public:
- WebGLRenderingContext(HTMLCanvasElement*, GraphicsContext3D::Attributes);
+ static OwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*);
+ virtual ~WebGLRenderingContext();
+
+ virtual bool is3d() const override { return true; }
+ virtual bool isAccelerated() const override { return true; }
+
+ int drawingBufferWidth() const;
+ int drawingBufferHeight() const;
+
+ void activeTexture(GC3Denum texture, ExceptionCode&);
+ void attachShader(WebGLProgram*, WebGLShader*, ExceptionCode&);
+ void bindAttribLocation(WebGLProgram*, GC3Duint index, const String& name, ExceptionCode&);
+ void bindBuffer(GC3Denum target, WebGLBuffer*, ExceptionCode&);
+ void bindFramebuffer(GC3Denum target, WebGLFramebuffer*, ExceptionCode&);
+ void bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*, ExceptionCode&);
+ void bindTexture(GC3Denum target, WebGLTexture*, ExceptionCode&);
+ void blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
+ void blendEquation(GC3Denum mode);
+ void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha);
+ void blendFunc(GC3Denum sfactor, GC3Denum dfactor);
+ void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha);
+
+ void bufferData(GC3Denum target, long long size, GC3Denum usage, ExceptionCode&);
+ void bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage, ExceptionCode&);
+ void bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage, ExceptionCode&);
+ void bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data, ExceptionCode&);
+ void bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data, ExceptionCode&);
+
+ GC3Denum checkFramebufferStatus(GC3Denum target);
+ void clear(GC3Dbitfield mask);
+ void clearColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
+ void clearDepth(GC3Dfloat);
+ void clearStencil(GC3Dint);
+ void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha);
+ void compileShader(WebGLShader*, ExceptionCode&);
+
+ void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
+ GC3Dsizei height, GC3Dint border, ArrayBufferView* data);
+ void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data);
+
+ void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
+ void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
+
+ PassRefPtr<WebGLBuffer> createBuffer();
+ PassRefPtr<WebGLFramebuffer> createFramebuffer();
+ PassRefPtr<WebGLProgram> createProgram();
+ PassRefPtr<WebGLRenderbuffer> createRenderbuffer();
+ PassRefPtr<WebGLShader> createShader(GC3Denum type, ExceptionCode&);
+ PassRefPtr<WebGLTexture> createTexture();
+
+ void cullFace(GC3Denum mode);
+
+ void deleteBuffer(WebGLBuffer*);
+ void deleteFramebuffer(WebGLFramebuffer*);
+ void deleteProgram(WebGLProgram*);
+ void deleteRenderbuffer(WebGLRenderbuffer*);
+ void deleteShader(WebGLShader*);
+ void deleteTexture(WebGLTexture*);
+
+ void depthFunc(GC3Denum);
+ void depthMask(GC3Dboolean);
+ void depthRange(GC3Dfloat zNear, GC3Dfloat zFar);
+ void detachShader(WebGLProgram*, WebGLShader*, ExceptionCode&);
+ void disable(GC3Denum cap);
+ void disableVertexAttribArray(GC3Duint index, ExceptionCode&);
+ void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count, ExceptionCode&);
+ void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, ExceptionCode&);
+
+ void enable(GC3Denum cap);
+ void enableVertexAttribArray(GC3Duint index, ExceptionCode&);
+ void finish();
+ void flush();
+ void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer*, ExceptionCode&);
+ void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture*, GC3Dint level, ExceptionCode&);
+ void frontFace(GC3Denum mode);
+ void generateMipmap(GC3Denum target);
+
+ PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GC3Duint index, ExceptionCode&);
+ PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GC3Duint index, ExceptionCode&);
+ bool getAttachedShaders(WebGLProgram*, Vector<RefPtr<WebGLShader>>&, ExceptionCode&);
+ GC3Dint getAttribLocation(WebGLProgram*, const String& name);
+ WebGLGetInfo getBufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode&);
+ PassRefPtr<WebGLContextAttributes> getContextAttributes();
+ GC3Denum getError();
+ WebGLExtension* getExtension(const String& name);
+ WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&);
+ WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&);
+ WebGLGetInfo getProgramParameter(WebGLProgram*, GC3Denum pname, ExceptionCode&);
+ String getProgramInfoLog(WebGLProgram*, ExceptionCode&);
+ WebGLGetInfo getRenderbufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode&);
+ WebGLGetInfo getShaderParameter(WebGLShader*, GC3Denum pname, ExceptionCode&);
+ String getShaderInfoLog(WebGLShader*, ExceptionCode&);
+ PassRefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType, ExceptionCode&);
+ String getShaderSource(WebGLShader*, ExceptionCode&);
+ Vector<String> getSupportedExtensions();
+ WebGLGetInfo getTexParameter(GC3Denum target, GC3Denum pname, ExceptionCode&);
+ WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*, ExceptionCode&);
+ PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&, ExceptionCode&);
+ WebGLGetInfo getVertexAttrib(GC3Duint index, GC3Denum pname, ExceptionCode&);
+ long long getVertexAttribOffset(GC3Duint index, GC3Denum pname);
+
+ void hint(GC3Denum target, GC3Denum mode);
+ GC3Dboolean isBuffer(WebGLBuffer*);
+ bool isContextLost() const;
+ GC3Dboolean isEnabled(GC3Denum cap);
+ GC3Dboolean isFramebuffer(WebGLFramebuffer*);
+ GC3Dboolean isProgram(WebGLProgram*);
+ GC3Dboolean isRenderbuffer(WebGLRenderbuffer*);
+ GC3Dboolean isShader(WebGLShader*);
+ GC3Dboolean isTexture(WebGLTexture*);
+
+ void lineWidth(GC3Dfloat);
+ void linkProgram(WebGLProgram*, ExceptionCode&);
+ void pixelStorei(GC3Denum pname, GC3Dint param);
+ void polygonOffset(GC3Dfloat factor, GC3Dfloat units);
+ void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&);
+ void releaseShaderCompiler();
+ void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
+ void sampleCoverage(GC3Dfloat value, GC3Dboolean invert);
+ void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
+ void shaderSource(WebGLShader*, const String&, ExceptionCode&);
+ void stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask);
+ void stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask);
+ void stencilMask(GC3Duint);
+ void stencilMaskSeparate(GC3Denum face, GC3Duint mask);
+ void stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
+ void stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
+
+ void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&);
+ void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&);
+ void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&);
+ void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&);
+#if ENABLE(VIDEO)
+ void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&);
+#endif
+
+ void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param);
+ void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param);
+
+ void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&);
+ void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&);
+ void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&);
+ void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&);
+#if ENABLE(VIDEO)
+ void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&);
+#endif
+
+ void uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode&);
+ void uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
+ void uniform1fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode&);
+ void uniform1i(const WebGLUniformLocation* location, GC3Dint x, ExceptionCode&);
+ void uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
+ void uniform1iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode&);
+ void uniform2f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, ExceptionCode&);
+ void uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
+ void uniform2fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode&);
+ void uniform2i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, ExceptionCode&);
+ void uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
+ void uniform2iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode&);
+ void uniform3f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, ExceptionCode&);
+ void uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
+ void uniform3fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode&);
+ void uniform3i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, ExceptionCode&);
+ void uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
+ void uniform3iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode&);
+ void uniform4f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w, ExceptionCode&);
+ void uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
+ void uniform4fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode&);
+ void uniform4i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w, ExceptionCode&);
+ void uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
+ void uniform4iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode&);
+ void uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value, ExceptionCode&);
+ void uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei size, ExceptionCode&);
+ void uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value, ExceptionCode&);
+ void uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei size, ExceptionCode&);
+ void uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value, ExceptionCode&);
+ void uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei size, ExceptionCode&);
+
+ void useProgram(WebGLProgram*, ExceptionCode&);
+ void validateProgram(WebGLProgram*, ExceptionCode&);
+
+ void vertexAttrib1f(GC3Duint index, GC3Dfloat x);
+ void vertexAttrib1fv(GC3Duint index, Float32Array* values);
+ void vertexAttrib1fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
+ void vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y);
+ void vertexAttrib2fv(GC3Duint index, Float32Array* values);
+ void vertexAttrib2fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
+ void vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
+ void vertexAttrib3fv(GC3Duint index, Float32Array* values);
+ void vertexAttrib3fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
+ void vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
+ void vertexAttrib4fv(GC3Duint index, Float32Array* values);
+ void vertexAttrib4fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
+ void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized,
+ GC3Dsizei stride, long long offset, ExceptionCode&);
+
+ void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
+
+ // WEBKIT_lose_context support
+ enum LostContextMode {
+ // Lost context occurred at the graphics system level.
+ RealLostContext,
+
+ // Lost context provoked by WEBKIT_lose_context.
+ SyntheticLostContext
+ };
+ void forceLostContext(LostContextMode);
+ void forceRestoreContext();
+ void loseContextImpl(LostContextMode);
+
+ GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
+ WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
+#if USE(ACCELERATED_COMPOSITING)
+ virtual PlatformLayer* platformLayer() const override;
+#endif
+
+ void reshape(int width, int height);
+
+ void markLayerComposited();
+ virtual void paintRenderingResultsToCanvas() override;
+ virtual PassRefPtr<ImageData> paintRenderingResultsToImageData();
+
+ void removeSharedObject(WebGLSharedObject*);
+ void removeContextObject(WebGLContextObject*);
+
+ unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; }
+
+ // ANGLE_instanced_arrays extension functions.
+ void drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
+ void drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount);
+ void vertexAttribDivisor(GC3Duint index, GC3Duint divisor);
+
+private:
+ friend class EXTDrawBuffers;
+ friend class WebGLFramebuffer;
+ friend class WebGLObject;
+ friend class OESVertexArrayObject;
+ friend class WebGLDebugShaders;
+ friend class WebGLCompressedTextureATC;
+ friend class WebGLCompressedTexturePVRTC;
+ friend class WebGLCompressedTextureS3TC;
+ friend class WebGLRenderingContextErrorMessageCallback;
+ friend class WebGLVertexArrayObjectOES;
+
WebGLRenderingContext(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>, GraphicsContext3D::Attributes);
- virtual bool isWebGL1() const override { return true; }
+ void initializeNewContext();
+ void setupFlags();
+
+ // ActiveDOMObject
+ virtual bool hasPendingActivity() const override;
+ virtual void stop() override;
+
+ void addSharedObject(WebGLSharedObject*);
+ void addContextObject(WebGLContextObject*);
+ void detachAndRemoveAllObjects();
+
+ void destroyGraphicsContext3D();
+ void markContextChanged();
+ void cleanupAfterGraphicsCall(bool changed)
+ {
+ if (changed)
+ markContextChanged();
+ }
+
+ // Query whether it is built on top of compliant GLES2 implementation.
+ bool isGLES2Compliant() { return m_isGLES2Compliant; }
+ // Query if the GL implementation is NPOT strict.
+ bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
+ // Query if the GL implementation generates errors on out-of-bounds buffer accesses.
+ bool isErrorGeneratedOnOutOfBoundsAccesses() { return m_isErrorGeneratedOnOutOfBoundsAccesses; }
+ // Query if the GL implementation initializes textures/renderbuffers to 0.
+ bool isResourceSafe() { return m_isResourceSafe; }
+ // Query if depth_stencil buffer is supported.
+ bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
+
+ // Helper to return the size in bytes of OpenGL data types
+ // like GL_FLOAT, GL_INT, etc.
+ unsigned int sizeInBytes(GC3Denum type);
+
+ // Basic validation of count and offset against number of elements in element array buffer
+ bool validateElementArraySize(GC3Dsizei count, GC3Denum type, GC3Dintptr offset);
+
+ // Conservative but quick index validation
+ bool validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired);
+
+ // Precise but slow index validation -- only done if conservative checks fail
+ bool validateIndexArrayPrecise(GC3Dsizei count, GC3Denum type, GC3Dintptr offset, unsigned& numElementsRequired);
+ bool validateVertexAttributes(unsigned elementCount, unsigned primitiveCount = 0);
+
+ bool validateWebGLObject(const char*, WebGLObject*);
+
+ bool validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
+ bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned& numElements);
+
+ // Adds a compressed texture format.
+ void addCompressedTextureFormat(GC3Denum);
+
+ PassRefPtr<Image> drawImageIntoBuffer(Image*, int width, int height, int deviceScaleFactor);
+
+#if ENABLE(VIDEO)
+ PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy, ExceptionCode&);
+#endif
+
+ RefPtr<GraphicsContext3D> m_context;
+ RefPtr<WebGLContextGroup> m_contextGroup;
+
+ // Optional structure for rendering to a DrawingBuffer, instead of directly
+ // to the back-buffer of m_context.
+ RefPtr<DrawingBuffer> m_drawingBuffer;
+
+ // Dispatches a context lost event once it is determined that one is needed.
+ // This is used both for synthetic and real context losses. For real ones, it's
+ // likely that there's no JavaScript on the stack, but that might be dependent
+ // on how exactly the platform discovers that the context was lost. For better
+ // portability we always defer the dispatch of the event.
+ Timer<WebGLRenderingContext> m_dispatchContextLostEventTimer;
+ bool m_restoreAllowed;
+ Timer<WebGLRenderingContext> m_restoreTimer;
+
+ bool m_needsUpdate;
+ bool m_markedCanvasDirty;
+ HashSet<WebGLContextObject*> m_contextObjects;
+
+ // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
+ RefPtr<WebGLBuffer> m_boundArrayBuffer;
+
+ RefPtr<WebGLVertexArrayObjectOES> m_defaultVertexArrayObject;
+ RefPtr<WebGLVertexArrayObjectOES> m_boundVertexArrayObject;
+ void setBoundVertexArrayObject(PassRefPtr<WebGLVertexArrayObjectOES> arrayObject)
+ {
+ if (arrayObject)
+ m_boundVertexArrayObject = arrayObject;
+ else
+ m_boundVertexArrayObject = m_defaultVertexArrayObject;
+ }
- virtual WebGLExtension* getExtension(const String&) override;
- virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&) override;
- virtual Vector<String> getSupportedExtensions() override;
-
- virtual WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&) override;
- virtual void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) override;
- virtual bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment) override;
- virtual void hint(GC3Denum target, GC3Denum mode) override;
- virtual void clear(GC3Dbitfield mask) override;
- virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) override;
- virtual void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&) override;
- virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&) override;
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&) override;
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&) override;
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&) override;
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&) override;
+ class VertexAttribValue {
+ public:
+ VertexAttribValue()
+ {
+ initValue();
+ }
+
+ void initValue()
+ {
+ value[0] = 0.0f;
+ value[1] = 0.0f;
+ value[2] = 0.0f;
+ value[3] = 1.0f;
+ }
+
+ GC3Dfloat value[4];
+ };
+ Vector<VertexAttribValue> m_vertexAttribValue;
+ unsigned m_maxVertexAttribs;
+ RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
+ long m_vertexAttrib0BufferSize;
+ GC3Dfloat m_vertexAttrib0BufferValue[4];
+ bool m_forceAttrib0BufferRefill;
+ bool m_vertexAttrib0UsedBefore;
+
+ RefPtr<WebGLProgram> m_currentProgram;
+ RefPtr<WebGLFramebuffer> m_framebufferBinding;
+ RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
+ struct TextureUnitState {
+ RefPtr<WebGLTexture> texture2DBinding;
+ RefPtr<WebGLTexture> textureCubeMapBinding;
+ };
+ Vector<TextureUnitState> m_textureUnits;
+ unsigned long m_activeTextureUnit;
+
+ RefPtr<WebGLTexture> m_blackTexture2D;
+ RefPtr<WebGLTexture> m_blackTextureCubeMap;
+
+ Vector<GC3Denum> m_compressedTextureFormats;
+
+ // Fixed-size cache of reusable image buffers for video texImage2D calls.
+ class LRUImageBufferCache {
+ public:
+ LRUImageBufferCache(int capacity);
+ // The pointer returned is owned by the image buffer map.
+ ImageBuffer* imageBuffer(const IntSize& size);
+ private:
+ void bubbleToFront(int idx);
+ std::unique_ptr<std::unique_ptr<ImageBuffer>[]> m_buffers;
+ int m_capacity;
+ };
+ LRUImageBufferCache m_generatedImageCache;
+
+ GC3Dint m_maxTextureSize;
+ GC3Dint m_maxCubeMapTextureSize;
+ GC3Dint m_maxRenderbufferSize;
+ GC3Dint m_maxViewportDims[2];
+ GC3Dint m_maxTextureLevel;
+ GC3Dint m_maxCubeMapTextureLevel;
+
+ GC3Dint m_maxDrawBuffers;
+ GC3Dint m_maxColorAttachments;
+ GC3Denum m_backDrawBuffer;
+ bool m_drawBuffersWebGLRequirementsChecked;
+ bool m_drawBuffersSupported;
+
+ GC3Dint m_packAlignment;
+ GC3Dint m_unpackAlignment;
+ bool m_unpackFlipY;
+ bool m_unpackPremultiplyAlpha;
+ GC3Denum m_unpackColorspaceConversion;
+ bool m_contextLost;
+ LostContextMode m_contextLostMode;
+ GraphicsContext3D::Attributes m_attributes;
+
+ bool m_layerCleared;
+ GC3Dfloat m_clearColor[4];
+ bool m_scissorEnabled;
+ GC3Dfloat m_clearDepth;
+ GC3Dint m_clearStencil;
+ GC3Dboolean m_colorMask[4];
+ GC3Dboolean m_depthMask;
+
+ bool m_stencilEnabled;
+ GC3Duint m_stencilMask, m_stencilMaskBack;
+ GC3Dint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
+ GC3Duint m_stencilFuncMask, m_stencilFuncMaskBack;
+
+ bool m_isGLES2Compliant;
+ bool m_isGLES2NPOTStrict;
+ bool m_isErrorGeneratedOnOutOfBoundsAccesses;
+ bool m_isResourceSafe;
+ bool m_isDepthStencilSupported;
+ bool m_isRobustnessEXTSupported;
+
+ bool m_synthesizedErrorsToConsole;
+ int m_numGLErrorsToConsoleAllowed;
+
+ // Enabled extension objects.
+ OwnPtr<EXTDrawBuffers> m_extDrawBuffers;
+ OwnPtr<EXTTextureFilterAnisotropic> m_extTextureFilterAnisotropic;
+ OwnPtr<OESTextureFloat> m_oesTextureFloat;
+ OwnPtr<OESTextureFloatLinear> m_oesTextureFloatLinear;
+ OwnPtr<OESTextureHalfFloat> m_oesTextureHalfFloat;
+ OwnPtr<OESTextureHalfFloatLinear> m_oesTextureHalfFloatLinear;
+ OwnPtr<OESStandardDerivatives> m_oesStandardDerivatives;
+ OwnPtr<OESVertexArrayObject> m_oesVertexArrayObject;
+ OwnPtr<OESElementIndexUint> m_oesElementIndexUint;
+ OwnPtr<WebGLLoseContext> m_webglLoseContext;
+ OwnPtr<WebGLDebugRendererInfo> m_webglDebugRendererInfo;
+ OwnPtr<WebGLDebugShaders> m_webglDebugShaders;
+ OwnPtr<WebGLCompressedTextureATC> m_webglCompressedTextureATC;
+ OwnPtr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC;
+ OwnPtr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC;
+ OwnPtr<WebGLDepthTexture> m_webglDepthTexture;
+ OwnPtr<ANGLEInstancedArrays> m_angleInstancedArrays;
+
+ // Helpers for getParameter and others
+ WebGLGetInfo getBooleanParameter(GC3Denum);
+ WebGLGetInfo getBooleanArrayParameter(GC3Denum);
+ WebGLGetInfo getFloatParameter(GC3Denum);
+ WebGLGetInfo getIntParameter(GC3Denum);
+ WebGLGetInfo getUnsignedIntParameter(GC3Denum);
+ WebGLGetInfo getWebGLFloatArrayParameter(GC3Denum);
+ WebGLGetInfo getWebGLIntArrayParameter(GC3Denum);
+
+ // Clear the backbuffer if it was composited since the last operation.
+ // clearMask is set to the bitfield of any clear that would happen anyway at this time
+ // and the function returns true if that clear is now unnecessary.
+ bool clearIfComposited(GC3Dbitfield clearMask = 0);
+
+ // Helper to restore state that clearing the framebuffer may destroy.
+ void restoreStateAfterClear();
+
+ void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&);
+ void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&);
+ void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&);
+ void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&);
+
+ void checkTextureCompleteness(const char*, bool);
+
+ void createFallbackBlackTextures1x1();
+
+ // Helper function for copyTex{Sub}Image, check whether the internalformat
+ // and the color buffer format of the current bound framebuffer combination
+ // is valid.
+ bool isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat,
+ GC3Denum colorBufferFormat);
+
+ // Helper function to get the bound framebuffer's color buffer format.
+ GC3Denum getBoundFramebufferColorFormat();
+
+ // Helper function to get the bound framebuffer's width.
+ int getBoundFramebufferWidth();
+
+ // Helper function to get the bound framebuffer's height.
+ int getBoundFramebufferHeight();
+
+ // Helper function to verify limits on the length of uniform and attribute locations.
+ bool validateLocationLength(const char* functionName, const String&);
+
+ // Helper function to check if size is non-negative.
+ // Generate GL error and return false for negative inputs; otherwise, return true.
+ bool validateSize(const char* functionName, GC3Dint x, GC3Dint y);
+
+ // Helper function to check if all characters in the string belong to the
+ // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
+ bool validateString(const char* functionName, const String&);
+
+ // Helper function to check target and texture bound to the target.
+ // Generate GL errors and return 0 if target is invalid or texture bound is
+ // null. Otherwise, return the texture bound to the target.
+ WebGLTexture* validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap);
+
+ // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if parameters are invalid.
+ bool validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level);
+
+ // Helper function to check input level for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if level is invalid.
+ bool validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level);
+
+ enum TexFuncValidationFunctionType {
+ NotTexSubImage2D,
+ TexSubImage2D,
+ };
+
+ enum TexFuncValidationSourceType {
+ SourceArrayBufferView,
+ SourceImageData,
+ SourceHTMLImageElement,
+ SourceHTMLCanvasElement,
+ SourceHTMLVideoElement,
+ };
+
+ // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
+ // Otherwise, it would return quickly without doing other work.
+ bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
+ GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset);
+
+ // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if parameters are invalid.
+ bool validateTexFuncParameters(const char* functionName,
+ TexFuncValidationFunctionType,
+ GC3Denum target, GC3Dint level,
+ GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type);
+
+ enum NullDisposition {
+ NullAllowed,
+ NullNotAllowed
+ };
+
+ // Helper function to validate that the given ArrayBufferView
+ // is of the correct type and contains enough data for the texImage call.
+ // Generates GL error and returns false if parameters are invalid.
+ bool validateTexFuncData(const char* functionName, GC3Dint level,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type,
+ ArrayBufferView* pixels,
+ NullDisposition);
+
+ // Helper function to validate a given texture format is settable as in
+ // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
+ // copyTexSubImage2D.
+ // Generates GL error and returns false if the format is not settable.
+ bool validateSettableTexFormat(const char* functionName, GC3Denum format);
+
+ // Helper function to validate compressed texture data is correct size
+ // for the given format and dimensions.
+ bool validateCompressedTexFuncData(const char* functionName,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, ArrayBufferView* pixels);
+
+ // Helper function for validating compressed texture formats.
+ bool validateCompressedTexFormat(GC3Denum format);
+
+ // Helper function to validate compressed texture dimensions are valid for
+ // the given format.
+ bool validateCompressedTexDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format);
+
+ // Helper function to validate compressed texture dimensions are valid for
+ // the given format.
+ bool validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture*);
+
+ // Helper function to validate mode for draw{Arrays/Elements}.
+ bool validateDrawMode(const char* functionName, GC3Denum);
+
+ // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
+ bool validateStencilSettings(const char* functionName);
+
+ // Helper function to validate stencil func.
+ bool validateStencilFunc(const char* functionName, GC3Denum);
+
+ // Helper function for texParameterf and texParameteri.
+ void texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat parami, GC3Dint paramf, bool isFloat);
+
+ // Helper function to print GL errors to console.
+ void printGLErrorToConsole(const String&);
+ void printGLWarningToConsole(const char* function, const char* reason);
+
+ // Helper function to print warnings to console. Currently
+ // used only to warn about use of obsolete functions.
+ void printWarningToConsole(const String&);
+
+ // Helper function to validate input parameters for framebuffer functions.
+ // Generate GL error if parameters are illegal.
+ bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment);
+
+ // Helper function to validate blend equation mode.
+ bool validateBlendEquation(const char* functionName, GC3Denum);
+
+ // Helper function to validate blend func factors.
+ bool validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst);
+
+ // Helper function to validate a GL capability.
+ bool validateCapability(const char* functionName, GC3Denum);
+
+ // Helper function to validate input parameters for uniform functions.
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GC3Dsizei mod);
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GC3Dsizei mod);
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GC3Dsizei, GC3Dsizei mod);
+ bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array*, GC3Dsizei mod);
+ bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei, GC3Dsizei mod);
+
+ // Helper function to validate parameters for bufferData.
+ // Return the current bound buffer to target, or 0 if parameters are invalid.
+ WebGLBuffer* validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage);
+
+ // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin.
+ bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionCode&);
+
+ // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin.
+ bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionCode&);
+
#if ENABLE(VIDEO)
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&) override;
+ // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin.
+ bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionCode&);
#endif
-protected:
- virtual GC3Dint getMaxDrawBuffers() override;
- virtual GC3Dint getMaxColorAttachments() override;
- virtual void initializeVertexArrayObjects() override;
- virtual bool validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired) override;
- virtual bool validateBlendEquation(const char* functionName, GC3Denum mode) override;
- virtual bool validateTexFuncParameters(const char* functionName,
- TexFuncValidationFunctionType,
- GC3Denum target, GC3Dint level,
- GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type) override;
- virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) override;
- virtual bool validateTexFuncData(const char* functionName, GC3Dint level,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum internalformat, GC3Denum format, GC3Denum type,
- ArrayBufferView* pixels,
- NullDisposition) override;
- virtual bool validateCapability(const char* functionName, GC3Denum cap) override;
+ // Helper functions for vertexAttribNf{v}.
+ void vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat);
+ void vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array*, GC3Dsizei expectedSize);
+ void vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat*, GC3Dsizei, GC3Dsizei expectedSize);
+
+ // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
+ // Return false if caller should return without further processing.
+ bool deleteObject(WebGLObject*);
+
+ // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
+ // If the object has already been deleted, set deleted to true upon return.
+ // Return false if caller should return without further processing.
+ bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted);
+
+ // Helpers for simulating vertexAttrib0
+ void initVertexAttrib0();
+ bool simulateVertexAttrib0(GC3Dsizei numVertex);
+ void restoreStatesAfterVertexAttrib0Simulation();
+
+ void dispatchContextLostEvent(Timer<WebGLRenderingContext>*);
+ // Helper for restoration after context lost.
+ void maybeRestoreContext(Timer<WebGLRenderingContext>*);
+
+ // Determine if we are running privileged code in the browser, for example,
+ // a Safari or Chrome extension.
+ bool allowPrivilegedExtensions() const;
+
+ enum ConsoleDisplayPreference {
+ DisplayInConsole,
+ DontDisplayInConsole
+ };
+
+ // Wrapper for GraphicsContext3D::synthesizeGLError that sends a message
+ // to the JavaScript console.
+ void synthesizeGLError(GC3Denum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
+
+ String ensureNotNull(const String&) const;
+
+ // Enable or disable stencil test based on user setting and
+ // whether the current FBO has a stencil buffer.
+ void applyStencilTest();
+
+ // Helper for enabling or disabling a capability.
+ void enableOrDisable(GC3Denum capability, bool enable);
+
+ // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
+ IntSize clampedCanvasSize();
+
+ // First time called, if EXT_draw_buffers is supported, query the value; otherwise return 0.
+ // Later, return the cached value.
+ GC3Dint getMaxDrawBuffers();
+ GC3Dint getMaxColorAttachments();
+
+ void setBackDrawBuffer(GC3Denum);
+
+ void restoreCurrentFramebuffer();
+ void restoreCurrentTexture2D();
+
+ // Check if EXT_draw_buffers extension is supported and if it satisfies the WebGL requirements.
+ bool supportsDrawBuffers();
+
+ friend class WebGLStateRestorer;
};
-
+
} // namespace WebCore
#endif
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.idl b/Source/WebCore/html/canvas/WebGLRenderingContext.idl
index 1268168e3..54d9b0431 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.idl
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -23,9 +23,647 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+typedef unsigned long GLenum;
+typedef boolean GLboolean;
+typedef unsigned long GLbitfield;
+typedef byte GLbyte; /* 'byte' should be a signed 8 bit type. */
+typedef short GLshort;
+typedef long GLint;
+typedef long GLsizei;
+typedef long long GLintptr;
+typedef long long GLsizeiptr;
+typedef octet GLubyte; /* 'octet' should be an unsigned 8 bit type. */
+typedef unsigned short GLushort;
+typedef unsigned long GLuint;
+typedef /*unrestricted*/ float GLfloat;
+typedef /*unrestricted*/ float GLclampf;
+
[
Conditional=WEBGL,
JSCustomMarkFunction,
DoNotCheckConstants,
-] interface WebGLRenderingContext : WebGLRenderingContextBase {
+] interface WebGLRenderingContext : CanvasRenderingContext {
+
+ /* ClearBufferMask */
+ const GLenum DEPTH_BUFFER_BIT = 0x00000100;
+ const GLenum STENCIL_BUFFER_BIT = 0x00000400;
+ const GLenum COLOR_BUFFER_BIT = 0x00004000;
+
+ /* BeginMode */
+ const GLenum POINTS = 0x0000;
+ const GLenum LINES = 0x0001;
+ const GLenum LINE_LOOP = 0x0002;
+ const GLenum LINE_STRIP = 0x0003;
+ const GLenum TRIANGLES = 0x0004;
+ const GLenum TRIANGLE_STRIP = 0x0005;
+ const GLenum TRIANGLE_FAN = 0x0006;
+
+ /* AlphaFunction (not supported in ES20) */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* BlendingFactorDest */
+ const GLenum ZERO = 0;
+ const GLenum ONE = 1;
+ const GLenum SRC_COLOR = 0x0300;
+ const GLenum ONE_MINUS_SRC_COLOR = 0x0301;
+ const GLenum SRC_ALPHA = 0x0302;
+ const GLenum ONE_MINUS_SRC_ALPHA = 0x0303;
+ const GLenum DST_ALPHA = 0x0304;
+ const GLenum ONE_MINUS_DST_ALPHA = 0x0305;
+
+ /* BlendingFactorSrc */
+ /* ZERO */
+ /* ONE */
+ const GLenum DST_COLOR = 0x0306;
+ const GLenum ONE_MINUS_DST_COLOR = 0x0307;
+ const GLenum SRC_ALPHA_SATURATE = 0x0308;
+ /* SRC_ALPHA */
+ /* ONE_MINUS_SRC_ALPHA */
+ /* DST_ALPHA */
+ /* ONE_MINUS_DST_ALPHA */
+
+ /* BlendEquationSeparate */
+ const GLenum FUNC_ADD = 0x8006;
+ const GLenum BLEND_EQUATION = 0x8009;
+ const GLenum BLEND_EQUATION_RGB = 0x8009; /* same as BLEND_EQUATION */
+ const GLenum BLEND_EQUATION_ALPHA = 0x883D;
+
+ /* BlendSubtract */
+ const GLenum FUNC_SUBTRACT = 0x800A;
+ const GLenum FUNC_REVERSE_SUBTRACT = 0x800B;
+
+ /* Separate Blend Functions */
+ const GLenum BLEND_DST_RGB = 0x80C8;
+ const GLenum BLEND_SRC_RGB = 0x80C9;
+ const GLenum BLEND_DST_ALPHA = 0x80CA;
+ const GLenum BLEND_SRC_ALPHA = 0x80CB;
+ const GLenum CONSTANT_COLOR = 0x8001;
+ const GLenum ONE_MINUS_CONSTANT_COLOR = 0x8002;
+ const GLenum CONSTANT_ALPHA = 0x8003;
+ const GLenum ONE_MINUS_CONSTANT_ALPHA = 0x8004;
+ const GLenum BLEND_COLOR = 0x8005;
+
+ /* Buffer Objects */
+ const GLenum ARRAY_BUFFER = 0x8892;
+ const GLenum ELEMENT_ARRAY_BUFFER = 0x8893;
+ const GLenum ARRAY_BUFFER_BINDING = 0x8894;
+ const GLenum ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
+
+ const GLenum STREAM_DRAW = 0x88E0;
+ const GLenum STATIC_DRAW = 0x88E4;
+ const GLenum DYNAMIC_DRAW = 0x88E8;
+
+ const GLenum BUFFER_SIZE = 0x8764;
+ const GLenum BUFFER_USAGE = 0x8765;
+
+ const GLenum CURRENT_VERTEX_ATTRIB = 0x8626;
+
+ /* CullFaceMode */
+ const GLenum FRONT = 0x0404;
+ const GLenum BACK = 0x0405;
+ const GLenum FRONT_AND_BACK = 0x0408;
+
+ /* DepthFunction */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* EnableCap */
+ const GLenum TEXTURE_2D = 0x0DE1;
+ const GLenum CULL_FACE = 0x0B44;
+ const GLenum BLEND = 0x0BE2;
+ const GLenum DITHER = 0x0BD0;
+ const GLenum STENCIL_TEST = 0x0B90;
+ const GLenum DEPTH_TEST = 0x0B71;
+ const GLenum SCISSOR_TEST = 0x0C11;
+ const GLenum POLYGON_OFFSET_FILL = 0x8037;
+ const GLenum SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
+ const GLenum SAMPLE_COVERAGE = 0x80A0;
+
+ /* ErrorCode */
+ const GLenum NO_ERROR = 0;
+ const GLenum INVALID_ENUM = 0x0500;
+ const GLenum INVALID_VALUE = 0x0501;
+ const GLenum INVALID_OPERATION = 0x0502;
+ const GLenum OUT_OF_MEMORY = 0x0505;
+
+ /* FrontFaceDirection */
+ const GLenum CW = 0x0900;
+ const GLenum CCW = 0x0901;
+
+ /* GetPName */
+ const GLenum LINE_WIDTH = 0x0B21;
+ const GLenum ALIASED_POINT_SIZE_RANGE = 0x846D;
+ const GLenum ALIASED_LINE_WIDTH_RANGE = 0x846E;
+ const GLenum CULL_FACE_MODE = 0x0B45;
+ const GLenum FRONT_FACE = 0x0B46;
+ const GLenum DEPTH_RANGE = 0x0B70;
+ const GLenum DEPTH_WRITEMASK = 0x0B72;
+ const GLenum DEPTH_CLEAR_VALUE = 0x0B73;
+ const GLenum DEPTH_FUNC = 0x0B74;
+ const GLenum STENCIL_CLEAR_VALUE = 0x0B91;
+ const GLenum STENCIL_FUNC = 0x0B92;
+ const GLenum STENCIL_FAIL = 0x0B94;
+ const GLenum STENCIL_PASS_DEPTH_FAIL = 0x0B95;
+ const GLenum STENCIL_PASS_DEPTH_PASS = 0x0B96;
+ const GLenum STENCIL_REF = 0x0B97;
+ const GLenum STENCIL_VALUE_MASK = 0x0B93;
+ const GLenum STENCIL_WRITEMASK = 0x0B98;
+ const GLenum STENCIL_BACK_FUNC = 0x8800;
+ const GLenum STENCIL_BACK_FAIL = 0x8801;
+ const GLenum STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
+ const GLenum STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
+ const GLenum STENCIL_BACK_REF = 0x8CA3;
+ const GLenum STENCIL_BACK_VALUE_MASK = 0x8CA4;
+ const GLenum STENCIL_BACK_WRITEMASK = 0x8CA5;
+ const GLenum VIEWPORT = 0x0BA2;
+ const GLenum SCISSOR_BOX = 0x0C10;
+ /* SCISSOR_TEST */
+ const GLenum COLOR_CLEAR_VALUE = 0x0C22;
+ const GLenum COLOR_WRITEMASK = 0x0C23;
+ const GLenum UNPACK_ALIGNMENT = 0x0CF5;
+ const GLenum PACK_ALIGNMENT = 0x0D05;
+ const GLenum MAX_TEXTURE_SIZE = 0x0D33;
+ const GLenum MAX_VIEWPORT_DIMS = 0x0D3A;
+ const GLenum SUBPIXEL_BITS = 0x0D50;
+ const GLenum RED_BITS = 0x0D52;
+ const GLenum GREEN_BITS = 0x0D53;
+ const GLenum BLUE_BITS = 0x0D54;
+ const GLenum ALPHA_BITS = 0x0D55;
+ const GLenum DEPTH_BITS = 0x0D56;
+ const GLenum STENCIL_BITS = 0x0D57;
+ const GLenum POLYGON_OFFSET_UNITS = 0x2A00;
+ /* POLYGON_OFFSET_FILL */
+ const GLenum POLYGON_OFFSET_FACTOR = 0x8038;
+ const GLenum TEXTURE_BINDING_2D = 0x8069;
+ const GLenum SAMPLE_BUFFERS = 0x80A8;
+ const GLenum SAMPLES = 0x80A9;
+ const GLenum SAMPLE_COVERAGE_VALUE = 0x80AA;
+ const GLenum SAMPLE_COVERAGE_INVERT = 0x80AB;
+
+ /* GetTextureParameter */
+ /* TEXTURE_MAG_FILTER */
+ /* TEXTURE_MIN_FILTER */
+ /* TEXTURE_WRAP_S */
+ /* TEXTURE_WRAP_T */
+
+ const GLenum COMPRESSED_TEXTURE_FORMATS = 0x86A3;
+
+ /* HintMode */
+ const GLenum DONT_CARE = 0x1100;
+ const GLenum FASTEST = 0x1101;
+ const GLenum NICEST = 0x1102;
+
+ /* HintTarget */
+ const GLenum GENERATE_MIPMAP_HINT = 0x8192;
+
+ /* DataType */
+ const GLenum BYTE = 0x1400;
+ const GLenum UNSIGNED_BYTE = 0x1401;
+ const GLenum SHORT = 0x1402;
+ const GLenum UNSIGNED_SHORT = 0x1403;
+ const GLenum INT = 0x1404;
+ const GLenum UNSIGNED_INT = 0x1405;
+ const GLenum FLOAT = 0x1406;
+
+ /* PixelFormat */
+ const GLenum DEPTH_COMPONENT = 0x1902;
+ const GLenum ALPHA = 0x1906;
+ const GLenum RGB = 0x1907;
+ const GLenum RGBA = 0x1908;
+ const GLenum LUMINANCE = 0x1909;
+ const GLenum LUMINANCE_ALPHA = 0x190A;
+
+ /* PixelType */
+ /* UNSIGNED_BYTE */
+ const GLenum UNSIGNED_SHORT_4_4_4_4 = 0x8033;
+ const GLenum UNSIGNED_SHORT_5_5_5_1 = 0x8034;
+ const GLenum UNSIGNED_SHORT_5_6_5 = 0x8363;
+
+ /* Shaders */
+ const GLenum FRAGMENT_SHADER = 0x8B30;
+ const GLenum VERTEX_SHADER = 0x8B31;
+ const GLenum MAX_VERTEX_ATTRIBS = 0x8869;
+ const GLenum MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
+ const GLenum MAX_VARYING_VECTORS = 0x8DFC;
+ const GLenum MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
+ const GLenum MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
+ const GLenum MAX_TEXTURE_IMAGE_UNITS = 0x8872;
+ const GLenum MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
+ const GLenum SHADER_TYPE = 0x8B4F;
+ const GLenum DELETE_STATUS = 0x8B80;
+ const GLenum LINK_STATUS = 0x8B82;
+ const GLenum VALIDATE_STATUS = 0x8B83;
+ const GLenum ATTACHED_SHADERS = 0x8B85;
+ const GLenum ACTIVE_UNIFORMS = 0x8B86;
+ const GLenum ACTIVE_ATTRIBUTES = 0x8B89;
+ const GLenum SHADING_LANGUAGE_VERSION = 0x8B8C;
+ const GLenum CURRENT_PROGRAM = 0x8B8D;
+
+ /* StencilFunction */
+ const GLenum NEVER = 0x0200;
+ const GLenum LESS = 0x0201;
+ const GLenum EQUAL = 0x0202;
+ const GLenum LEQUAL = 0x0203;
+ const GLenum GREATER = 0x0204;
+ const GLenum NOTEQUAL = 0x0205;
+ const GLenum GEQUAL = 0x0206;
+ const GLenum ALWAYS = 0x0207;
+
+ /* StencilOp */
+ /* ZERO */
+ const GLenum KEEP = 0x1E00;
+ const GLenum REPLACE = 0x1E01;
+ const GLenum INCR = 0x1E02;
+ const GLenum DECR = 0x1E03;
+ const GLenum INVERT = 0x150A;
+ const GLenum INCR_WRAP = 0x8507;
+ const GLenum DECR_WRAP = 0x8508;
+
+ /* StringName */
+ const GLenum VENDOR = 0x1F00;
+ const GLenum RENDERER = 0x1F01;
+ const GLenum VERSION = 0x1F02;
+
+ /* TextureMagFilter */
+ const GLenum NEAREST = 0x2600;
+ const GLenum LINEAR = 0x2601;
+
+ /* TextureMinFilter */
+ /* NEAREST */
+ /* LINEAR */
+ const GLenum NEAREST_MIPMAP_NEAREST = 0x2700;
+ const GLenum LINEAR_MIPMAP_NEAREST = 0x2701;
+ const GLenum NEAREST_MIPMAP_LINEAR = 0x2702;
+ const GLenum LINEAR_MIPMAP_LINEAR = 0x2703;
+
+ /* TextureParameterName */
+ const GLenum TEXTURE_MAG_FILTER = 0x2800;
+ const GLenum TEXTURE_MIN_FILTER = 0x2801;
+ const GLenum TEXTURE_WRAP_S = 0x2802;
+ const GLenum TEXTURE_WRAP_T = 0x2803;
+
+ /* TextureTarget */
+ /* TEXTURE_2D */
+ const GLenum TEXTURE = 0x1702;
+
+ const GLenum TEXTURE_CUBE_MAP = 0x8513;
+ const GLenum TEXTURE_BINDING_CUBE_MAP = 0x8514;
+ const GLenum TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
+ const GLenum TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
+ const GLenum TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
+ const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
+ const GLenum TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
+ const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
+ const GLenum MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
+
+ /* TextureUnit */
+ const GLenum TEXTURE0 = 0x84C0;
+ const GLenum TEXTURE1 = 0x84C1;
+ const GLenum TEXTURE2 = 0x84C2;
+ const GLenum TEXTURE3 = 0x84C3;
+ const GLenum TEXTURE4 = 0x84C4;
+ const GLenum TEXTURE5 = 0x84C5;
+ const GLenum TEXTURE6 = 0x84C6;
+ const GLenum TEXTURE7 = 0x84C7;
+ const GLenum TEXTURE8 = 0x84C8;
+ const GLenum TEXTURE9 = 0x84C9;
+ const GLenum TEXTURE10 = 0x84CA;
+ const GLenum TEXTURE11 = 0x84CB;
+ const GLenum TEXTURE12 = 0x84CC;
+ const GLenum TEXTURE13 = 0x84CD;
+ const GLenum TEXTURE14 = 0x84CE;
+ const GLenum TEXTURE15 = 0x84CF;
+ const GLenum TEXTURE16 = 0x84D0;
+ const GLenum TEXTURE17 = 0x84D1;
+ const GLenum TEXTURE18 = 0x84D2;
+ const GLenum TEXTURE19 = 0x84D3;
+ const GLenum TEXTURE20 = 0x84D4;
+ const GLenum TEXTURE21 = 0x84D5;
+ const GLenum TEXTURE22 = 0x84D6;
+ const GLenum TEXTURE23 = 0x84D7;
+ const GLenum TEXTURE24 = 0x84D8;
+ const GLenum TEXTURE25 = 0x84D9;
+ const GLenum TEXTURE26 = 0x84DA;
+ const GLenum TEXTURE27 = 0x84DB;
+ const GLenum TEXTURE28 = 0x84DC;
+ const GLenum TEXTURE29 = 0x84DD;
+ const GLenum TEXTURE30 = 0x84DE;
+ const GLenum TEXTURE31 = 0x84DF;
+ const GLenum ACTIVE_TEXTURE = 0x84E0;
+
+ /* TextureWrapMode */
+ const GLenum REPEAT = 0x2901;
+ const GLenum CLAMP_TO_EDGE = 0x812F;
+ const GLenum MIRRORED_REPEAT = 0x8370;
+
+ /* Uniform Types */
+ const GLenum FLOAT_VEC2 = 0x8B50;
+ const GLenum FLOAT_VEC3 = 0x8B51;
+ const GLenum FLOAT_VEC4 = 0x8B52;
+ const GLenum INT_VEC2 = 0x8B53;
+ const GLenum INT_VEC3 = 0x8B54;
+ const GLenum INT_VEC4 = 0x8B55;
+ const GLenum BOOL = 0x8B56;
+ const GLenum BOOL_VEC2 = 0x8B57;
+ const GLenum BOOL_VEC3 = 0x8B58;
+ const GLenum BOOL_VEC4 = 0x8B59;
+ const GLenum FLOAT_MAT2 = 0x8B5A;
+ const GLenum FLOAT_MAT3 = 0x8B5B;
+ const GLenum FLOAT_MAT4 = 0x8B5C;
+ const GLenum SAMPLER_2D = 0x8B5E;
+ const GLenum SAMPLER_CUBE = 0x8B60;
+
+ /* Vertex Arrays */
+ const GLenum VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
+ const GLenum VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
+ const GLenum VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
+ const GLenum VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
+ const GLenum VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
+ const GLenum VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
+ const GLenum VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+
+ /* Shader Source */
+ const GLenum COMPILE_STATUS = 0x8B81;
+
+ /* Shader Precision-Specified Types */
+ const GLenum LOW_FLOAT = 0x8DF0;
+ const GLenum MEDIUM_FLOAT = 0x8DF1;
+ const GLenum HIGH_FLOAT = 0x8DF2;
+ const GLenum LOW_INT = 0x8DF3;
+ const GLenum MEDIUM_INT = 0x8DF4;
+ const GLenum HIGH_INT = 0x8DF5;
+
+ /* Framebuffer Object. */
+ const GLenum FRAMEBUFFER = 0x8D40;
+ const GLenum RENDERBUFFER = 0x8D41;
+
+ const GLenum RGBA4 = 0x8056;
+ const GLenum RGB5_A1 = 0x8057;
+ const GLenum RGB565 = 0x8D62;
+ const GLenum DEPTH_COMPONENT16 = 0x81A5;
+ const GLenum STENCIL_INDEX = 0x1901;
+ const GLenum STENCIL_INDEX8 = 0x8D48;
+ const GLenum DEPTH_STENCIL = 0x84F9;
+
+ const GLenum RENDERBUFFER_WIDTH = 0x8D42;
+ const GLenum RENDERBUFFER_HEIGHT = 0x8D43;
+ const GLenum RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
+ const GLenum RENDERBUFFER_RED_SIZE = 0x8D50;
+ const GLenum RENDERBUFFER_GREEN_SIZE = 0x8D51;
+ const GLenum RENDERBUFFER_BLUE_SIZE = 0x8D52;
+ const GLenum RENDERBUFFER_ALPHA_SIZE = 0x8D53;
+ const GLenum RENDERBUFFER_DEPTH_SIZE = 0x8D54;
+ const GLenum RENDERBUFFER_STENCIL_SIZE = 0x8D55;
+
+ const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
+ const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
+ const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
+ const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
+
+ const GLenum COLOR_ATTACHMENT0 = 0x8CE0;
+ const GLenum DEPTH_ATTACHMENT = 0x8D00;
+ const GLenum STENCIL_ATTACHMENT = 0x8D20;
+ const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A;
+
+ const GLenum NONE = 0;
+
+ const GLenum FRAMEBUFFER_COMPLETE = 0x8CD5;
+ const GLenum FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
+ const GLenum FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
+ const GLenum FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
+ const GLenum FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
+
+ const GLenum FRAMEBUFFER_BINDING = 0x8CA6;
+ const GLenum RENDERBUFFER_BINDING = 0x8CA7;
+ const GLenum MAX_RENDERBUFFER_SIZE = 0x84E8;
+
+ const GLenum INVALID_FRAMEBUFFER_OPERATION = 0x0506;
+
+ /* WebGL-specific enums */
+ const GLenum UNPACK_FLIP_Y_WEBGL = 0x9240;
+ const GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
+ const GLenum CONTEXT_LOST_WEBGL = 0x9242;
+ const GLenum UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
+ const GLenum BROWSER_DEFAULT_WEBGL = 0x9244;
+
+ readonly attribute GLsizei drawingBufferWidth;
+ readonly attribute GLsizei drawingBufferHeight;
+
+ [StrictTypeChecking, RaisesException] void activeTexture(GLenum texture);
+ [StrictTypeChecking, RaisesException] void attachShader(WebGLProgram program, WebGLShader shader);
+ [StrictTypeChecking, RaisesException] void bindAttribLocation(WebGLProgram program, GLuint index, DOMString name);
+ [StrictTypeChecking, RaisesException] void bindBuffer(GLenum target, WebGLBuffer buffer);
+ [StrictTypeChecking, RaisesException] void bindFramebuffer(GLenum target, WebGLFramebuffer framebuffer);
+ [StrictTypeChecking, RaisesException] void bindRenderbuffer(GLenum target, WebGLRenderbuffer renderbuffer);
+ [StrictTypeChecking, RaisesException] void bindTexture(GLenum target, WebGLTexture texture);
+ [StrictTypeChecking] void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ [StrictTypeChecking] void blendEquation(GLenum mode);
+ [StrictTypeChecking] void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+ [StrictTypeChecking] void blendFunc(GLenum sfactor, GLenum dfactor);
+ [StrictTypeChecking] void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ [StrictTypeChecking, RaisesException] void bufferData(GLenum target, ArrayBuffer? data, GLenum usage);
+ [StrictTypeChecking, RaisesException] void bufferData(GLenum target, ArrayBufferView? data, GLenum usage);
+ [StrictTypeChecking, RaisesException] void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
+ [StrictTypeChecking, RaisesException] void bufferSubData(GLenum target, GLintptr offset, ArrayBuffer? data);
+ [StrictTypeChecking, RaisesException] void bufferSubData(GLenum target, GLintptr offset, ArrayBufferView? data);
+
+ [StrictTypeChecking] GLenum checkFramebufferStatus(GLenum target);
+ [StrictTypeChecking] void clear(GLbitfield mask);
+ [StrictTypeChecking] void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ [StrictTypeChecking] void clearDepth(GLclampf depth);
+ [StrictTypeChecking] void clearStencil(GLint s);
+ [StrictTypeChecking] void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ [StrictTypeChecking, RaisesException] void compileShader(WebGLShader shader);
+
+ [StrictTypeChecking] void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLint border, ArrayBufferView data);
+ [StrictTypeChecking] void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, ArrayBufferView data);
+
+ [StrictTypeChecking] void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+ [StrictTypeChecking] void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+
+ [StrictTypeChecking] WebGLBuffer createBuffer();
+ [StrictTypeChecking] WebGLFramebuffer createFramebuffer();
+ [StrictTypeChecking] WebGLProgram createProgram();
+ [StrictTypeChecking] WebGLRenderbuffer createRenderbuffer();
+ [StrictTypeChecking, RaisesException] WebGLShader createShader(GLenum type);
+ [StrictTypeChecking] WebGLTexture createTexture();
+
+ [StrictTypeChecking] void cullFace(GLenum mode);
+
+ [StrictTypeChecking] void deleteBuffer(WebGLBuffer buffer);
+ [StrictTypeChecking] void deleteFramebuffer(WebGLFramebuffer framebuffer);
+ [StrictTypeChecking] void deleteProgram(WebGLProgram program);
+ [StrictTypeChecking] void deleteRenderbuffer(WebGLRenderbuffer renderbuffer);
+ [StrictTypeChecking] void deleteShader(WebGLShader shader);
+ [StrictTypeChecking] void deleteTexture(WebGLTexture texture);
+
+ [StrictTypeChecking] void depthFunc(GLenum func);
+ [StrictTypeChecking] void depthMask(GLboolean flag);
+ [StrictTypeChecking] void depthRange(GLclampf zNear, GLclampf zFar);
+ [StrictTypeChecking, RaisesException] void detachShader(WebGLProgram program, WebGLShader shader);
+ [StrictTypeChecking] void disable(GLenum cap);
+ [StrictTypeChecking, RaisesException] void disableVertexAttribArray(GLuint index);
+ [StrictTypeChecking, RaisesException] void drawArrays(GLenum mode, GLint first, GLsizei count);
+ [StrictTypeChecking, RaisesException] void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset);
+
+ [StrictTypeChecking] void enable(GLenum cap);
+ [StrictTypeChecking, RaisesException] void enableVertexAttribArray(GLuint index);
+ [StrictTypeChecking] void finish();
+ [StrictTypeChecking] void flush();
+ [StrictTypeChecking, RaisesException] void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer renderbuffer);
+ [StrictTypeChecking, RaisesException] void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture texture, GLint level);
+ [StrictTypeChecking] void frontFace(GLenum mode);
+ [StrictTypeChecking] void generateMipmap(GLenum target);
+
+ [StrictTypeChecking, RaisesException] WebGLActiveInfo getActiveAttrib(WebGLProgram program, GLuint index);
+ [StrictTypeChecking, RaisesException] WebGLActiveInfo getActiveUniform(WebGLProgram program, GLuint index);
+
+ [StrictTypeChecking, Custom, RaisesException] void getAttachedShaders(WebGLProgram program);
+
+ [StrictTypeChecking] GLint getAttribLocation(WebGLProgram program, DOMString name);
+
+ [StrictTypeChecking, Custom] any getBufferParameter(GLenum target, GLenum pname);
+
+ [StrictTypeChecking] WebGLContextAttributes getContextAttributes();
+
+ [StrictTypeChecking] GLenum getError();
+
+ // object getExtension(DOMString name);
+ [StrictTypeChecking, Custom] any getExtension(DOMString name);
+
+ [StrictTypeChecking, Custom, RaisesException] any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
+ [StrictTypeChecking, Custom, RaisesException] any getParameter(GLenum pname);
+ [StrictTypeChecking, Custom, RaisesException] any getProgramParameter(WebGLProgram program, GLenum pname);
+ [StrictTypeChecking, TreatReturnedNullStringAs=Null, RaisesException] DOMString getProgramInfoLog(WebGLProgram program);
+ [StrictTypeChecking, Custom, RaisesException] any getRenderbufferParameter(GLenum target, GLenum pname);
+ [StrictTypeChecking, Custom, RaisesException] any getShaderParameter(WebGLShader shader, GLenum pname);
+
+ [StrictTypeChecking, TreatReturnedNullStringAs=Null, RaisesException] DOMString getShaderInfoLog(WebGLShader shader);
+
+ [StrictTypeChecking, RaisesException] WebGLShaderPrecisionFormat getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
+
+ [StrictTypeChecking, TreatReturnedNullStringAs=Null, RaisesException] DOMString getShaderSource(WebGLShader shader);
+
+ [StrictTypeChecking, Custom] sequence<DOMString> getSupportedExtensions();
+
+ [StrictTypeChecking, Custom, RaisesException] any getTexParameter(GLenum target, GLenum pname);
+
+ [StrictTypeChecking, Custom, RaisesException] any getUniform(WebGLProgram program, WebGLUniformLocation location);
+
+ [StrictTypeChecking, RaisesException] WebGLUniformLocation getUniformLocation(WebGLProgram program, DOMString name);
+
+ [StrictTypeChecking, Custom, RaisesException] any getVertexAttrib(GLuint index, GLenum pname);
+
+ [StrictTypeChecking] GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname);
+
+ [StrictTypeChecking] void hint(GLenum target, GLenum mode);
+ [StrictTypeChecking] GLboolean isBuffer(WebGLBuffer buffer);
+ [StrictTypeChecking] GLboolean isContextLost();
+ [StrictTypeChecking] GLboolean isEnabled(GLenum cap);
+ [StrictTypeChecking] GLboolean isFramebuffer(WebGLFramebuffer framebuffer);
+ [StrictTypeChecking] GLboolean isProgram(WebGLProgram program);
+ [StrictTypeChecking] GLboolean isRenderbuffer(WebGLRenderbuffer renderbuffer);
+ [StrictTypeChecking] GLboolean isShader(WebGLShader shader);
+ [StrictTypeChecking] GLboolean isTexture(WebGLTexture texture);
+ [StrictTypeChecking] void lineWidth(GLfloat width);
+ [StrictTypeChecking, RaisesException] void linkProgram(WebGLProgram program);
+ [StrictTypeChecking] void pixelStorei(GLenum pname, GLint param);
+ [StrictTypeChecking] void polygonOffset(GLfloat factor, GLfloat units);
+
+ [StrictTypeChecking, RaisesException] void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView pixels);
+
+ [StrictTypeChecking] void releaseShaderCompiler();
+ [StrictTypeChecking] void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ [StrictTypeChecking] void sampleCoverage(GLclampf value, GLboolean invert);
+ [StrictTypeChecking] void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+ [StrictTypeChecking, RaisesException] void shaderSource(WebGLShader shader, DOMString string);
+ [StrictTypeChecking] void stencilFunc(GLenum func, GLint ref, GLuint mask);
+ [StrictTypeChecking] void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+ [StrictTypeChecking] void stencilMask(GLuint mask);
+ [StrictTypeChecking] void stencilMaskSeparate(GLenum face, GLuint mask);
+ [StrictTypeChecking] void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+ [StrictTypeChecking] void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+
+ [StrictTypeChecking] void texParameterf(GLenum target, GLenum pname, GLfloat param);
+ [StrictTypeChecking] void texParameteri(GLenum target, GLenum pname, GLint param);
+
+ // Supported forms:
+ [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+ GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
+ [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, ImageData? pixels);
+ [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLImageElement? image);
+ [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLCanvasElement? canvas);
+#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
+ [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLVideoElement? video);
+#endif
+
+ [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, ArrayBufferView? pixels);
+ [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, ImageData? pixels);
+ [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLImageElement? image);
+ [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLCanvasElement? canvas);
+#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
+ [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLVideoElement? video);
+#endif
+
+ [StrictTypeChecking, RaisesException] void uniform1f(WebGLUniformLocation location, GLfloat x);
+ [StrictTypeChecking, Custom, RaisesException] void uniform1fv(WebGLUniformLocation location, Float32Array v);
+ [StrictTypeChecking, RaisesException] void uniform1i(WebGLUniformLocation location, GLint x);
+ [StrictTypeChecking, Custom, RaisesException] void uniform1iv(WebGLUniformLocation location, Int32Array v);
+ [StrictTypeChecking, RaisesException] void uniform2f(WebGLUniformLocation location, GLfloat x, GLfloat y);
+ [StrictTypeChecking, Custom, RaisesException] void uniform2fv(WebGLUniformLocation location, Float32Array v);
+ [StrictTypeChecking, RaisesException] void uniform2i(WebGLUniformLocation location, GLint x, GLint y);
+ [StrictTypeChecking, Custom, RaisesException] void uniform2iv(WebGLUniformLocation location, Int32Array v);
+ [StrictTypeChecking, RaisesException] void uniform3f(WebGLUniformLocation location, GLfloat x, GLfloat y, GLfloat z);
+ [StrictTypeChecking, Custom, RaisesException] void uniform3fv(WebGLUniformLocation location, Float32Array v);
+ [StrictTypeChecking, RaisesException] void uniform3i(WebGLUniformLocation location, GLint x, GLint y, GLint z);
+ [StrictTypeChecking, Custom, RaisesException] void uniform3iv(WebGLUniformLocation location, Int32Array v);
+ [StrictTypeChecking, RaisesException] void uniform4f(WebGLUniformLocation location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ [StrictTypeChecking, Custom, RaisesException] void uniform4fv(WebGLUniformLocation location, Float32Array v);
+ [StrictTypeChecking, RaisesException] void uniform4i(WebGLUniformLocation location, GLint x, GLint y, GLint z, GLint w);
+ [StrictTypeChecking, Custom, RaisesException] void uniform4iv(WebGLUniformLocation location, Int32Array v);
+
+ [StrictTypeChecking, Custom, RaisesException] void uniformMatrix2fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
+ [StrictTypeChecking, Custom, RaisesException] void uniformMatrix3fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
+ [StrictTypeChecking, Custom, RaisesException] void uniformMatrix4fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
+
+ [StrictTypeChecking, RaisesException] void useProgram(WebGLProgram program);
+ [StrictTypeChecking, RaisesException] void validateProgram(WebGLProgram program);
+
+ [StrictTypeChecking] void vertexAttrib1f(GLuint indx, GLfloat x);
+ [StrictTypeChecking, Custom] void vertexAttrib1fv(GLuint indx, Float32Array values);
+ [StrictTypeChecking] void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
+ [StrictTypeChecking, Custom] void vertexAttrib2fv(GLuint indx, Float32Array values);
+ [StrictTypeChecking] void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+ [StrictTypeChecking, Custom] void vertexAttrib3fv(GLuint indx, Float32Array values);
+ [StrictTypeChecking] void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ [StrictTypeChecking, Custom] void vertexAttrib4fv(GLuint indx, Float32Array values);
+ [StrictTypeChecking, RaisesException] void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized,
+ GLsizei stride, GLintptr offset);
+
+ [StrictTypeChecking] void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
};
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp b/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
deleted file mode 100644
index 6d75fff35..000000000
--- a/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
+++ /dev/null
@@ -1,5093 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL)
-#include "WebGLRenderingContextBase.h"
-
-#include "ANGLEInstancedArrays.h"
-#include "CachedImage.h"
-#include "DOMWindow.h"
-#include "Document.h"
-#include "EXTBlendMinMax.h"
-#include "EXTFragDepth.h"
-#include "EXTShaderTextureLOD.h"
-#include "EXTTextureFilterAnisotropic.h"
-#include "EXTsRGB.h"
-#include "ExceptionCode.h"
-#include "Extensions3D.h"
-#include "Frame.h"
-#include "FrameLoader.h"
-#include "FrameLoaderClient.h"
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "HTMLCanvasElement.h"
-#include "HTMLImageElement.h"
-#include "HTMLVideoElement.h"
-#include "ImageBuffer.h"
-#include "ImageData.h"
-#include "IntSize.h"
-#include "Logging.h"
-#include "MainFrame.h"
-#include "NotImplemented.h"
-#include "OESElementIndexUint.h"
-#include "OESStandardDerivatives.h"
-#include "OESTextureFloat.h"
-#include "OESTextureFloatLinear.h"
-#include "OESTextureHalfFloat.h"
-#include "OESTextureHalfFloatLinear.h"
-#include "OESVertexArrayObject.h"
-#include "Page.h"
-#include "RenderBox.h"
-#include "Settings.h"
-#include "WebGL2RenderingContext.h"
-#include "WebGLActiveInfo.h"
-#include "WebGLBuffer.h"
-#include "WebGLCompressedTextureATC.h"
-#include "WebGLCompressedTexturePVRTC.h"
-#include "WebGLCompressedTextureS3TC.h"
-#include "WebGLContextAttributes.h"
-#include "WebGLContextEvent.h"
-#include "WebGLContextGroup.h"
-#include "WebGLDebugRendererInfo.h"
-#include "WebGLDebugShaders.h"
-#include "WebGLDepthTexture.h"
-#include "WebGLDrawBuffers.h"
-#include "WebGLFramebuffer.h"
-#include "WebGLLoseContext.h"
-#include "WebGLProgram.h"
-#include "WebGLRenderbuffer.h"
-#include "WebGLRenderingContext.h"
-#include "WebGLShader.h"
-#include "WebGLShaderPrecisionFormat.h"
-#include "WebGLTexture.h"
-#include "WebGLUniformLocation.h"
-
-#include <runtime/JSCInlines.h>
-#include <runtime/TypedArrayInlines.h>
-#include <runtime/Uint32Array.h>
-#include <wtf/CheckedArithmetic.h>
-#include <wtf/StdLibExtras.h>
-#include <wtf/text/CString.h>
-#include <wtf/text/StringBuilder.h>
-
-namespace WebCore {
-
-const double secondsBetweenRestoreAttempts = 1.0;
-const int maxGLErrorsAllowedToConsole = 256;
-
-namespace {
-
- Platform3DObject objectOrZero(WebGLObject* object)
- {
- return object ? object->object() : 0;
- }
-
- GC3Dint clamp(GC3Dint value, GC3Dint min, GC3Dint max)
- {
- if (value < min)
- value = min;
- if (value > max)
- value = max;
- return value;
- }
-
- // Return true if a character belongs to the ASCII subset as defined in
- // GLSL ES 1.0 spec section 3.1.
- bool validateCharacter(unsigned char c)
- {
- // Printing characters are valid except " $ ` @ \ ' DEL.
- if (c >= 32 && c <= 126
- && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
- return true;
- // Horizontal tab, line feed, vertical tab, form feed, carriage return
- // are also valid.
- if (c >= 9 && c <= 13)
- return true;
- return false;
- }
-
- bool isPrefixReserved(const String& name)
- {
- if (name.startsWith("gl_") || name.startsWith("webgl_") || name.startsWith("_webgl_"))
- return true;
- return false;
- }
-
- // Strips comments from shader text. This allows non-ASCII characters
- // to be used in comments without potentially breaking OpenGL
- // implementations not expecting characters outside the GLSL ES set.
- class StripComments {
- public:
- StripComments(const String& str)
- : m_parseState(BeginningOfLine)
- , m_sourceString(str)
- , m_length(str.length())
- , m_position(0)
- {
- parse();
- }
-
- String result()
- {
- return m_builder.toString();
- }
-
- private:
- bool hasMoreCharacters() const
- {
- return (m_position < m_length);
- }
-
- void parse()
- {
- while (hasMoreCharacters()) {
- process(current());
- // process() might advance the position.
- if (hasMoreCharacters())
- advance();
- }
- }
-
- void process(UChar);
-
- bool peek(UChar& character) const
- {
- if (m_position + 1 >= m_length)
- return false;
- character = m_sourceString[m_position + 1];
- return true;
- }
-
- UChar current() const
- {
- ASSERT_WITH_SECURITY_IMPLICATION(m_position < m_length);
- return m_sourceString[m_position];
- }
-
- void advance()
- {
- ++m_position;
- }
-
- bool isNewline(UChar character) const
- {
- // Don't attempt to canonicalize newline related characters.
- return (character == '\n' || character == '\r');
- }
-
- void emit(UChar character)
- {
- m_builder.append(character);
- }
-
- enum ParseState {
- // Have not seen an ASCII non-whitespace character yet on
- // this line. Possible that we might see a preprocessor
- // directive.
- BeginningOfLine,
-
- // Have seen at least one ASCII non-whitespace character
- // on this line.
- MiddleOfLine,
-
- // Handling a preprocessor directive. Passes through all
- // characters up to the end of the line. Disables comment
- // processing.
- InPreprocessorDirective,
-
- // Handling a single-line comment. The comment text is
- // replaced with a single space.
- InSingleLineComment,
-
- // Handling a multi-line comment. Newlines are passed
- // through to preserve line numbers.
- InMultiLineComment
- };
-
- ParseState m_parseState;
- String m_sourceString;
- unsigned m_length;
- unsigned m_position;
- StringBuilder m_builder;
- };
-
- void StripComments::process(UChar c)
- {
- if (isNewline(c)) {
- // No matter what state we are in, pass through newlines
- // so we preserve line numbers.
- emit(c);
-
- if (m_parseState != InMultiLineComment)
- m_parseState = BeginningOfLine;
-
- return;
- }
-
- UChar temp = 0;
- switch (m_parseState) {
- case BeginningOfLine:
- if (WTF::isASCIISpace(c)) {
- emit(c);
- break;
- }
-
- if (c == '#') {
- m_parseState = InPreprocessorDirective;
- emit(c);
- break;
- }
-
- // Transition to normal state and re-handle character.
- m_parseState = MiddleOfLine;
- process(c);
- break;
-
- case MiddleOfLine:
- if (c == '/' && peek(temp)) {
- if (temp == '/') {
- m_parseState = InSingleLineComment;
- emit(' ');
- advance();
- break;
- }
-
- if (temp == '*') {
- m_parseState = InMultiLineComment;
- // Emit the comment start in case the user has
- // an unclosed comment and we want to later
- // signal an error.
- emit('/');
- emit('*');
- advance();
- break;
- }
- }
-
- emit(c);
- break;
-
- case InPreprocessorDirective:
- // No matter what the character is, just pass it
- // through. Do not parse comments in this state. This
- // might not be the right thing to do long term, but it
- // should handle the #error preprocessor directive.
- emit(c);
- break;
-
- case InSingleLineComment:
- // The newline code at the top of this function takes care
- // of resetting our state when we get out of the
- // single-line comment. Swallow all other characters.
- break;
-
- case InMultiLineComment:
- if (c == '*' && peek(temp) && temp == '/') {
- emit('*');
- emit('/');
- m_parseState = MiddleOfLine;
- advance();
- break;
- }
-
- // Swallow all other characters. Unclear whether we may
- // want or need to just emit a space per character to try
- // to preserve column numbers for debugging purposes.
- break;
- }
- }
-} // namespace anonymous
-
-class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostCallback {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit WebGLRenderingContextLostCallback(WebGLRenderingContextBase* cb) : m_context(cb) { }
- virtual void onContextLost() override { m_context->forceLostContext(WebGLRenderingContext::RealLostContext); }
- virtual ~WebGLRenderingContextLostCallback() {}
-private:
- WebGLRenderingContextBase* m_context;
-};
-
-class WebGLRenderingContextErrorMessageCallback : public GraphicsContext3D::ErrorMessageCallback {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit WebGLRenderingContextErrorMessageCallback(WebGLRenderingContextBase* cb) : m_context(cb) { }
- virtual void onErrorMessage(const String& message, GC3Dint) override
- {
- if (m_context->m_synthesizedErrorsToConsole)
- m_context->printGLErrorToConsole(message);
- }
- virtual ~WebGLRenderingContextErrorMessageCallback() { }
-private:
- WebGLRenderingContextBase* m_context;
-};
-
-std::unique_ptr<WebGLRenderingContextBase> WebGLRenderingContextBase::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs, const String& type)
-{
-#if !ENABLE(WEBGL2)
- UNUSED_PARAM(type);
-#endif
-
- Document& document = canvas->document();
- Frame* frame = document.frame();
- if (!frame)
- return nullptr;
-
- // The FrameLoaderClient might block creation of a new WebGL context despite the page settings; in
- // particular, if WebGL contexts were lost one or more times via the GL_ARB_robustness extension.
- if (!frame->loader().client().allowWebGL(frame->settings().webGLEnabled())) {
- canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Web page was not allowed to create a WebGL context."));
- return nullptr;
- }
-
- bool isPendingPolicyResolution = false;
- Document& topDocument = document.topDocument();
- Page* page = topDocument.page();
- bool forcingPendingPolicy = frame->settings().isForcePendingWebGLPolicy();
-
- if (forcingPendingPolicy || (page && !topDocument.url().isLocalFile())) {
- WebGLLoadPolicy policy = forcingPendingPolicy ? WebGLPendingCreation : page->mainFrame().loader().client().webGLPolicyForURL(topDocument.url());
-
- if (policy == WebGLBlockCreation) {
- LOG(WebGL, "The policy for this URL (%s) is to block WebGL.", topDocument.url().host().utf8().data());
- return nullptr;
- }
-
- if (policy == WebGLPendingCreation) {
- LOG(WebGL, "WebGL policy is pending. May need to be resolved later.");
- isPendingPolicyResolution = true;
- }
- }
-
- GraphicsContext3D::Attributes attributes = attrs ? attrs->attributes() : GraphicsContext3D::Attributes();
-
- if (attributes.antialias) {
- if (!frame->settings().openGLMultisamplingEnabled())
- attributes.antialias = false;
- }
-
- attributes.noExtensions = true;
- attributes.shareResources = false;
- attributes.preferDiscreteGPU = true;
-
- if (frame->settings().forceSoftwareWebGLRendering())
- attributes.forceSoftwareRenderer = true;
-
- if (page)
- attributes.devicePixelRatio = page->deviceScaleFactor();
-
- if (isPendingPolicyResolution) {
- LOG(WebGL, "Create a WebGL context that looks real, but will require a policy resolution if used.");
- std::unique_ptr<WebGLRenderingContextBase> renderingContext = nullptr;
-#if ENABLE(WEBGL2)
- if (type == "experimental-webgl2")
- renderingContext = std::unique_ptr<WebGL2RenderingContext>(new WebGL2RenderingContext(canvas, attributes));
- else
-#endif
- renderingContext = std::unique_ptr<WebGLRenderingContext>(new WebGLRenderingContext(canvas, attributes));
- renderingContext->suspendIfNeeded();
- return renderingContext;
- }
-
- HostWindow* hostWindow = document.view()->root()->hostWindow();
- RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes, hostWindow));
-
- if (!context || !context->makeContextCurrent()) {
- canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Could not create a WebGL context."));
- return nullptr;
- }
-
- Extensions3D* extensions = context->getExtensions();
- if (extensions->supports("GL_EXT_debug_marker"))
- extensions->pushGroupMarkerEXT("WebGLRenderingContext");
-
- std::unique_ptr<WebGLRenderingContextBase> renderingContext = nullptr;
-#if ENABLE(WEBGL2)
- if (type == "experimental-webgl2")
- renderingContext = std::unique_ptr<WebGL2RenderingContext>(new WebGL2RenderingContext(canvas, context, attributes));
- else
-#endif
- renderingContext = std::unique_ptr<WebGLRenderingContext>(new WebGLRenderingContext(canvas, context, attributes));
- renderingContext->suspendIfNeeded();
-
- return renderingContext;
-}
-
-WebGLRenderingContextBase::WebGLRenderingContextBase(HTMLCanvasElement* passedCanvas, GraphicsContext3D::Attributes attributes)
- : CanvasRenderingContext(passedCanvas)
- , ActiveDOMObject(&passedCanvas->document())
- , m_context(0)
- , m_dispatchContextLostEventTimer(*this, &WebGLRenderingContextBase::dispatchContextLostEvent)
- , m_restoreAllowed(false)
- , m_restoreTimer(*this, &WebGLRenderingContextBase::maybeRestoreContext)
- , m_generatedImageCache(0)
- , m_contextLost(false)
- , m_contextLostMode(SyntheticLostContext)
- , m_attributes(attributes)
- , m_synthesizedErrorsToConsole(true)
- , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
- , m_isPendingPolicyResolution(true)
- , m_hasRequestedPolicyResolution(false)
-{
-}
-
-WebGLRenderingContextBase::WebGLRenderingContextBase(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context, GraphicsContext3D::Attributes attributes)
- : CanvasRenderingContext(passedCanvas)
- , ActiveDOMObject(&passedCanvas->document())
- , m_context(context)
- , m_dispatchContextLostEventTimer(*this, &WebGLRenderingContextBase::dispatchContextLostEvent)
- , m_restoreAllowed(false)
- , m_restoreTimer(*this, &WebGLRenderingContextBase::maybeRestoreContext)
- , m_generatedImageCache(4)
- , m_contextLost(false)
- , m_contextLostMode(SyntheticLostContext)
- , m_attributes(attributes)
- , m_synthesizedErrorsToConsole(true)
- , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
- , m_isPendingPolicyResolution(false)
- , m_hasRequestedPolicyResolution(false)
-{
- ASSERT(m_context);
- m_contextGroup = WebGLContextGroup::create();
- m_contextGroup->addContext(this);
-
- m_context->setWebGLContext(this);
-
- m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDims);
-
- setupFlags();
- initializeNewContext();
-}
-
-void WebGLRenderingContextBase::initializeNewContext()
-{
- ASSERT(!m_contextLost);
- m_needsUpdate = true;
- m_markedCanvasDirty = false;
- m_activeTextureUnit = 0;
- m_packAlignment = 4;
- m_unpackAlignment = 4;
- m_unpackFlipY = false;
- m_unpackPremultiplyAlpha = false;
- m_unpackColorspaceConversion = GraphicsContext3D::BROWSER_DEFAULT_WEBGL;
- m_boundArrayBuffer = nullptr;
- m_currentProgram = nullptr;
- m_framebufferBinding = nullptr;
- m_renderbufferBinding = nullptr;
- m_depthMask = true;
- m_stencilEnabled = false;
- m_stencilMask = 0xFFFFFFFF;
- m_stencilMaskBack = 0xFFFFFFFF;
- m_stencilFuncRef = 0;
- m_stencilFuncRefBack = 0;
- m_stencilFuncMask = 0xFFFFFFFF;
- m_stencilFuncMaskBack = 0xFFFFFFFF;
- m_layerCleared = false;
- m_numGLErrorsToConsoleAllowed = maxGLErrorsAllowedToConsole;
-
- m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0;
- m_scissorEnabled = false;
- m_clearDepth = 1;
- m_clearStencil = 0;
- m_colorMask[0] = m_colorMask[1] = m_colorMask[2] = m_colorMask[3] = true;
-
- GC3Dint numCombinedTextureImageUnits = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
- m_textureUnits.clear();
- m_textureUnits.resize(numCombinedTextureImageUnits);
-
- GC3Dint numVertexAttribs = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &numVertexAttribs);
- m_maxVertexAttribs = numVertexAttribs;
-
- m_maxTextureSize = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize);
- m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
- m_maxCubeMapTextureSize = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
- m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
- m_maxRenderbufferSize = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_RENDERBUFFER_SIZE, &m_maxRenderbufferSize);
-
- // These two values from EXT_draw_buffers are lazily queried.
- m_maxDrawBuffers = 0;
- m_maxColorAttachments = 0;
-
- m_backDrawBuffer = GraphicsContext3D::BACK;
- m_drawBuffersWebGLRequirementsChecked = false;
- m_drawBuffersSupported = false;
-
- m_vertexAttribValue.resize(m_maxVertexAttribs);
-
- if (!isGLES2NPOTStrict())
- createFallbackBlackTextures1x1();
-
- IntSize canvasSize = clampedCanvasSize();
- m_context->reshape(canvasSize.width(), canvasSize.height());
- m_context->viewport(0, 0, canvasSize.width(), canvasSize.height());
- m_context->scissor(0, 0, canvasSize.width(), canvasSize.height());
-
- m_context->setContextLostCallback(std::make_unique<WebGLRenderingContextLostCallback>(this));
- m_context->setErrorMessageCallback(std::make_unique<WebGLRenderingContextErrorMessageCallback>(this));
-}
-
-void WebGLRenderingContextBase::setupFlags()
-{
- ASSERT(m_context);
-
- if (Page* page = canvas()->document().page())
- m_synthesizedErrorsToConsole = page->settings().webGLErrorsToConsoleEnabled();
-
- m_isGLES2Compliant = m_context->isGLES2Compliant();
- m_isErrorGeneratedOnOutOfBoundsAccesses = m_context->getExtensions()->isEnabled("GL_CHROMIUM_strict_attribs");
- m_isResourceSafe = m_context->getExtensions()->isEnabled("GL_CHROMIUM_resource_safe");
- if (m_isGLES2Compliant) {
- m_isGLES2NPOTStrict = !m_context->getExtensions()->isEnabled("GL_OES_texture_npot");
- m_isDepthStencilSupported = m_context->getExtensions()->isEnabled("GL_OES_packed_depth_stencil");
- } else {
- m_isGLES2NPOTStrict = !m_context->getExtensions()->isEnabled("GL_ARB_texture_non_power_of_two");
- m_isDepthStencilSupported = m_context->getExtensions()->isEnabled("GL_EXT_packed_depth_stencil");
- }
- m_isRobustnessEXTSupported = m_context->getExtensions()->isEnabled("GL_EXT_robustness");
-}
-
-bool WebGLRenderingContextBase::allowPrivilegedExtensions() const
-{
- if (Page* page = canvas()->document().page())
- return page->settings().privilegedWebGLExtensionsEnabled();
- return false;
-}
-
-void WebGLRenderingContextBase::addCompressedTextureFormat(GC3Denum format)
-{
- if (!m_compressedTextureFormats.contains(format))
- m_compressedTextureFormats.append(format);
-}
-
-WebGLRenderingContextBase::~WebGLRenderingContextBase()
-{
- // Remove all references to WebGLObjects so if they are the last reference
- // they will be freed before the last context is removed from the context group.
- m_boundArrayBuffer = nullptr;
- m_defaultVertexArrayObject = nullptr;
- m_boundVertexArrayObject = nullptr;
- m_vertexAttrib0Buffer = nullptr;
- m_currentProgram = nullptr;
- m_framebufferBinding = nullptr;
- m_renderbufferBinding = nullptr;
-
- for (size_t i = 0; i < m_textureUnits.size(); ++i) {
- m_textureUnits[i].texture2DBinding = nullptr;
- m_textureUnits[i].textureCubeMapBinding = nullptr;
- }
-
- m_blackTexture2D = nullptr;
- m_blackTextureCubeMap = nullptr;
-
- if (!m_isPendingPolicyResolution) {
- detachAndRemoveAllObjects();
- destroyGraphicsContext3D();
- m_contextGroup->removeContext(this);
- }
-}
-
-void WebGLRenderingContextBase::destroyGraphicsContext3D()
-{
- if (m_isPendingPolicyResolution)
- return;
-
- if (m_context) {
- m_context->setContextLostCallback(nullptr);
- m_context->setErrorMessageCallback(nullptr);
- m_context = nullptr;
- }
-}
-
-void WebGLRenderingContextBase::markContextChanged()
-{
- if (m_framebufferBinding)
- return;
-
- m_context->markContextChanged();
-
- m_layerCleared = false;
- RenderBox* renderBox = canvas()->renderBox();
- if (isAccelerated() && renderBox && renderBox->hasAcceleratedCompositing()) {
- m_markedCanvasDirty = true;
- canvas()->clearCopiedImage();
- renderBox->contentChanged(CanvasChanged);
- } else {
- if (!m_markedCanvasDirty) {
- m_markedCanvasDirty = true;
- canvas()->didDraw(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
- }
- }
-}
-
-bool WebGLRenderingContextBase::clearIfComposited(GC3Dbitfield mask)
-{
- if (isContextLostOrPending())
- return false;
-
- if (!m_context->layerComposited() || m_layerCleared
- || m_attributes.preserveDrawingBuffer || (mask && m_framebufferBinding))
- return false;
-
- RefPtr<WebGLContextAttributes> contextAttributes = getContextAttributes();
-
- // Determine if it's possible to combine the clear the user asked for and this clear.
- bool combinedClear = mask && !m_scissorEnabled;
-
- m_context->disable(GraphicsContext3D::SCISSOR_TEST);
- if (combinedClear && (mask & GraphicsContext3D::COLOR_BUFFER_BIT))
- m_context->clearColor(m_colorMask[0] ? m_clearColor[0] : 0,
- m_colorMask[1] ? m_clearColor[1] : 0,
- m_colorMask[2] ? m_clearColor[2] : 0,
- m_colorMask[3] ? m_clearColor[3] : 0);
- else
- m_context->clearColor(0, 0, 0, 0);
- m_context->colorMask(true, true, true, true);
- GC3Dbitfield clearMask = GraphicsContext3D::COLOR_BUFFER_BIT;
- if (contextAttributes->depth()) {
- if (!combinedClear || !m_depthMask || !(mask & GraphicsContext3D::DEPTH_BUFFER_BIT))
- m_context->clearDepth(1.0f);
- clearMask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
- m_context->depthMask(true);
- }
- if (contextAttributes->stencil()) {
- if (combinedClear && (mask & GraphicsContext3D::STENCIL_BUFFER_BIT))
- m_context->clearStencil(m_clearStencil & m_stencilMask);
- else
- m_context->clearStencil(0);
- clearMask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
- m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, 0xFFFFFFFF);
- }
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
- m_context->clear(clearMask);
-
- restoreStateAfterClear();
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
- m_layerCleared = true;
-
- return combinedClear;
-}
-
-void WebGLRenderingContextBase::restoreStateAfterClear()
-{
- // Restore the state that the context set.
- if (m_scissorEnabled)
- m_context->enable(GraphicsContext3D::SCISSOR_TEST);
- m_context->clearColor(m_clearColor[0], m_clearColor[1],
- m_clearColor[2], m_clearColor[3]);
- m_context->colorMask(m_colorMask[0], m_colorMask[1],
- m_colorMask[2], m_colorMask[3]);
- m_context->clearDepth(m_clearDepth);
- m_context->clearStencil(m_clearStencil);
- m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, m_stencilMask);
- m_context->depthMask(m_depthMask);
-}
-
-void WebGLRenderingContextBase::markLayerComposited()
-{
- if (isContextLostOrPending())
- return;
- m_context->markLayerComposited();
-}
-
-void WebGLRenderingContextBase::paintRenderingResultsToCanvas()
-{
- if (isContextLostOrPending())
- return;
-
- if (canvas()->document().printing())
- canvas()->clearPresentationCopy();
-
- // Until the canvas is written to by the application, the clear that
- // happened after it was composited should be ignored by the compositor.
- if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer) {
- m_context->paintCompositedResultsToCanvas(canvas()->buffer());
-
- canvas()->makePresentationCopy();
- } else
- canvas()->clearPresentationCopy();
- clearIfComposited();
-
- if (!m_markedCanvasDirty && !m_layerCleared)
- return;
-
- canvas()->clearCopiedImage();
- m_markedCanvasDirty = false;
-
- m_context->paintRenderingResultsToCanvas(canvas()->buffer());
-}
-
-PassRefPtr<ImageData> WebGLRenderingContextBase::paintRenderingResultsToImageData()
-{
- if (isContextLostOrPending())
- return nullptr;
- clearIfComposited();
- return m_context->paintRenderingResultsToImageData();
-}
-
-void WebGLRenderingContextBase::reshape(int width, int height)
-{
- if (isContextLostOrPending())
- return;
-
- // This is an approximation because at WebGLRenderingContext level we don't
- // know if the underlying FBO uses textures or renderbuffers.
- GC3Dint maxSize = std::min(m_maxTextureSize, m_maxRenderbufferSize);
- // Limit drawing buffer size to 4k to avoid memory exhaustion.
- const int sizeUpperLimit = 4096;
- maxSize = std::min(maxSize, sizeUpperLimit);
- GC3Dint maxWidth = std::min(maxSize, m_maxViewportDims[0]);
- GC3Dint maxHeight = std::min(maxSize, m_maxViewportDims[1]);
- width = clamp(width, 1, maxWidth);
- height = clamp(height, 1, maxHeight);
-
- if (m_needsUpdate) {
- RenderBox* renderBox = canvas()->renderBox();
- if (renderBox && renderBox->hasAcceleratedCompositing())
- renderBox->contentChanged(CanvasChanged);
- m_needsUpdate = false;
- }
-
- // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off
- // clear (and this matches what reshape will do).
- m_context->reshape(width, height);
-
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(m_textureUnits[m_activeTextureUnit].texture2DBinding.get()));
- m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, objectOrZero(m_renderbufferBinding.get()));
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
-}
-
-int WebGLRenderingContextBase::drawingBufferWidth() const
-{
- if (m_isPendingPolicyResolution && !m_hasRequestedPolicyResolution)
- return 0;
-
- return m_context->getInternalFramebufferSize().width();
-}
-
-int WebGLRenderingContextBase::drawingBufferHeight() const
-{
- if (m_isPendingPolicyResolution && !m_hasRequestedPolicyResolution)
- return 0;
-
- return m_context->getInternalFramebufferSize().height();
-}
-
-unsigned WebGLRenderingContextBase::sizeInBytes(GC3Denum type)
-{
- switch (type) {
- case GraphicsContext3D::BYTE:
- return sizeof(GC3Dbyte);
- case GraphicsContext3D::UNSIGNED_BYTE:
- return sizeof(GC3Dubyte);
- case GraphicsContext3D::SHORT:
- return sizeof(GC3Dshort);
- case GraphicsContext3D::UNSIGNED_SHORT:
- return sizeof(GC3Dushort);
- case GraphicsContext3D::INT:
- return sizeof(GC3Dint);
- case GraphicsContext3D::UNSIGNED_INT:
- return sizeof(GC3Duint);
- case GraphicsContext3D::FLOAT:
- return sizeof(GC3Dfloat);
- }
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-void WebGLRenderingContextBase::activeTexture(GC3Denum texture, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return;
- if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "activeTexture", "texture unit out of range");
- return;
- }
- m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0;
- m_context->activeTexture(texture);
-}
-
-void WebGLRenderingContextBase::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
- return;
- if (!program->attachShader(shader)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "attachShader", "shader attachment already has shader");
- return;
- }
- m_context->attachShader(objectOrZero(program), objectOrZero(shader));
- shader->onAttached();
-}
-
-void WebGLRenderingContextBase::bindAttribLocation(WebGLProgram* program, GC3Duint index, const String& name, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("bindAttribLocation", program))
- return;
- if (!validateLocationLength("bindAttribLocation", name))
- return;
- if (!validateString("bindAttribLocation", name))
- return;
- if (isPrefixReserved(name)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindAttribLocation", "reserved prefix");
- return;
- }
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bindAttribLocation", "index out of range");
- return;
- }
- m_context->bindAttribLocation(objectOrZero(program), index, name);
-}
-
-bool WebGLRenderingContextBase::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted)
-{
- deleted = false;
- if (isContextLostOrPending())
- return false;
- if (object) {
- if (!object->validate(contextGroup(), this)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object not from this context");
- return false;
- }
- deleted = !object->object();
- }
- return true;
-}
-
-void WebGLRenderingContextBase::bindBuffer(GC3Denum target, WebGLBuffer* buffer, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- bool deleted;
- if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
- return;
- if (deleted)
- buffer = 0;
- if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindBuffer", "buffers can not be used with multiple targets");
- return;
- }
- if (target == GraphicsContext3D::ARRAY_BUFFER)
- m_boundArrayBuffer = buffer;
- else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
- m_boundVertexArrayObject->setElementArrayBuffer(buffer);
- else {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindBuffer", "invalid target");
- return;
- }
-
- m_context->bindBuffer(target, objectOrZero(buffer));
- if (buffer)
- buffer->setTarget(target);
-}
-
-void WebGLRenderingContextBase::bindFramebuffer(GC3Denum target, WebGLFramebuffer* buffer, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- bool deleted;
- if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
- return;
- if (deleted)
- buffer = 0;
- if (target != GraphicsContext3D::FRAMEBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindFramebuffer", "invalid target");
- return;
- }
- m_framebufferBinding = buffer;
- m_context->bindFramebuffer(target, objectOrZero(buffer));
- if (buffer)
- buffer->setHasEverBeenBound();
- applyStencilTest();
-}
-
-void WebGLRenderingContextBase::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- bool deleted;
- if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
- return;
- if (deleted)
- renderBuffer = 0;
- if (target != GraphicsContext3D::RENDERBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindRenderbuffer", "invalid target");
- return;
- }
- m_renderbufferBinding = renderBuffer;
- m_context->bindRenderbuffer(target, objectOrZero(renderBuffer));
- if (renderBuffer)
- renderBuffer->setHasEverBeenBound();
-}
-
-void WebGLRenderingContextBase::bindTexture(GC3Denum target, WebGLTexture* texture, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- bool deleted;
- if (!checkObjectToBeBound("bindTexture", texture, deleted))
- return;
- if (deleted)
- texture = 0;
- if (texture && texture->getTarget() && texture->getTarget() != target) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
- return;
- }
- GC3Dint maxLevel = 0;
- if (target == GraphicsContext3D::TEXTURE_2D) {
- m_textureUnits[m_activeTextureUnit].texture2DBinding = texture;
- maxLevel = m_maxTextureLevel;
- } else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
- m_textureUnits[m_activeTextureUnit].textureCubeMapBinding = texture;
- maxLevel = m_maxCubeMapTextureLevel;
- } else {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindTexture", "invalid target");
- return;
- }
- m_context->bindTexture(target, objectOrZero(texture));
- if (texture)
- texture->setTarget(target, maxLevel);
-
- // Note: previously we used to automatically set the TEXTURE_WRAP_R
- // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL
- // ES 2.0 doesn't expose this flag (a bug in the specification) and
- // otherwise the application has no control over the seams in this
- // dimension. However, it appears that supporting this properly on all
- // platforms is fairly involved (will require a HashMap from texture ID
- // in all ports), and we have not had any complaints, so the logic has
- // been removed.
-}
-
-void WebGLRenderingContextBase::blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha)
-{
- if (isContextLostOrPending())
- return;
- m_context->blendColor(red, green, blue, alpha);
-}
-
-void WebGLRenderingContextBase::blendEquation(GC3Denum mode)
-{
- if (isContextLostOrPending() || !validateBlendEquation("blendEquation", mode))
- return;
- m_context->blendEquation(mode);
-}
-
-void WebGLRenderingContextBase::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
-{
- if (isContextLostOrPending() || !validateBlendEquation("blendEquation", modeRGB) || !validateBlendEquation("blendEquation", modeAlpha))
- return;
- m_context->blendEquationSeparate(modeRGB, modeAlpha);
-}
-
-
-void WebGLRenderingContextBase::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
-{
- if (isContextLostOrPending() || !validateBlendFuncFactors("blendFunc", sfactor, dfactor))
- return;
- m_context->blendFunc(sfactor, dfactor);
-}
-
-void WebGLRenderingContextBase::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
-{
- // Note: Alpha does not have the same restrictions as RGB.
- if (isContextLostOrPending() || !validateBlendFuncFactors("blendFunc", srcRGB, dstRGB))
- return;
- m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
-}
-
-void WebGLRenderingContextBase::bufferData(GC3Denum target, long long size, GC3Denum usage, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
- if (!buffer)
- return;
- if (size < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "size < 0");
- return;
- }
- if (!size) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "size == 0");
- return;
- }
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferData(static_cast<GC3Dsizeiptr>(size))) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
- return;
- }
- }
-
- m_context->moveErrorsToSyntheticErrorList();
- m_context->bufferData(target, static_cast<GC3Dsizeiptr>(size), usage);
- if (m_context->moveErrorsToSyntheticErrorList()) {
- // The bufferData function failed. Tell the buffer it doesn't have the data it thinks it does.
- buffer->disassociateBufferData();
- }
-}
-
-void WebGLRenderingContextBase::bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
- if (!buffer)
- return;
- if (!data) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "no data");
- return;
- }
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferData(data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
- return;
- }
- }
-
- m_context->moveErrorsToSyntheticErrorList();
- m_context->bufferData(target, data->byteLength(), data->data(), usage);
- if (m_context->moveErrorsToSyntheticErrorList()) {
- // The bufferData function failed. Tell the buffer it doesn't have the data it thinks it does.
- buffer->disassociateBufferData();
- }
-}
-
-void WebGLRenderingContextBase::bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
- if (!buffer)
- return;
- if (!data) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "no data");
- return;
- }
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferData(data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
- return;
- }
- }
-
- m_context->moveErrorsToSyntheticErrorList();
- m_context->bufferData(target, data->byteLength(), data->baseAddress(), usage);
- if (m_context->moveErrorsToSyntheticErrorList()) {
- // The bufferData function failed. Tell the buffer it doesn't have the data it thinks it does.
- buffer->disassociateBufferData();
- }
-}
-
-void WebGLRenderingContextBase::bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW);
- if (!buffer)
- return;
- if (offset < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset < 0");
- return;
- }
- if (!data)
- return;
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferSubData(static_cast<GC3Dintptr>(offset), data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset out of range");
- return;
- }
- }
-
- m_context->moveErrorsToSyntheticErrorList();
- m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->data());
- if (m_context->moveErrorsToSyntheticErrorList()) {
- // The bufferSubData function failed. Tell the buffer it doesn't have the data it thinks it does.
- buffer->disassociateBufferData();
- }
-}
-
-void WebGLRenderingContextBase::bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW);
- if (!buffer)
- return;
- if (offset < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset < 0");
- return;
- }
- if (!data)
- return;
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferSubData(static_cast<GC3Dintptr>(offset), data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset out of range");
- return;
- }
- }
-
- m_context->moveErrorsToSyntheticErrorList();
- m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->baseAddress());
- if (m_context->moveErrorsToSyntheticErrorList()) {
- // The bufferSubData function failed. Tell the buffer it doesn't have the data it thinks it does.
- buffer->disassociateBufferData();
- }
-}
-
-GC3Denum WebGLRenderingContextBase::checkFramebufferStatus(GC3Denum target)
-{
- if (isContextLostOrPending())
- return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
- if (target != GraphicsContext3D::FRAMEBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "checkFramebufferStatus", "invalid target");
- return 0;
- }
- if (!m_framebufferBinding || !m_framebufferBinding->object())
- return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
- const char* reason = "framebuffer incomplete";
- GC3Denum result = m_framebufferBinding->checkStatus(&reason);
- if (result != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
- printGLWarningToConsole("checkFramebufferStatus", reason);
- return result;
- }
- result = m_context->checkFramebufferStatus(target);
- return result;
-}
-
-void WebGLRenderingContextBase::clearColor(GC3Dfloat r, GC3Dfloat g, GC3Dfloat b, GC3Dfloat a)
-{
- if (isContextLostOrPending())
- return;
- if (std::isnan(r))
- r = 0;
- if (std::isnan(g))
- g = 0;
- if (std::isnan(b))
- b = 0;
- if (std::isnan(a))
- a = 1;
- m_clearColor[0] = r;
- m_clearColor[1] = g;
- m_clearColor[2] = b;
- m_clearColor[3] = a;
- m_context->clearColor(r, g, b, a);
-}
-
-void WebGLRenderingContextBase::clearDepth(GC3Dfloat depth)
-{
- if (isContextLostOrPending())
- return;
- m_clearDepth = depth;
- m_context->clearDepth(depth);
-}
-
-void WebGLRenderingContextBase::clearStencil(GC3Dint s)
-{
- if (isContextLostOrPending())
- return;
- m_clearStencil = s;
- m_context->clearStencil(s);
-}
-
-void WebGLRenderingContextBase::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha)
-{
- if (isContextLostOrPending())
- return;
- m_colorMask[0] = red;
- m_colorMask[1] = green;
- m_colorMask[2] = blue;
- m_colorMask[3] = alpha;
- m_context->colorMask(red, green, blue, alpha);
-}
-
-void WebGLRenderingContextBase::compileShader(WebGLShader* shader, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("compileShader", shader))
- return;
- m_context->compileShader(objectOrZero(shader));
- GC3Dint value;
- m_context->getShaderiv(objectOrZero(shader), GraphicsContext3D::COMPILE_STATUS, &value);
- shader->setValid(value);
-}
-
-void WebGLRenderingContextBase::compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
- GC3Dsizei height, GC3Dint border, ArrayBufferView* data)
-{
- if (isContextLostOrPending())
- return;
- if (!validateTexFuncLevel("compressedTexImage2D", target, level))
- return;
-
- if (!validateCompressedTexFormat(internalformat)) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexImage2D", "invalid internalformat");
- return;
- }
- if (border) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "compressedTexImage2D", "border not 0");
- return;
- }
- if (!validateCompressedTexDimensions("compressedTexImage2D", target, level, width, height, internalformat))
- return;
- if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
- return;
-
- WebGLTexture* tex = validateTextureBinding("compressedTexImage2D", target, true);
- if (!tex)
- return;
- if (!isGLES2NPOTStrict()) {
- if (level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "compressedTexImage2D", "level > 0 not power of 2");
- return;
- }
- }
- m_context->moveErrorsToSyntheticErrorList();
- m_context->compressedTexImage2D(target, level, internalformat, width, height,
- border, data->byteLength(), data->baseAddress());
- if (m_context->moveErrorsToSyntheticErrorList()) {
- // The compressedTexImage2D function failed. Tell the WebGLTexture it doesn't have the data for this level.
- tex->markInvalid(target, level);
- return;
- }
-
- tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
- tex->setCompressed();
-}
-
-void WebGLRenderingContextBase::compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data)
-{
- if (isContextLostOrPending())
- return;
- if (!validateTexFuncLevel("compressedTexSubImage2D", target, level))
- return;
- if (!validateCompressedTexFormat(format)) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexSubImage2D", "invalid format");
- return;
- }
- if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, format, data))
- return;
-
- WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target, true);
- if (!tex)
- return;
-
- if (format != tex->getInternalFormat(target, level)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "compressedTexSubImage2D", "format does not match texture format");
- return;
- }
-
- if (!validateCompressedTexSubDimensions("compressedTexSubImage2D", target, level, xoffset, yoffset, width, height, format, tex))
- return;
-
- graphicsContext3D()->compressedTexSubImage2D(target, level, xoffset, yoffset,
- width, height, format, data->byteLength(), data->baseAddress());
- tex->setCompressed();
-}
-
-bool WebGLRenderingContextBase::validateSettableTexFormat(const char* functionName, GC3Denum format)
-{
- if (GraphicsContext3D::getClearBitsByFormat(format) & (GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format can not be set, only rendered to");
- return false;
- }
- return true;
-}
-
-void WebGLRenderingContextBase::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLostOrPending())
- return;
- if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
- return;
- WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true);
- if (!tex)
- return;
- if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height))
- return;
- // Before checking if it is in the range, check if overflow happens first.
- if (xoffset + width < 0 || yoffset + height < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "bad dimensions");
- return;
- }
- if (xoffset + width > tex->getWidth(target, level) || yoffset + height > tex->getHeight(target, level)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range");
- return;
- }
- GC3Denum internalformat = tex->getInternalFormat(target, level);
- if (!validateSettableTexFormat("copyTexSubImage2D", internalformat))
- return;
- if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
- return;
- }
- clearIfComposited();
- if (isResourceSafe())
- m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
- else {
- GC3Dint clippedX, clippedY;
- GC3Dsizei clippedWidth, clippedHeight;
- if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
- GC3Denum format = tex->getInternalFormat(target, level);
- GC3Denum type = tex->getType(target, level);
- std::unique_ptr<unsigned char[]> zero;
- if (width && height) {
- unsigned int size;
- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, 0);
- if (error != GraphicsContext3D::NO_ERROR) {
- synthesizeGLError(error, "copyTexSubImage2D", "bad dimensions");
- return;
- }
- zero = std::make_unique<unsigned char[]>(size);
- if (!zero) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "out of memory");
- return;
- }
- memset(zero.get(), 0, size);
- }
- m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, zero.get());
- if (clippedWidth > 0 && clippedHeight > 0)
- m_context->copyTexSubImage2D(target, level, xoffset + clippedX - x, yoffset + clippedY - y,
- clippedX, clippedY, clippedWidth, clippedHeight);
- } else
- m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
- }
-}
-
-PassRefPtr<WebGLBuffer> WebGLRenderingContextBase::createBuffer()
-{
- if (isContextLostOrPending())
- return nullptr;
- RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLFramebuffer> WebGLRenderingContextBase::createFramebuffer()
-{
- if (isContextLostOrPending())
- return nullptr;
- RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
- addContextObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLTexture> WebGLRenderingContextBase::createTexture()
-{
- if (isContextLostOrPending())
- return nullptr;
- RefPtr<WebGLTexture> o = WebGLTexture::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLProgram> WebGLRenderingContextBase::createProgram()
-{
- if (isContextLostOrPending())
- return nullptr;
- RefPtr<WebGLProgram> o = WebGLProgram::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLRenderbuffer> WebGLRenderingContextBase::createRenderbuffer()
-{
- if (isContextLostOrPending())
- return nullptr;
- RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLShader> WebGLRenderingContextBase::createShader(GC3Denum type, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return nullptr;
- if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "createShader", "invalid shader type");
- return nullptr;
- }
-
- RefPtr<WebGLShader> o = WebGLShader::create(this, type);
- addSharedObject(o.get());
- return o;
-}
-
-void WebGLRenderingContextBase::cullFace(GC3Denum mode)
-{
- if (isContextLostOrPending())
- return;
- m_context->cullFace(mode);
-}
-
-bool WebGLRenderingContextBase::deleteObject(WebGLObject* object)
-{
- if (isContextLostOrPending() || !object)
- return false;
- if (!object->validate(contextGroup(), this)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "delete", "object does not belong to this context");
- return false;
- }
- if (object->object())
- // We need to pass in context here because we want
- // things in this context unbound.
- object->deleteObject(graphicsContext3D());
- return true;
-}
-
-void WebGLRenderingContextBase::deleteBuffer(WebGLBuffer* buffer)
-{
- if (!deleteObject(buffer))
- return;
- if (m_boundArrayBuffer == buffer)
- m_boundArrayBuffer = nullptr;
-
- m_boundVertexArrayObject->unbindBuffer(buffer);
-}
-
-void WebGLRenderingContextBase::deleteFramebuffer(WebGLFramebuffer* framebuffer)
-{
- if (!deleteObject(framebuffer))
- return;
- if (framebuffer == m_framebufferBinding) {
- m_framebufferBinding = nullptr;
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
- }
-}
-
-void WebGLRenderingContextBase::deleteProgram(WebGLProgram* program)
-{
- deleteObject(program);
- // We don't reset m_currentProgram to 0 here because the deletion of the
- // current program is delayed.
-}
-
-void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
-{
- if (!deleteObject(renderbuffer))
- return;
- if (renderbuffer == m_renderbufferBinding)
- m_renderbufferBinding = nullptr;
- if (m_framebufferBinding)
- m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer);
-}
-
-void WebGLRenderingContextBase::deleteShader(WebGLShader* shader)
-{
- deleteObject(shader);
-}
-
-void WebGLRenderingContextBase::deleteTexture(WebGLTexture* texture)
-{
- if (!deleteObject(texture))
- return;
- for (size_t i = 0; i < m_textureUnits.size(); ++i) {
- if (texture == m_textureUnits[i].texture2DBinding)
- m_textureUnits[i].texture2DBinding = nullptr;
- if (texture == m_textureUnits[i].textureCubeMapBinding)
- m_textureUnits[i].textureCubeMapBinding = nullptr;
- }
- if (m_framebufferBinding)
- m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
-}
-
-void WebGLRenderingContextBase::depthFunc(GC3Denum func)
-{
- if (isContextLostOrPending())
- return;
- m_context->depthFunc(func);
-}
-
-void WebGLRenderingContextBase::depthMask(GC3Dboolean flag)
-{
- if (isContextLostOrPending())
- return;
- m_depthMask = flag;
- m_context->depthMask(flag);
-}
-
-void WebGLRenderingContextBase::depthRange(GC3Dfloat zNear, GC3Dfloat zFar)
-{
- if (isContextLostOrPending())
- return;
- if (zNear > zFar) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "depthRange", "zNear > zFar");
- return;
- }
- m_context->depthRange(zNear, zFar);
-}
-
-void WebGLRenderingContextBase::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
- return;
- if (!program->detachShader(shader)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "detachShader", "shader not attached");
- return;
- }
- m_context->detachShader(objectOrZero(program), objectOrZero(shader));
- shader->onDetached(graphicsContext3D());
-}
-
-void WebGLRenderingContextBase::disable(GC3Denum cap)
-{
- if (isContextLostOrPending() || !validateCapability("disable", cap))
- return;
- if (cap == GraphicsContext3D::STENCIL_TEST) {
- m_stencilEnabled = false;
- applyStencilTest();
- return;
- }
- if (cap == GraphicsContext3D::SCISSOR_TEST)
- m_scissorEnabled = false;
- m_context->disable(cap);
-}
-
-void WebGLRenderingContextBase::disableVertexAttribArray(GC3Duint index, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return;
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "disableVertexAttribArray", "index out of range");
- return;
- }
-
- WebGLVertexArrayObjectBase::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
- state.enabled = false;
-
- if (index > 0 || isGLES2Compliant())
- m_context->disableVertexAttribArray(index);
-}
-
-bool WebGLRenderingContextBase::validateElementArraySize(GC3Dsizei count, GC3Denum type, GC3Dintptr offset)
-{
- RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
-
- if (!elementArrayBuffer)
- return false;
-
- if (offset < 0)
- return false;
-
- if (type == GraphicsContext3D::UNSIGNED_INT) {
- // For an unsigned int array, offset must be divisible by 4 for alignment reasons.
- if (offset % 4)
- return false;
-
- // Make uoffset an element offset.
- offset /= 4;
-
- GC3Dsizeiptr n = elementArrayBuffer->byteLength() / 4;
- if (offset > n || count > n - offset)
- return false;
- } else if (type == GraphicsContext3D::UNSIGNED_SHORT) {
- // For an unsigned short array, offset must be divisible by 2 for alignment reasons.
- if (offset % 2)
- return false;
-
- // Make uoffset an element offset.
- offset /= 2;
-
- GC3Dsizeiptr n = elementArrayBuffer->byteLength() / 2;
- if (offset > n || count > n - offset)
- return false;
- } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
- GC3Dsizeiptr n = elementArrayBuffer->byteLength();
- if (offset > n || count > n - offset)
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContextBase::validateIndexArrayPrecise(GC3Dsizei count, GC3Denum type, GC3Dintptr offset, unsigned& numElementsRequired)
-{
- ASSERT(count >= 0 && offset >= 0);
- unsigned lastIndex = 0;
-
- RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
-
- if (!elementArrayBuffer)
- return false;
-
- if (!count) {
- numElementsRequired = 0;
- return true;
- }
-
- if (!elementArrayBuffer->elementArrayBuffer())
- return false;
-
- unsigned long uoffset = offset;
- unsigned long n = count;
-
- if (type == GraphicsContext3D::UNSIGNED_INT) {
- // Make uoffset an element offset.
- uoffset /= sizeof(GC3Duint);
- const GC3Duint* p = static_cast<const GC3Duint*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
- while (n-- > 0) {
- if (*p > lastIndex)
- lastIndex = *p;
- ++p;
- }
- } else if (type == GraphicsContext3D::UNSIGNED_SHORT) {
- // Make uoffset an element offset.
- uoffset /= sizeof(GC3Dushort);
- const GC3Dushort* p = static_cast<const GC3Dushort*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
- while (n-- > 0) {
- if (*p > lastIndex)
- lastIndex = *p;
- ++p;
- }
- } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
- const GC3Dubyte* p = static_cast<const GC3Dubyte*>(elementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
- while (n-- > 0) {
- if (*p > lastIndex)
- lastIndex = *p;
- ++p;
- }
- }
-
- // Then set the last index in the index array and make sure it is valid.
- numElementsRequired = lastIndex + 1;
- return numElementsRequired > 0;
-}
-
-bool WebGLRenderingContextBase::validateVertexAttributes(unsigned elementCount, unsigned primitiveCount)
-{
- if (!m_currentProgram)
- return false;
-
- // Look in each enabled vertex attrib and check if they've been bound to a buffer.
- for (unsigned i = 0; i < m_maxVertexAttribs; ++i) {
- if (!m_boundVertexArrayObject->getVertexAttribState(i).validateBinding())
- return false;
- }
-
- if (elementCount <= 0)
- return true;
-
- // Look in each consumed vertex attrib (by the current program).
- bool sawNonInstancedAttrib = false;
- bool sawEnabledAttrib = false;
- int numActiveAttribLocations = m_currentProgram->numActiveAttribLocations();
- for (int i = 0; i < numActiveAttribLocations; ++i) {
- int loc = m_currentProgram->getActiveAttribLocation(i);
- if (loc >= 0 && loc < static_cast<int>(m_maxVertexAttribs)) {
- const WebGLVertexArrayObjectBase::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(loc);
- if (state.enabled) {
- sawEnabledAttrib = true;
- // Avoid off-by-one errors in numElements computation.
- // For the last element, we will only touch the data for the
- // element and nothing beyond it.
- int bytesRemaining = static_cast<int>(state.bufferBinding->byteLength() - state.offset);
- unsigned numElements = 0;
- ASSERT(state.stride > 0);
- if (bytesRemaining >= state.bytesPerElement)
- numElements = 1 + (bytesRemaining - state.bytesPerElement) / state.stride;
- unsigned instancesRequired = 0;
- if (state.divisor) {
- instancesRequired = ceil(static_cast<float>(primitiveCount) / state.divisor);
- if (instancesRequired > numElements)
- return false;
- } else {
- sawNonInstancedAttrib = true;
- if (elementCount > numElements)
- return false;
- }
- }
- }
- }
-
- if (!sawNonInstancedAttrib && sawEnabledAttrib)
- return false;
-
- return true;
-}
-
-bool WebGLRenderingContextBase::validateWebGLObject(const char* functionName, WebGLObject* object)
-{
- if (!object || !object->object()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no object or object deleted");
- return false;
- }
- if (!object->validate(contextGroup(), this)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object does not belong to this context");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContextBase::validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primitiveCount)
-{
- if (isContextLostOrPending() || !validateDrawMode(functionName, mode))
- return false;
-
- if (!validateStencilSettings(functionName))
- return false;
-
- if (first < 0 || count < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "first or count < 0");
- return false;
- }
-
- if (!count) {
- markContextChanged();
- return false;
- }
-
- if (primitiveCount < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "primcount < 0");
- return false;
- }
-
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- // Ensure we have a valid rendering state
- Checked<GC3Dint, RecordOverflow> checkedFirst(first);
- Checked<GC3Dint, RecordOverflow> checkedCount(count);
- Checked<GC3Dint, RecordOverflow> checkedSum = checkedFirst + checkedCount;
- Checked<GC3Dint, RecordOverflow> checkedPrimitiveCount(primitiveCount);
- if (checkedSum.hasOverflowed() || checkedPrimitiveCount.hasOverflowed() || !validateVertexAttributes(checkedSum.unsafeGet(), checkedPrimitiveCount.unsafeGet())) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access out of bounds arrays");
- return false;
- }
- if (!validateSimulatedVertexAttrib0(checkedSum.unsafeGet() - 1)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access outside the bounds of the simulated vertexAttrib0 array");
- return false;
- }
- } else {
- if (!validateVertexAttributes(0)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attribs not setup correctly");
- return false;
- }
- }
-
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContextBase::validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned& numElements, GC3Dsizei primitiveCount)
-{
- if (isContextLostOrPending() || !validateDrawMode(functionName, mode))
- return false;
-
- if (!validateStencilSettings(functionName))
- return false;
-
- switch (type) {
- case GraphicsContext3D::UNSIGNED_BYTE:
- case GraphicsContext3D::UNSIGNED_SHORT:
- break;
- case GraphicsContext3D::UNSIGNED_INT:
- if (m_oesElementIndexUint || isWebGL2())
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid type");
- return false;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid type");
- return false;
- }
-
- if (count < 0 || offset < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "count or offset < 0");
- return false;
- }
-
- if (!count) {
- markContextChanged();
- return false;
- }
-
- if (primitiveCount < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "primcount < 0");
- return false;
- }
-
- if (!m_boundVertexArrayObject->getElementArrayBuffer()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no ELEMENT_ARRAY_BUFFER bound");
- return false;
- }
-
- if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- // Ensure we have a valid rendering state
- if (!validateElementArraySize(count, type, static_cast<GC3Dintptr>(offset))) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "request out of bounds for current ELEMENT_ARRAY_BUFFER");
- return false;
- }
- if (!count)
- return false;
-
- Checked<GC3Dint, RecordOverflow> checkedCount(count);
- Checked<GC3Dint, RecordOverflow> checkedPrimitiveCount(primitiveCount);
- if (checkedCount.hasOverflowed() || checkedPrimitiveCount.hasOverflowed()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access out of bounds arrays");
- return false;
- }
-
- if (!validateIndexArrayConservative(type, numElements) || !validateVertexAttributes(numElements, checkedPrimitiveCount.unsafeGet())) {
- if (!validateIndexArrayPrecise(checkedCount.unsafeGet(), type, static_cast<GC3Dintptr>(offset), numElements) || !validateVertexAttributes(numElements, checkedPrimitiveCount.unsafeGet())) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access out of bounds arrays");
- return false;
- }
- }
-
- if (!validateSimulatedVertexAttrib0(numElements)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attempt to access outside the bounds of the simulated vertexAttrib0 array");
- return false;
- }
-
- } else {
- if (!validateVertexAttributes(0)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "attribs not setup correctly");
- return false;
- }
- }
-
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
- return false;
- }
-
- return true;
-}
-
-void WebGLRenderingContextBase::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
-
- if (!validateDrawArrays("drawArrays", mode, first, count, 0))
- return;
-
- clearIfComposited();
-
- bool vertexAttrib0Simulated = false;
- if (!isGLES2Compliant())
- vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawArrays", true);
-
- m_context->drawArrays(mode, first, count);
-
- if (!isGLES2Compliant() && vertexAttrib0Simulated)
- restoreStatesAfterVertexAttrib0Simulation();
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawArrays", false);
- markContextChanged();
-}
-
-void WebGLRenderingContextBase::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
-
- unsigned numElements = 0;
- if (!validateDrawElements("drawElements", mode, count, type, offset, numElements, 0))
- return;
-
- clearIfComposited();
-
- bool vertexAttrib0Simulated = false;
- if (!isGLES2Compliant()) {
- if (!numElements)
- validateIndexArrayPrecise(count, type, static_cast<GC3Dintptr>(offset), numElements);
- vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
- }
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawElements", true);
-
- m_context->drawElements(mode, count, type, static_cast<GC3Dintptr>(offset));
-
- if (!isGLES2Compliant() && vertexAttrib0Simulated)
- restoreStatesAfterVertexAttrib0Simulation();
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawElements", false);
- markContextChanged();
-}
-
-void WebGLRenderingContextBase::enable(GC3Denum cap)
-{
- if (isContextLostOrPending() || !validateCapability("enable", cap))
- return;
- if (cap == GraphicsContext3D::STENCIL_TEST) {
- m_stencilEnabled = true;
- applyStencilTest();
- return;
- }
- if (cap == GraphicsContext3D::SCISSOR_TEST)
- m_scissorEnabled = true;
- m_context->enable(cap);
-}
-
-void WebGLRenderingContextBase::enableVertexAttribArray(GC3Duint index, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return;
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "enableVertexAttribArray", "index out of range");
- return;
- }
-
- WebGLVertexArrayObjectBase::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
- state.enabled = true;
-
- m_context->enableVertexAttribArray(index);
-}
-
-void WebGLRenderingContextBase::finish()
-{
- if (isContextLostOrPending())
- return;
- m_context->finish();
-}
-
-void WebGLRenderingContextBase::flush()
-{
- if (isContextLostOrPending())
- return;
- m_context->flush();
-}
-
-void WebGLRenderingContextBase::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment))
- return;
- if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "framebufferRenderbuffer", "invalid target");
- return;
- }
- if (buffer && !buffer->validate(contextGroup(), this)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context");
- return;
- }
- // Don't allow the default framebuffer to be mutated; all current
- // implementations use an FBO internally in place of the default
- // FBO.
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no framebuffer bound");
- return;
- }
- Platform3DObject bufferObject = objectOrZero(buffer);
- switch (attachment) {
- case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
- m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
- m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
- break;
- default:
- m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, bufferObject);
- }
- m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
- applyStencilTest();
-}
-
-void WebGLRenderingContextBase::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture* texture, GC3Dint level, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment))
- return;
- if (level) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "framebufferTexture2D", "level not 0");
- return;
- }
- if (texture && !texture->validate(contextGroup(), this)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context");
- return;
- }
- // Don't allow the default framebuffer to be mutated; all current
- // implementations use an FBO internally in place of the default
- // FBO.
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no framebuffer bound");
- return;
- }
- Platform3DObject textureObject = objectOrZero(texture);
- switch (attachment) {
- case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
- m_context->framebufferTexture2D(target, GraphicsContext3D::DEPTH_ATTACHMENT, textarget, textureObject, level);
- m_context->framebufferTexture2D(target, GraphicsContext3D::STENCIL_ATTACHMENT, textarget, textureObject, level);
- break;
- case GraphicsContext3D::DEPTH_ATTACHMENT:
- m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
- break;
- case GraphicsContext3D::STENCIL_ATTACHMENT:
- m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
- break;
- default:
- m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
- }
- m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
- applyStencilTest();
-}
-
-void WebGLRenderingContextBase::frontFace(GC3Denum mode)
-{
- if (isContextLostOrPending())
- return;
- m_context->frontFace(mode);
-}
-
-void WebGLRenderingContextBase::generateMipmap(GC3Denum target)
-{
- if (isContextLostOrPending())
- return;
- WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false);
- if (!tex)
- return;
- if (!tex->canGenerateMipmaps()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "generateMipmap", "level 0 not power of 2 or not all the same size");
- return;
- }
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=123916. Compressed textures should be allowed in WebGL 2:
- if (tex->isCompressed()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "generateMipmap", "trying to generate mipmaps from compressed texture");
- return;
- }
- if (!validateSettableTexFormat("generateMipmap", tex->getInternalFormat(target, 0)))
- return;
-
- // generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR
- // on Mac. Remove the hack once this driver bug is fixed.
-#if OS(DARWIN)
- bool needToResetMinFilter = false;
- if (tex->getMinFilter() != GraphicsContext3D::NEAREST_MIPMAP_LINEAR) {
- m_context->texParameteri(target, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST_MIPMAP_LINEAR);
- needToResetMinFilter = true;
- }
-#endif
- m_context->generateMipmap(target);
-#if OS(DARWIN)
- if (needToResetMinFilter)
- m_context->texParameteri(target, GraphicsContext3D::TEXTURE_MIN_FILTER, tex->getMinFilter());
-#endif
- tex->generateMipmapLevelInfo();
-}
-
-PassRefPtr<WebGLActiveInfo> WebGLRenderingContextBase::getActiveAttrib(WebGLProgram* program, GC3Duint index, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("getActiveAttrib", program))
- return nullptr;
- ActiveInfo info;
- if (!m_context->getActiveAttrib(objectOrZero(program), index, info))
- return nullptr;
-
- LOG(WebGL, "Returning active attribute %d: %s", index, info.name.utf8().data());
-
- return WebGLActiveInfo::create(info.name, info.type, info.size);
-}
-
-PassRefPtr<WebGLActiveInfo> WebGLRenderingContextBase::getActiveUniform(WebGLProgram* program, GC3Duint index, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("getActiveUniform", program))
- return 0;
- ActiveInfo info;
- if (!m_context->getActiveUniform(objectOrZero(program), index, info))
- return nullptr;
- if (!isGLES2Compliant())
- if (info.size > 1 && !info.name.endsWith("[0]"))
- info.name.append("[0]");
-
- LOG(WebGL, "Returning active uniform %d: %s", index, info.name.utf8().data());
-
- return WebGLActiveInfo::create(info.name, info.type, info.size);
-}
-
-bool WebGLRenderingContextBase::getAttachedShaders(WebGLProgram* program, Vector<RefPtr<WebGLShader>>& shaderObjects, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- shaderObjects.clear();
- if (isContextLostOrPending() || !validateWebGLObject("getAttachedShaders", program))
- return false;
-
- const GC3Denum shaderType[] = {
- GraphicsContext3D::VERTEX_SHADER,
- GraphicsContext3D::FRAGMENT_SHADER
- };
- for (unsigned i = 0; i < sizeof(shaderType) / sizeof(GC3Denum); ++i) {
- WebGLShader* shader = program->getAttachedShader(shaderType[i]);
- if (shader)
- shaderObjects.append(shader);
- }
- return true;
-}
-
-GC3Dint WebGLRenderingContextBase::getAttribLocation(WebGLProgram* program, const String& name)
-{
- if (isContextLostOrPending() || !validateWebGLObject("getAttribLocation", program))
- return -1;
- if (!validateLocationLength("getAttribLocation", name))
- return -1;
- if (!validateString("getAttribLocation", name))
- return -1;
- if (isPrefixReserved(name))
- return -1;
- if (!program->getLinkStatus()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getAttribLocation", "program not linked");
- return -1;
- }
- return m_context->getAttribLocation(objectOrZero(program), name);
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getBufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return WebGLGetInfo();
- if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid target");
- return WebGLGetInfo();
- }
-
- if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-
- GC3Dint value = 0;
- m_context->getBufferParameteriv(target, pname, &value);
- if (pname == GraphicsContext3D::BUFFER_SIZE)
- return WebGLGetInfo(value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
-}
-
-PassRefPtr<WebGLContextAttributes> WebGLRenderingContextBase::getContextAttributes()
-{
- if (isContextLostOrPending())
- return nullptr;
- // We always need to return a new WebGLContextAttributes object to
- // prevent the user from mutating any cached version.
-
- // Also, we need to enforce requested values of "false" for depth
- // and stencil, regardless of the properties of the underlying
- // GraphicsContext3D.
- RefPtr<WebGLContextAttributes> attributes = WebGLContextAttributes::create(m_context->getContextAttributes());
- if (!m_attributes.depth)
- attributes->setDepth(false);
- if (!m_attributes.stencil)
- attributes->setStencil(false);
- return attributes.release();
-}
-
-GC3Denum WebGLRenderingContextBase::getError()
-{
- if (m_isPendingPolicyResolution)
- return GraphicsContext3D::NO_ERROR;
- return m_context->getError();
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getProgramParameter(WebGLProgram* program, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("getProgramParameter", program))
- return WebGLGetInfo();
-
- GC3Dint value = 0;
- switch (pname) {
- case GraphicsContext3D::DELETE_STATUS:
- return WebGLGetInfo(program->isDeleted());
- case GraphicsContext3D::VALIDATE_STATUS:
- m_context->getProgramiv(objectOrZero(program), pname, &value);
- return WebGLGetInfo(static_cast<bool>(value));
- case GraphicsContext3D::LINK_STATUS:
- return WebGLGetInfo(program->getLinkStatus());
- case GraphicsContext3D::ATTACHED_SHADERS:
- m_context->getProgramiv(objectOrZero(program), pname, &value);
- return WebGLGetInfo(value);
- case GraphicsContext3D::ACTIVE_ATTRIBUTES:
- case GraphicsContext3D::ACTIVE_UNIFORMS:
- m_context->getNonBuiltInActiveSymbolCount(objectOrZero(program), pname, &value);
- return WebGLGetInfo(value);
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getProgramParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-String WebGLRenderingContextBase::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("getProgramInfoLog", program))
- return String();
- return ensureNotNull(m_context->getProgramInfoLog(objectOrZero(program)));
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getRenderbufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return WebGLGetInfo();
- if (target != GraphicsContext3D::RENDERBUFFER) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid target");
- return WebGLGetInfo();
- }
- if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound");
- return WebGLGetInfo();
- }
-
- if (m_renderbufferBinding->getInternalFormat() == GraphicsContext3D::DEPTH_STENCIL
- && !m_renderbufferBinding->isValid()) {
- ASSERT(!isDepthStencilSupported());
- int value = 0;
- switch (pname) {
- case GraphicsContext3D::RENDERBUFFER_WIDTH:
- value = m_renderbufferBinding->getWidth();
- break;
- case GraphicsContext3D::RENDERBUFFER_HEIGHT:
- value = m_renderbufferBinding->getHeight();
- break;
- case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
- case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
- case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
- case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
- value = 0;
- break;
- case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
- value = 24;
- break;
- case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
- value = 8;
- break;
- case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
- return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
- return WebGLGetInfo(value);
- }
-
- GC3Dint value = 0;
- switch (pname) {
- case GraphicsContext3D::RENDERBUFFER_WIDTH:
- case GraphicsContext3D::RENDERBUFFER_HEIGHT:
- case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
- case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
- case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
- case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
- case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
- case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
- m_context->getRenderbufferParameteriv(target, pname, &value);
- return WebGLGetInfo(value);
- case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
- return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getShaderParameter(WebGLShader* shader, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("getShaderParameter", shader))
- return WebGLGetInfo();
- GC3Dint value = 0;
- switch (pname) {
- case GraphicsContext3D::DELETE_STATUS:
- return WebGLGetInfo(shader->isDeleted());
- case GraphicsContext3D::COMPILE_STATUS:
- m_context->getShaderiv(objectOrZero(shader), pname, &value);
- return WebGLGetInfo(static_cast<bool>(value));
- case GraphicsContext3D::SHADER_TYPE:
- m_context->getShaderiv(objectOrZero(shader), pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-String WebGLRenderingContextBase::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("getShaderInfoLog", shader))
- return String();
- return ensureNotNull(m_context->getShaderInfoLog(objectOrZero(shader)));
-}
-
-PassRefPtr<WebGLShaderPrecisionFormat> WebGLRenderingContextBase::getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return nullptr;
- switch (shaderType) {
- case GraphicsContext3D::VERTEX_SHADER:
- case GraphicsContext3D::FRAGMENT_SHADER:
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderPrecisionFormat", "invalid shader type");
- return nullptr;
- }
- switch (precisionType) {
- case GraphicsContext3D::LOW_FLOAT:
- case GraphicsContext3D::MEDIUM_FLOAT:
- case GraphicsContext3D::HIGH_FLOAT:
- case GraphicsContext3D::LOW_INT:
- case GraphicsContext3D::MEDIUM_INT:
- case GraphicsContext3D::HIGH_INT:
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderPrecisionFormat", "invalid precision type");
- return nullptr;
- }
-
- GC3Dint range[2] = {0, 0};
- GC3Dint precision = 0;
- m_context->getShaderPrecisionFormat(shaderType, precisionType, range, &precision);
- return WebGLShaderPrecisionFormat::create(range[0], range[1], precision);
-}
-
-String WebGLRenderingContextBase::getShaderSource(WebGLShader* shader, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("getShaderSource", shader))
- return String();
- return ensureNotNull(shader->getSource());
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getTexParameter(GC3Denum target, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return WebGLGetInfo();
- WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false);
- if (!tex)
- return WebGLGetInfo();
- GC3Dint value = 0;
- switch (pname) {
- case GraphicsContext3D::TEXTURE_MAG_FILTER:
- case GraphicsContext3D::TEXTURE_MIN_FILTER:
- case GraphicsContext3D::TEXTURE_WRAP_S:
- case GraphicsContext3D::TEXTURE_WRAP_T:
- m_context->getTexParameteriv(target, pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
- case Extensions3D::TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
- if (m_extTextureFilterAnisotropic) {
- m_context->getTexParameteriv(target, pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
- }
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getTexParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
- return WebGLGetInfo();
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getTexParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("getUniform", program))
- return WebGLGetInfo();
- if (!uniformLocation || uniformLocation->program() != program) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program");
- return WebGLGetInfo();
- }
- GC3Dint location = uniformLocation->location();
-
- GC3Denum baseType;
- unsigned length;
- switch (uniformLocation->type()) {
- case GraphicsContext3D::BOOL:
- baseType = GraphicsContext3D::BOOL;
- length = 1;
- break;
- case GraphicsContext3D::BOOL_VEC2:
- baseType = GraphicsContext3D::BOOL;
- length = 2;
- break;
- case GraphicsContext3D::BOOL_VEC3:
- baseType = GraphicsContext3D::BOOL;
- length = 3;
- break;
- case GraphicsContext3D::BOOL_VEC4:
- baseType = GraphicsContext3D::BOOL;
- length = 4;
- break;
- case GraphicsContext3D::INT:
- baseType = GraphicsContext3D::INT;
- length = 1;
- break;
- case GraphicsContext3D::INT_VEC2:
- baseType = GraphicsContext3D::INT;
- length = 2;
- break;
- case GraphicsContext3D::INT_VEC3:
- baseType = GraphicsContext3D::INT;
- length = 3;
- break;
- case GraphicsContext3D::INT_VEC4:
- baseType = GraphicsContext3D::INT;
- length = 4;
- break;
- case GraphicsContext3D::FLOAT:
- baseType = GraphicsContext3D::FLOAT;
- length = 1;
- break;
- case GraphicsContext3D::FLOAT_VEC2:
- baseType = GraphicsContext3D::FLOAT;
- length = 2;
- break;
- case GraphicsContext3D::FLOAT_VEC3:
- baseType = GraphicsContext3D::FLOAT;
- length = 3;
- break;
- case GraphicsContext3D::FLOAT_VEC4:
- baseType = GraphicsContext3D::FLOAT;
- length = 4;
- break;
- case GraphicsContext3D::FLOAT_MAT2:
- baseType = GraphicsContext3D::FLOAT;
- length = 4;
- break;
- case GraphicsContext3D::FLOAT_MAT3:
- baseType = GraphicsContext3D::FLOAT;
- length = 9;
- break;
- case GraphicsContext3D::FLOAT_MAT4:
- baseType = GraphicsContext3D::FLOAT;
- length = 16;
- break;
- case GraphicsContext3D::SAMPLER_2D:
- case GraphicsContext3D::SAMPLER_CUBE:
- baseType = GraphicsContext3D::INT;
- length = 1;
- break;
- default:
- // Can't handle this type
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getUniform", "unhandled type");
- return WebGLGetInfo();
- }
- switch (baseType) {
- case GraphicsContext3D::FLOAT: {
- GC3Dfloat value[16] = {0};
- if (m_isRobustnessEXTSupported)
- m_context->getExtensions()->getnUniformfvEXT(objectOrZero(program), location, 16 * sizeof(GC3Dfloat), value);
- else
- m_context->getUniformfv(objectOrZero(program), location, value);
- if (length == 1)
- return WebGLGetInfo(value[0]);
- return WebGLGetInfo(Float32Array::create(value, length).release());
- }
- case GraphicsContext3D::INT: {
- GC3Dint value[4] = {0};
- if (m_isRobustnessEXTSupported)
- m_context->getExtensions()->getnUniformivEXT(objectOrZero(program), location, 4 * sizeof(GC3Dint), value);
- else
- m_context->getUniformiv(objectOrZero(program), location, value);
- if (length == 1)
- return WebGLGetInfo(value[0]);
- return WebGLGetInfo(Int32Array::create(value, length).release());
- }
- case GraphicsContext3D::BOOL: {
- GC3Dint value[4] = {0};
- if (m_isRobustnessEXTSupported)
- m_context->getExtensions()->getnUniformivEXT(objectOrZero(program), location, 4 * sizeof(GC3Dint), value);
- else
- m_context->getUniformiv(objectOrZero(program), location, value);
- if (length > 1) {
- bool boolValue[16] = {0};
- for (unsigned j = 0; j < length; j++)
- boolValue[j] = static_cast<bool>(value[j]);
- return WebGLGetInfo(boolValue, length);
- }
- return WebGLGetInfo(static_cast<bool>(value[0]));
- }
- default:
- notImplemented();
- }
-
- // If we get here, something went wrong in our unfortunately complex logic above
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getUniform", "unknown error");
- return WebGLGetInfo();
-}
-
-PassRefPtr<WebGLUniformLocation> WebGLRenderingContextBase::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("getUniformLocation", program))
- return nullptr;
- if (!validateLocationLength("getUniformLocation", name))
- return nullptr;
- if (!validateString("getUniformLocation", name))
- return nullptr;
- if (isPrefixReserved(name))
- return nullptr;
- if (!program->getLinkStatus()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getUniformLocation", "program not linked");
- return nullptr;
- }
- GC3Dint uniformLocation = m_context->getUniformLocation(objectOrZero(program), name);
- if (uniformLocation == -1)
- return nullptr;
-
- GC3Dint activeUniforms = 0;
- m_context->getNonBuiltInActiveSymbolCount(objectOrZero(program), GraphicsContext3D::ACTIVE_UNIFORMS, &activeUniforms);
- for (GC3Dint i = 0; i < activeUniforms; i++) {
- ActiveInfo info;
- if (!m_context->getActiveUniform(objectOrZero(program), i, info))
- return nullptr;
- // Strip "[0]" from the name if it's an array.
- if (info.name.endsWith("[0]"))
- info.name = info.name.left(info.name.length() - 3);
- // If it's an array, we need to iterate through each element, appending "[index]" to the name.
- for (GC3Dint index = 0; index < info.size; ++index) {
- String uniformName = info.name + "[" + String::number(index) + "]";
-
- if (name == uniformName || name == info.name)
- return WebGLUniformLocation::create(program, uniformLocation, info.type);
- }
- }
- return nullptr;
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getVertexAttrib(GC3Duint index, GC3Denum pname, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
-
- if (isContextLostOrPending())
- return WebGLGetInfo();
-
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getVertexAttrib", "index out of range");
- return WebGLGetInfo();
- }
-
- const WebGLVertexArrayObjectBase::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
-
- if ((isWebGL2() || m_angleInstancedArrays) && pname == GraphicsContext3D::VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE)
- return WebGLGetInfo(state.divisor);
-
- switch (pname) {
- case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- if ((!isGLES2Compliant() && !index && m_boundVertexArrayObject->getVertexAttribState(0).bufferBinding == m_vertexAttrib0Buffer)
- || !state.bufferBinding
- || !state.bufferBinding->object())
- return WebGLGetInfo();
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(state.bufferBinding));
- case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_ENABLED:
- return WebGLGetInfo(state.enabled);
- case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_NORMALIZED:
- return WebGLGetInfo(state.normalized);
- case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE:
- return WebGLGetInfo(state.size);
- case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE:
- return WebGLGetInfo(state.originalStride);
- case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE:
- return WebGLGetInfo(state.type);
- case GraphicsContext3D::CURRENT_VERTEX_ATTRIB:
- return WebGLGetInfo(Float32Array::create(m_vertexAttribValue[index].value, 4).release());
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getVertexAttrib", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-long long WebGLRenderingContextBase::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
-{
- if (isContextLostOrPending())
- return 0;
- GC3Dsizeiptr result = m_context->getVertexAttribOffset(index, pname);
- return static_cast<long long>(result);
-}
-
-GC3Dboolean WebGLRenderingContextBase::isBuffer(WebGLBuffer* buffer)
-{
- if (!buffer || isContextLostOrPending())
- return 0;
-
- if (!buffer->hasEverBeenBound())
- return 0;
-
- return m_context->isBuffer(buffer->object());
-}
-
-bool WebGLRenderingContextBase::isContextLost() const
-{
- return m_contextLost;
-}
-
-bool WebGLRenderingContextBase::isContextLostOrPending()
-{
- if (m_isPendingPolicyResolution && !m_hasRequestedPolicyResolution) {
- LOG(WebGL, "Context is being used. Attempt to resolve the policy.");
- Document& document = canvas()->document().topDocument();
- Page* page = document.page();
- if (page && !document.url().isLocalFile())
- page->mainFrame().loader().client().resolveWebGLPolicyForURL(document.url());
- // FIXME: We don't currently do anything with the result from resolution. A more
- // complete implementation might try to construct a real context, etc and proceed
- // with normal operation.
- // https://bugs.webkit.org/show_bug.cgi?id=129122
- m_hasRequestedPolicyResolution = true;
- }
-
- return m_contextLost || m_isPendingPolicyResolution;
-}
-
-GC3Dboolean WebGLRenderingContextBase::isEnabled(GC3Denum cap)
-{
- if (isContextLostOrPending() || !validateCapability("isEnabled", cap))
- return 0;
- if (cap == GraphicsContext3D::STENCIL_TEST)
- return m_stencilEnabled;
- return m_context->isEnabled(cap);
-}
-
-GC3Dboolean WebGLRenderingContextBase::isFramebuffer(WebGLFramebuffer* framebuffer)
-{
- if (!framebuffer || isContextLostOrPending())
- return 0;
-
- if (!framebuffer->hasEverBeenBound())
- return 0;
-
- return m_context->isFramebuffer(framebuffer->object());
-}
-
-GC3Dboolean WebGLRenderingContextBase::isProgram(WebGLProgram* program)
-{
- if (!program || isContextLostOrPending())
- return 0;
-
- return m_context->isProgram(program->object());
-}
-
-GC3Dboolean WebGLRenderingContextBase::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
-{
- if (!renderbuffer || isContextLostOrPending())
- return 0;
-
- if (!renderbuffer->hasEverBeenBound())
- return 0;
-
- return m_context->isRenderbuffer(renderbuffer->object());
-}
-
-GC3Dboolean WebGLRenderingContextBase::isShader(WebGLShader* shader)
-{
- if (!shader || isContextLostOrPending())
- return 0;
-
- return m_context->isShader(shader->object());
-}
-
-GC3Dboolean WebGLRenderingContextBase::isTexture(WebGLTexture* texture)
-{
- if (!texture || isContextLostOrPending())
- return 0;
-
- if (!texture->hasEverBeenBound())
- return 0;
-
- return m_context->isTexture(texture->object());
-}
-
-void WebGLRenderingContextBase::lineWidth(GC3Dfloat width)
-{
- if (isContextLostOrPending())
- return;
- m_context->lineWidth(width);
-}
-
-void WebGLRenderingContextBase::linkProgram(WebGLProgram* program, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("linkProgram", program))
- return;
- WebGLShader* vertexShader = program->getAttachedShader(GraphicsContext3D::VERTEX_SHADER);
- WebGLShader* fragmentShader = program->getAttachedShader(GraphicsContext3D::FRAGMENT_SHADER);
- if (!vertexShader || !vertexShader->isValid() || !fragmentShader || !fragmentShader->isValid() || !m_context->precisionsMatch(objectOrZero(vertexShader), objectOrZero(fragmentShader)) || !m_context->checkVaryingsPacking(objectOrZero(vertexShader), objectOrZero(fragmentShader))) {
- program->setLinkStatus(false);
- return;
- }
-
- m_context->linkProgram(objectOrZero(program));
- program->increaseLinkCount();
-}
-
-void WebGLRenderingContextBase::pixelStorei(GC3Denum pname, GC3Dint param)
-{
- if (isContextLostOrPending())
- return;
- switch (pname) {
- case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
- m_unpackFlipY = param;
- break;
- case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
- m_unpackPremultiplyAlpha = param;
- break;
- case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL:
- if (param == GraphicsContext3D::BROWSER_DEFAULT_WEBGL || param == GraphicsContext3D::NONE)
- m_unpackColorspaceConversion = static_cast<GC3Denum>(param);
- else {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "pixelStorei", "invalid parameter for UNPACK_COLORSPACE_CONVERSION_WEBGL");
- return;
- }
- break;
- case GraphicsContext3D::PACK_ALIGNMENT:
- case GraphicsContext3D::UNPACK_ALIGNMENT:
- if (param == 1 || param == 2 || param == 4 || param == 8) {
- if (pname == GraphicsContext3D::PACK_ALIGNMENT)
- m_packAlignment = param;
- else // GraphicsContext3D::UNPACK_ALIGNMENT:
- m_unpackAlignment = param;
- m_context->pixelStorei(pname, param);
- } else {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "pixelStorei", "invalid parameter for alignment");
- return;
- }
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "pixelStorei", "invalid parameter name");
- return;
- }
-}
-
-void WebGLRenderingContextBase::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
-{
- if (isContextLostOrPending())
- return;
- m_context->polygonOffset(factor, units);
-}
-
-void WebGLRenderingContextBase::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&)
-{
- if (isContextLostOrPending())
- return;
- // Due to WebGL's same-origin restrictions, it is not possible to
- // taint the origin using the WebGL API.
- ASSERT(canvas()->originClean());
- // Validate input parameters.
- if (!pixels) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "readPixels", "no destination ArrayBufferView");
- return;
- }
- switch (format) {
- case GraphicsContext3D::ALPHA:
- case GraphicsContext3D::RGB:
- case GraphicsContext3D::RGBA:
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "invalid format");
- return;
- }
- switch (type) {
- case GraphicsContext3D::UNSIGNED_BYTE:
- case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
- case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
- case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "invalid type");
- return;
- }
- if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "format not RGBA or type not UNSIGNED_BYTE");
- return;
- }
- // Validate array type against pixel type.
- if (pixels->getType() != JSC::TypeUint8) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "ArrayBufferView not Uint8Array");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
- return;
- }
- // Calculate array size, taking into consideration of PACK_ALIGNMENT.
- unsigned int totalBytesRequired = 0;
- unsigned int padding = 0;
- if (!m_isRobustnessEXTSupported) {
- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
- if (error != GraphicsContext3D::NO_ERROR) {
- synthesizeGLError(error, "readPixels", "invalid dimensions");
- return;
- }
- if (pixels->byteLength() < totalBytesRequired) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
- return;
- }
- }
-
- clearIfComposited();
- void* data = pixels->baseAddress();
-
- {
- if (m_isRobustnessEXTSupported)
- m_context->getExtensions()->readnPixelsEXT(x, y, width, height, format, type, pixels->byteLength(), data);
- else
- m_context->readPixels(x, y, width, height, format, type, data);
- }
-
-#if OS(DARWIN)
- if (m_isRobustnessEXTSupported) // we haven't computed padding
- m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
- // FIXME: remove this section when GL driver bug on Mac AND the GLES driver bug
- // on QC is fixed, i.e., when alpha is off, readPixels should
- // set alpha to 255 instead of 0.
- if (!m_framebufferBinding && !m_context->getContextAttributes().alpha) {
- unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
- for (GC3Dsizei iy = 0; iy < height; ++iy) {
- for (GC3Dsizei ix = 0; ix < width; ++ix) {
- pixels[3] = 255;
- pixels += 4;
- }
- pixels += padding;
- }
- }
-#endif
-}
-
-void WebGLRenderingContextBase::releaseShaderCompiler()
-{
- if (isContextLostOrPending())
- return;
- m_context->releaseShaderCompiler();
-}
-
-void WebGLRenderingContextBase::sampleCoverage(GC3Dfloat value, GC3Dboolean invert)
-{
- if (isContextLostOrPending())
- return;
- m_context->sampleCoverage(value, invert);
-}
-
-void WebGLRenderingContextBase::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLostOrPending())
- return;
- if (!validateSize("scissor", width, height))
- return;
- m_context->scissor(x, y, width, height);
-}
-
-void WebGLRenderingContextBase::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("shaderSource", shader))
- return;
- String stringWithoutComments = StripComments(string).result();
- if (!validateString("shaderSource", stringWithoutComments))
- return;
- shader->setSource(string);
- m_context->shaderSource(objectOrZero(shader), stringWithoutComments);
-}
-
-void WebGLRenderingContextBase::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
-{
- if (isContextLostOrPending())
- return;
- if (!validateStencilFunc("stencilFunc", func))
- return;
- m_stencilFuncRef = ref;
- m_stencilFuncRefBack = ref;
- m_stencilFuncMask = mask;
- m_stencilFuncMaskBack = mask;
- m_context->stencilFunc(func, ref, mask);
-}
-
-void WebGLRenderingContextBase::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
-{
- if (isContextLostOrPending())
- return;
- if (!validateStencilFunc("stencilFuncSeparate", func))
- return;
- switch (face) {
- case GraphicsContext3D::FRONT_AND_BACK:
- m_stencilFuncRef = ref;
- m_stencilFuncRefBack = ref;
- m_stencilFuncMask = mask;
- m_stencilFuncMaskBack = mask;
- break;
- case GraphicsContext3D::FRONT:
- m_stencilFuncRef = ref;
- m_stencilFuncMask = mask;
- break;
- case GraphicsContext3D::BACK:
- m_stencilFuncRefBack = ref;
- m_stencilFuncMaskBack = mask;
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "stencilFuncSeparate", "invalid face");
- return;
- }
- m_context->stencilFuncSeparate(face, func, ref, mask);
-}
-
-void WebGLRenderingContextBase::stencilMask(GC3Duint mask)
-{
- if (isContextLostOrPending())
- return;
- m_stencilMask = mask;
- m_stencilMaskBack = mask;
- m_context->stencilMask(mask);
-}
-
-void WebGLRenderingContextBase::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
-{
- if (isContextLostOrPending())
- return;
- switch (face) {
- case GraphicsContext3D::FRONT_AND_BACK:
- m_stencilMask = mask;
- m_stencilMaskBack = mask;
- break;
- case GraphicsContext3D::FRONT:
- m_stencilMask = mask;
- break;
- case GraphicsContext3D::BACK:
- m_stencilMaskBack = mask;
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "stencilMaskSeparate", "invalid face");
- return;
- }
- m_context->stencilMaskSeparate(face, mask);
-}
-
-void WebGLRenderingContextBase::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
-{
- if (isContextLostOrPending())
- return;
- m_context->stencilOp(fail, zfail, zpass);
-}
-
-void WebGLRenderingContextBase::stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
-{
- if (isContextLostOrPending())
- return;
- m_context->stencilOpSeparate(face, fail, zfail, zpass);
-}
-
-void WebGLRenderingContextBase::texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec)
-{
- // FIXME: For now we ignore any errors returned.
- ec = 0;
- WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
- ASSERT(validateTexFuncParameters("texImage2D", TexImage, target, level, internalformat, width, height, border, format, type));
- ASSERT(tex);
- ASSERT(!level || !WebGLTexture::isNPOT(width, height));
- if (!pixels) {
- // Note: Chromium's OpenGL implementation clears textures and isResourceSafe() is therefore true.
- // For other implementations, if they are using ANGLE_depth_texture, ANGLE depth textures
- // can not be cleared with texImage2D and must be cleared by binding to an fbo and calling
- // clear.
- if (isResourceSafe())
- m_context->texImage2D(target, level, internalformat, width, height, border, format, type, nullptr);
- else {
- bool succeed = m_context->texImage2DResourceSafe(target, level, internalformat, width, height,
- border, format, type, m_unpackAlignment);
- if (!succeed)
- return;
- }
- } else {
- ASSERT(validateSettableTexFormat("texImage2D", internalformat));
- m_context->moveErrorsToSyntheticErrorList();
- m_context->texImage2D(target, level, internalformat, width, height,
- border, format, type, pixels);
- if (m_context->moveErrorsToSyntheticErrorList()) {
- // The texImage2D function failed. Tell the WebGLTexture it doesn't have the data for this level.
- tex->markInvalid(target, level);
- return;
- }
- }
- tex->setLevelInfo(target, level, internalformat, width, height, type);
-}
-
-void WebGLRenderingContextBase::texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
-{
- ec = 0;
- Vector<uint8_t> data;
- GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
- if (!imageExtractor.extractSucceeded()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
- GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
- const void* imagePixelData = imageExtractor.imagePixelData();
-
- bool needConversion = true;
- if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
- needConversion = false;
- else {
- if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "packImage error");
- return;
- }
- }
-
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- texImage2DBase(target, level, internalformat, image->width(), image->height(), 0, format, type, needConversion ? data.data() : imagePixelData, ec);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset)
-{
- if (!validateTexFuncParameters(functionName, functionType, target, level, internalformat, width, height, border, format, type))
- return false;
-
- WebGLTexture* texture = validateTextureBinding(functionName, target, true);
- if (!texture)
- return false;
-
- if (functionType != TexSubImage) {
- if (level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level > 0 not power of 2");
- return false;
- }
- // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
- // by checking if the ArrayBufferView is null or not.
- if (sourceType != SourceArrayBufferView) {
- if (!validateSettableTexFormat(functionName, format))
- return false;
- }
- } else {
- if (!validateSettableTexFormat(functionName, format))
- return false;
- if (!validateSize(functionName, xoffset, yoffset))
- return false;
- // Before checking if it is in the range, check if overflow happens first.
- if (xoffset + width < 0 || yoffset + height < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "bad dimensions");
- return false;
- }
- if (xoffset + width > texture->getWidth(target, level) || yoffset + height > texture->getHeight(target, level)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "dimensions out of range");
- return false;
- }
- if (texture->getInternalFormat(target, level) != format || texture->getType(target, level) != type) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type and format do not match texture");
- return false;
- }
- }
-
- return true;
-}
-
-void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
-{
- if (isContextLostOrPending() || !validateTexFuncData("texImage2D", level, width, height, internalformat, format, type, pixels, NullAllowed)
- || !validateTexFunc("texImage2D", TexImage, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))
- return;
- void* data = pixels ? pixels->baseAddress() : 0;
- Vector<uint8_t> tempData;
- bool changeUnpackAlignment = false;
- if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
- if (!m_context->extractTextureData(width, height, format, type,
- m_unpackAlignment,
- m_unpackFlipY, m_unpackPremultiplyAlpha,
- data,
- tempData))
- return;
- data = tempData.data();
- changeUnpackAlignment = true;
- }
- if (changeUnpackAlignment)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- texImage2DBase(target, level, internalformat, width, height, border,
- format, type, data, ec);
- if (changeUnpackAlignment)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLostOrPending() || !pixels || !validateTexFunc("texImage2D", TexImage, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
- return;
- Vector<uint8_t> data;
- bool needConversion = true;
- // The data from ImageData is always of format RGBA8.
- // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
- if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE)
- needConversion = false;
- else {
- if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- }
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data(), ec);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-PassRefPtr<Image> WebGLRenderingContextBase::drawImageIntoBuffer(Image* image, int width, int height, int deviceScaleFactor)
-{
- IntSize size(width, height);
- size.scale(deviceScaleFactor);
- ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
- if (!buf) {
- synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "texImage2D", "out of memory");
- return nullptr;
- }
-
- FloatRect srcRect(FloatPoint(), image->size());
- FloatRect destRect(FloatPoint(), size);
- buf->context()->drawImage(image, ColorSpaceDeviceRGB, destRect, srcRect);
- return buf->copyImage(ImageBuffer::fastCopyImageMode());
-}
-
-void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLostOrPending() || !validateHTMLImageElement("texImage2D", image, ec))
- return;
-
- RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
- if (imageForRender->isSVGImage())
- imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), 1);
-
- if (!imageForRender || !validateTexFunc("texImage2D", TexImage, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
- return;
-
- texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-
-void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLostOrPending() || !validateHTMLCanvasElement("texImage2D", canvas, ec) || !validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
- return;
-
- WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
- // If possible, copy from the canvas element directly to the texture
- // via the GPU, without a read-back to system memory.
- //
- // FIXME: restriction of (RGB || RGBA)/UNSIGNED_BYTE should be lifted when
- // ImageBuffer::copyToPlatformTexture implementations are fully functional.
- if (texture
- && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
- && type == GraphicsContext3D::UNSIGNED_BYTE
- && (texture->getType(target, level) == GraphicsContext3D::UNSIGNED_BYTE || !texture->isValid(target, level))) {
- ImageBuffer* buffer = canvas->buffer();
- if (buffer && buffer->copyToPlatformTexture(*m_context.get(), target, texture->object(), internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
- return;
- }
- }
-
- RefPtr<ImageData> imageData = canvas->getImageData();
- if (imageData)
- texImage2D(target, level, internalformat, format, type, imageData.get(), ec);
- else
- texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-
-#if ENABLE(VIDEO)
-PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy, ExceptionCode&)
-{
- IntSize size(video->videoWidth(), video->videoHeight());
- ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
- if (!buf) {
- synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "texImage2D", "out of memory");
- return nullptr;
- }
- FloatRect destRect(0, 0, size.width(), size.height());
- // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
- video->paintCurrentFrameInContext(buf->context(), destRect);
- return buf->copyImage(backingStoreCopy);
-}
-
-void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLostOrPending() || !validateHTMLVideoElement("texImage2D", video, ec)
- || !validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
- return;
-
- // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
- // Otherwise, it will fall back to the normal SW path.
- // FIXME: The current restrictions require that format shoud be RGB or RGBA,
- // type should be UNSIGNED_BYTE and level should be 0. It may be lifted in the future.
- WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
- if (GraphicsContext3D::TEXTURE_2D == target && texture
- && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
- && type == GraphicsContext3D::UNSIGNED_BYTE
- && (texture->getType(target, level) == GraphicsContext3D::UNSIGNED_BYTE || !texture->isValid(target, level))
- && !level) {
- if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), level, type, internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
- return;
- }
- }
-
- // Normal pure SW path.
- RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);
- if (!image)
- return;
- texImage2DImpl(target, level, internalformat, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-#endif
-
-void WebGLRenderingContextBase::texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat paramf, GC3Dint parami, bool isFloat)
-{
- if (isContextLostOrPending())
- return;
- WebGLTexture* tex = validateTextureBinding("texParameter", target, false);
- if (!tex)
- return;
- switch (pname) {
- case GraphicsContext3D::TEXTURE_MIN_FILTER:
- case GraphicsContext3D::TEXTURE_MAG_FILTER:
- break;
- case GraphicsContext3D::TEXTURE_WRAP_S:
- case GraphicsContext3D::TEXTURE_WRAP_T:
- if ((isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT)
- || (!isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT)) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter");
- return;
- }
- break;
- case Extensions3D::TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
- if (!m_extTextureFilterAnisotropic) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter, EXT_texture_filter_anisotropic not enabled");
- return;
- }
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter name");
- return;
- }
- if (isFloat) {
- tex->setParameterf(pname, paramf);
- m_context->texParameterf(target, pname, paramf);
- } else {
- tex->setParameteri(pname, parami);
- m_context->texParameteri(target, pname, parami);
- }
-}
-
-void WebGLRenderingContextBase::texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param)
-{
- texParameter(target, pname, param, 0, true);
-}
-
-void WebGLRenderingContextBase::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param)
-{
- texParameter(target, pname, 0, param, false);
-}
-
-void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform1f", "location not for current program");
- return;
- }
-
- m_context->uniform1f(location->location(), x);
-}
-
-void WebGLRenderingContextBase::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform1fv", location, v, 1))
- return;
-
- m_context->uniform1fv(location->location(), v->length(), v->data());
-}
-
-void WebGLRenderingContextBase::uniform1fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform1fv", location, v, size, 1))
- return;
-
- m_context->uniform1fv(location->location(), size, v);
-}
-
-void WebGLRenderingContextBase::uniform1i(const WebGLUniformLocation* location, GC3Dint x, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform1i", "location not for current program");
- return;
- }
-
- if ((location->type() == GraphicsContext3D::SAMPLER_2D || location->type() == GraphicsContext3D::SAMPLER_CUBE) && x >= (int)m_textureUnits.size()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "uniform1i", "invalid texture unit");
- return;
- }
-
- m_context->uniform1i(location->location(), x);
-}
-
-void WebGLRenderingContextBase::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform1iv", location, v, 1))
- return;
-
- if (location->type() == GraphicsContext3D::SAMPLER_2D || location->type() == GraphicsContext3D::SAMPLER_CUBE)
- for (unsigned i = 0; i < v->length(); ++i) {
- if (v->data()[i] >= static_cast<int>(m_textureUnits.size())) {
- LOG(WebGL, "Texture unit size=%zu, v[%d]=%d. Location type = %04X.", m_textureUnits.size(), i, v->data()[i], location->type());
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "uniform1iv", "invalid texture unit");
- return;
- }
- }
-
- m_context->uniform1iv(location->location(), v->length(), v->data());
-}
-
-void WebGLRenderingContextBase::uniform1iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform1iv", location, v, size, 1))
- return;
-
- if (location->type() == GraphicsContext3D::SAMPLER_2D || location->type() == GraphicsContext3D::SAMPLER_CUBE)
- for (unsigned i = 0; i < static_cast<unsigned>(size); ++i) {
- if (((GC3Dint*)v)[i] >= static_cast<int>(m_textureUnits.size())) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "uniform1iv", "invalid texture unit");
- return;
- }
- }
-
- m_context->uniform1iv(location->location(), size, v);
-}
-
-void WebGLRenderingContextBase::uniform2f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2f", "location not for current program");
- return;
- }
-
- m_context->uniform2f(location->location(), x, y);
-}
-
-void WebGLRenderingContextBase::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform2fv", location, v, 2))
- return;
-
- m_context->uniform2fv(location->location(), v->length() / 2, v->data());
-}
-
-void WebGLRenderingContextBase::uniform2fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform2fv", location, v, size, 2))
- return;
-
- m_context->uniform2fv(location->location(), size / 2, v);
-}
-
-void WebGLRenderingContextBase::uniform2i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2i", "location not for current program");
- return;
- }
-
- m_context->uniform2i(location->location(), x, y);
-}
-
-void WebGLRenderingContextBase::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform2iv", location, v, 2))
- return;
-
- m_context->uniform2iv(location->location(), v->length() / 2, v->data());
-}
-
-void WebGLRenderingContextBase::uniform2iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform2iv", location, v, size, 2))
- return;
-
- m_context->uniform2iv(location->location(), size / 2, v);
-}
-
-void WebGLRenderingContextBase::uniform3f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3f", "location not for current program");
- return;
- }
-
- m_context->uniform3f(location->location(), x, y, z);
-}
-
-void WebGLRenderingContextBase::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform3fv", location, v, 3))
- return;
-
- m_context->uniform3fv(location->location(), v->length() / 3, v->data());
-}
-
-void WebGLRenderingContextBase::uniform3fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform3fv", location, v, size, 3))
- return;
-
- m_context->uniform3fv(location->location(), size / 3, v);
-}
-
-void WebGLRenderingContextBase::uniform3i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3i", "location not for current program");
- return;
- }
-
- m_context->uniform3i(location->location(), x, y, z);
-}
-
-void WebGLRenderingContextBase::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform3iv", location, v, 3))
- return;
-
- m_context->uniform3iv(location->location(), v->length() / 3, v->data());
-}
-
-void WebGLRenderingContextBase::uniform3iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform3iv", location, v, size, 3))
- return;
-
- m_context->uniform3iv(location->location(), size / 3, v);
-}
-
-void WebGLRenderingContextBase::uniform4f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4f", "location not for current program");
- return;
- }
-
- m_context->uniform4f(location->location(), x, y, z, w);
-}
-
-void WebGLRenderingContextBase::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform4fv", location, v, 4))
- return;
-
- m_context->uniform4fv(location->location(), v->length() / 4, v->data());
-}
-
-void WebGLRenderingContextBase::uniform4fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform4fv", location, v, size, 4))
- return;
-
- m_context->uniform4fv(location->location(), size / 4, v);
-}
-
-void WebGLRenderingContextBase::uniform4i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4i", "location not for current program");
- return;
- }
-
- m_context->uniform4i(location->location(), x, y, z, w);
-}
-
-void WebGLRenderingContextBase::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform4iv", location, v, 4))
- return;
-
- m_context->uniform4iv(location->location(), v->length() / 4, v->data());
-}
-
-void WebGLRenderingContextBase::uniform4iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformParameters("uniform4iv", location, v, size, 4))
- return;
-
- m_context->uniform4iv(location->location(), size / 4, v);
-}
-
-void WebGLRenderingContextBase::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4))
- return;
- m_context->uniformMatrix2fv(location->location(), v->length() / 4, transpose, v->data());
-}
-
-void WebGLRenderingContextBase::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, size, 4))
- return;
- m_context->uniformMatrix2fv(location->location(), size / 4, transpose, v);
-}
-
-void WebGLRenderingContextBase::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9))
- return;
- m_context->uniformMatrix3fv(location->location(), v->length() / 9, transpose, v->data());
-}
-
-void WebGLRenderingContextBase::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, size, 9))
- return;
- m_context->uniformMatrix3fv(location->location(), size / 9, transpose, v);
-}
-
-void WebGLRenderingContextBase::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16))
- return;
- m_context->uniformMatrix4fv(location->location(), v->length() / 16, transpose, v->data());
-}
-
-void WebGLRenderingContextBase::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, size, 16))
- return;
- m_context->uniformMatrix4fv(location->location(), size / 16, transpose, v);
-}
-
-void WebGLRenderingContextBase::useProgram(WebGLProgram* program, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- bool deleted;
- if (!checkObjectToBeBound("useProgram", program, deleted))
- return;
- if (deleted)
- program = 0;
- if (program && !program->getLinkStatus()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "useProgram", "program not valid");
- return;
- }
- if (m_currentProgram != program) {
- if (m_currentProgram)
- m_currentProgram->onDetached(graphicsContext3D());
- m_currentProgram = program;
- m_context->useProgram(objectOrZero(program));
- if (program)
- program->onAttached();
- }
-}
-
-void WebGLRenderingContextBase::validateProgram(WebGLProgram* program, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending() || !validateWebGLObject("validateProgram", program))
- return;
- m_context->validateProgram(objectOrZero(program));
-}
-
-void WebGLRenderingContextBase::vertexAttrib1f(GC3Duint index, GC3Dfloat v0)
-{
- vertexAttribfImpl("vertexAttrib1f", index, 1, v0, 0.0f, 0.0f, 1.0f);
-}
-
-void WebGLRenderingContextBase::vertexAttrib1fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib1fv", index, v, 1);
-}
-
-void WebGLRenderingContextBase::vertexAttrib1fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib1fv", index, v, size, 1);
-}
-
-void WebGLRenderingContextBase::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1)
-{
- vertexAttribfImpl("vertexAttrib2f", index, 2, v0, v1, 0.0f, 1.0f);
-}
-
-void WebGLRenderingContextBase::vertexAttrib2fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib2fv", index, v, 2);
-}
-
-void WebGLRenderingContextBase::vertexAttrib2fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib2fv", index, v, size, 2);
-}
-
-void WebGLRenderingContextBase::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
-{
- vertexAttribfImpl("vertexAttrib3f", index, 3, v0, v1, v2, 1.0f);
-}
-
-void WebGLRenderingContextBase::vertexAttrib3fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib3fv", index, v, 3);
-}
-
-void WebGLRenderingContextBase::vertexAttrib3fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib3fv", index, v, size, 3);
-}
-
-void WebGLRenderingContextBase::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
-{
- vertexAttribfImpl("vertexAttrib4f", index, 4, v0, v1, v2, v3);
-}
-
-void WebGLRenderingContextBase::vertexAttrib4fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib4fv", index, v, 4);
-}
-
-void WebGLRenderingContextBase::vertexAttrib4fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib4fv", index, v, size, 4);
-}
-
-void WebGLRenderingContextBase::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, long long offset, ExceptionCode& ec)
-{
- UNUSED_PARAM(ec);
- if (isContextLostOrPending())
- return;
- switch (type) {
- case GraphicsContext3D::BYTE:
- case GraphicsContext3D::UNSIGNED_BYTE:
- case GraphicsContext3D::SHORT:
- case GraphicsContext3D::UNSIGNED_SHORT:
- case GraphicsContext3D::FLOAT:
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "vertexAttribPointer", "invalid type");
- return;
- }
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribPointer", "index out of range");
- return;
- }
- if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribPointer", "bad size, stride or offset");
- return;
- }
- if (!m_boundArrayBuffer) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER");
- return;
- }
- // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
- unsigned int typeSize = sizeInBytes(type);
- if (!typeSize) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "vertexAttribPointer", "invalid type");
- return;
- }
- if ((stride % typeSize) || (static_cast<GC3Dintptr>(offset) % typeSize)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "vertexAttribPointer", "stride or offset not valid for type");
- return;
- }
- GC3Dsizei bytesPerElement = size * typeSize;
-
- m_boundVertexArrayObject->setVertexAttribState(index, bytesPerElement, size, type, normalized, stride, static_cast<GC3Dintptr>(offset), m_boundArrayBuffer);
- m_context->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GC3Dintptr>(offset));
-}
-
-void WebGLRenderingContextBase::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLostOrPending())
- return;
- if (!validateSize("viewport", width, height))
- return;
- m_context->viewport(x, y, width, height);
-}
-
-void WebGLRenderingContextBase::forceLostContext(WebGLRenderingContextBase::LostContextMode mode)
-{
- if (isContextLostOrPending()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "loseContext", "context already lost");
- return;
- }
-
- m_contextGroup->loseContextGroup(mode);
-}
-
-void WebGLRenderingContextBase::loseContextImpl(WebGLRenderingContextBase::LostContextMode mode)
-{
- if (isContextLost())
- return;
-
- m_contextLost = true;
- m_contextLostMode = mode;
-
- if (mode == RealLostContext) {
- // Inform the embedder that a lost context was received. In response, the embedder might
- // decide to take action such as asking the user for permission to use WebGL again.
- if (Frame* frame = canvas()->document().frame())
- frame->loader().client().didLoseWebGLContext(m_context->getExtensions()->getGraphicsResetStatusARB());
- }
-
- detachAndRemoveAllObjects();
-
- // There is no direct way to clear errors from a GL implementation and
- // looping until getError() becomes NO_ERROR might cause an infinite loop if
- // the driver or context implementation had a bug. So, loop a reasonably
- // large number of times to clear any existing errors.
- for (int i = 0; i < 100; ++i) {
- if (m_context->getError() == GraphicsContext3D::NO_ERROR)
- break;
- }
- ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInConsole: DontDisplayInConsole;
- synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL, "loseContext", "context lost", display);
-
- // Don't allow restoration unless the context lost event has both been
- // dispatched and its default behavior prevented.
- m_restoreAllowed = false;
-
- // Always defer the dispatch of the context lost event, to implement
- // the spec behavior of queueing a task.
- m_dispatchContextLostEventTimer.startOneShot(0);
-}
-
-void WebGLRenderingContextBase::forceRestoreContext()
-{
- if (!isContextLostOrPending()) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "restoreContext", "context not lost");
- return;
- }
-
- if (!m_restoreAllowed) {
- if (m_contextLostMode == SyntheticLostContext)
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "restoreContext", "context restoration not allowed");
- return;
- }
-
- if (!m_restoreTimer.isActive())
- m_restoreTimer.startOneShot(0);
-}
-
-PlatformLayer* WebGLRenderingContextBase::platformLayer() const
-{
- return (!isContextLost() && !m_isPendingPolicyResolution) ? m_context->platformLayer() : 0;
-}
-
-void WebGLRenderingContextBase::removeSharedObject(WebGLSharedObject* object)
-{
- if (m_isPendingPolicyResolution)
- return;
-
- m_contextGroup->removeObject(object);
-}
-
-void WebGLRenderingContextBase::addSharedObject(WebGLSharedObject* object)
-{
- if (m_isPendingPolicyResolution)
- return;
-
- ASSERT(!isContextLost());
- m_contextGroup->addObject(object);
-}
-
-void WebGLRenderingContextBase::removeContextObject(WebGLContextObject* object)
-{
- if (m_isPendingPolicyResolution)
- return;
-
- m_contextObjects.remove(object);
-}
-
-void WebGLRenderingContextBase::addContextObject(WebGLContextObject* object)
-{
- if (m_isPendingPolicyResolution)
- return;
-
- ASSERT(!isContextLost());
- m_contextObjects.add(object);
-}
-
-void WebGLRenderingContextBase::detachAndRemoveAllObjects()
-{
- if (m_isPendingPolicyResolution)
- return;
-
- while (m_contextObjects.size() > 0) {
- HashSet<WebGLContextObject*>::iterator it = m_contextObjects.begin();
- (*it)->detachContext();
- }
-}
-
-bool WebGLRenderingContextBase::hasPendingActivity() const
-{
- return false;
-}
-
-void WebGLRenderingContextBase::stop()
-{
- if (!isContextLost() && !m_isPendingPolicyResolution) {
- forceLostContext(SyntheticLostContext);
- destroyGraphicsContext3D();
- }
-}
-
-const char* WebGLRenderingContextBase::activeDOMObjectName() const
-{
- return "WebGLRenderingContext";
-}
-
-bool WebGLRenderingContextBase::canSuspendForPageCache() const
-{
- // FIXME: We should try and do better here.
- return false;
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getBooleanParameter(GC3Denum pname)
-{
- GC3Dboolean value = 0;
- m_context->getBooleanv(pname, &value);
- return WebGLGetInfo(static_cast<bool>(value));
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getBooleanArrayParameter(GC3Denum pname)
-{
- if (pname != GraphicsContext3D::COLOR_WRITEMASK) {
- notImplemented();
- return WebGLGetInfo(0, 0);
- }
- GC3Dboolean value[4] = {0};
- m_context->getBooleanv(pname, value);
- bool boolValue[4];
- for (int ii = 0; ii < 4; ++ii)
- boolValue[ii] = static_cast<bool>(value[ii]);
- return WebGLGetInfo(boolValue, 4);
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getFloatParameter(GC3Denum pname)
-{
- GC3Dfloat value = 0;
- m_context->getFloatv(pname, &value);
- return WebGLGetInfo(value);
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getIntParameter(GC3Denum pname)
-{
- GC3Dint value = 0;
- m_context->getIntegerv(pname, &value);
- return WebGLGetInfo(value);
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getUnsignedIntParameter(GC3Denum pname)
-{
- GC3Dint value = 0;
- m_context->getIntegerv(pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getInt64Parameter(GC3Denum pname)
-{
- GC3Dint64 value = 0;
- m_context->getInteger64v(pname, &value);
- return WebGLGetInfo(value);
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getWebGLFloatArrayParameter(GC3Denum pname)
-{
- GC3Dfloat value[4] = {0};
- m_context->getFloatv(pname, value);
- unsigned length = 0;
- switch (pname) {
- case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
- case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
- case GraphicsContext3D::DEPTH_RANGE:
- length = 2;
- break;
- case GraphicsContext3D::BLEND_COLOR:
- case GraphicsContext3D::COLOR_CLEAR_VALUE:
- length = 4;
- break;
- default:
- notImplemented();
- }
- return WebGLGetInfo(Float32Array::create(value, length).release());
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getWebGLIntArrayParameter(GC3Denum pname)
-{
- GC3Dint value[4] = {0};
- m_context->getIntegerv(pname, value);
- unsigned length = 0;
- switch (pname) {
- case GraphicsContext3D::MAX_VIEWPORT_DIMS:
- length = 2;
- break;
- case GraphicsContext3D::SCISSOR_BOX:
- case GraphicsContext3D::VIEWPORT:
- length = 4;
- break;
- default:
- notImplemented();
- }
- return WebGLGetInfo(Int32Array::create(value, length).release());
-}
-
-void WebGLRenderingContextBase::checkTextureCompleteness(const char* functionName, bool prepareToDraw)
-{
- bool resetActiveUnit = false;
- WebGLTexture::TextureExtensionFlag extensions = static_cast<WebGLTexture::TextureExtensionFlag>((m_oesTextureFloatLinear ? WebGLTexture::TextureExtensionFloatLinearEnabled : 0) | (m_oesTextureHalfFloatLinear ? WebGLTexture::TextureExtensionHalfFloatLinearEnabled : 0));
-
- for (unsigned ii = 0; ii < m_textureUnits.size(); ++ii) {
- if ((m_textureUnits[ii].texture2DBinding && m_textureUnits[ii].texture2DBinding->needToUseBlackTexture(extensions))
- || (m_textureUnits[ii].textureCubeMapBinding && m_textureUnits[ii].textureCubeMapBinding->needToUseBlackTexture(extensions))) {
- if (ii != m_activeTextureUnit) {
- m_context->activeTexture(ii + GraphicsContext3D::TEXTURE0);
- resetActiveUnit = true;
- } else if (resetActiveUnit) {
- m_context->activeTexture(ii + GraphicsContext3D::TEXTURE0);
- resetActiveUnit = false;
- }
- WebGLTexture* tex2D;
- WebGLTexture* texCubeMap;
- if (prepareToDraw) {
- String msg(String("texture bound to texture unit ") + String::number(ii)
- + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete',"
- + " or it is a float/half-float type with linear filtering and without the relevant float/half-float linear extension enabled.");
- printGLWarningToConsole(functionName, msg.utf8().data());
- tex2D = m_blackTexture2D.get();
- texCubeMap = m_blackTextureCubeMap.get();
- } else {
- tex2D = m_textureUnits[ii].texture2DBinding.get();
- texCubeMap = m_textureUnits[ii].textureCubeMapBinding.get();
- }
- if (m_textureUnits[ii].texture2DBinding && m_textureUnits[ii].texture2DBinding->needToUseBlackTexture(extensions))
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(tex2D));
- if (m_textureUnits[ii].textureCubeMapBinding && m_textureUnits[ii].textureCubeMapBinding->needToUseBlackTexture(extensions))
- m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
- }
- }
- if (resetActiveUnit)
- m_context->activeTexture(m_activeTextureUnit + GraphicsContext3D::TEXTURE0);
-}
-
-void WebGLRenderingContextBase::createFallbackBlackTextures1x1()
-{
- unsigned char black[] = {0, 0, 0, 255};
- m_blackTexture2D = createTexture();
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_blackTexture2D->object());
- m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
- m_blackTextureCubeMap = createTexture();
- m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, m_blackTextureCubeMap->object());
- m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
- 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
- m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, 0);
-}
-
-bool WebGLRenderingContextBase::isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat,
- GC3Denum colorBufferFormat)
-{
- unsigned need = GraphicsContext3D::getChannelBitsByFormat(texInternalFormat);
- unsigned have = GraphicsContext3D::getChannelBitsByFormat(colorBufferFormat);
- return (need & have) == need;
-}
-
-GC3Denum WebGLRenderingContextBase::getBoundFramebufferColorFormat()
-{
- if (m_framebufferBinding && m_framebufferBinding->object())
- return m_framebufferBinding->getColorBufferFormat();
- if (m_attributes.alpha)
- return GraphicsContext3D::RGBA;
- return GraphicsContext3D::RGB;
-}
-
-int WebGLRenderingContextBase::getBoundFramebufferWidth()
-{
- if (m_framebufferBinding && m_framebufferBinding->object())
- return m_framebufferBinding->getColorBufferWidth();
- return m_context->getInternalFramebufferSize().width();
-}
-
-int WebGLRenderingContextBase::getBoundFramebufferHeight()
-{
- if (m_framebufferBinding && m_framebufferBinding->object())
- return m_framebufferBinding->getColorBufferHeight();
- return m_context->getInternalFramebufferSize().height();
-}
-
-WebGLTexture* WebGLRenderingContextBase::validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap)
-{
- WebGLTexture* texture = nullptr;
- switch (target) {
- case GraphicsContext3D::TEXTURE_2D:
- texture = m_textureUnits[m_activeTextureUnit].texture2DBinding.get();
- break;
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (!useSixEnumsForCubeMap) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
- return nullptr;
- }
- texture = m_textureUnits[m_activeTextureUnit].textureCubeMapBinding.get();
- break;
- case GraphicsContext3D::TEXTURE_CUBE_MAP:
- if (useSixEnumsForCubeMap) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
- return nullptr;
- }
- texture = m_textureUnits[m_activeTextureUnit].textureCubeMapBinding.get();
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
- return nullptr;
- }
- if (!texture)
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no texture");
- return texture;
-}
-
-bool WebGLRenderingContextBase::validateLocationLength(const char* functionName, const String& string)
-{
- const unsigned maxWebGLLocationLength = 256;
- if (string.length() > maxWebGLLocationLength) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "location length > 256");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContextBase::validateSize(const char* functionName, GC3Dint x, GC3Dint y)
-{
- if (x < 0 || y < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "size < 0");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContextBase::validateString(const char* functionName, const String& string)
-{
- for (size_t i = 0; i < string.length(); ++i) {
- if (!validateCharacter(string[i])) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "string not ASCII");
- return false;
- }
- }
- return true;
-}
-
-bool WebGLRenderingContextBase::validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level)
-{
- if (level < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level < 0");
- return false;
- }
- switch (target) {
- case GraphicsContext3D::TEXTURE_2D:
- if (level >= m_maxTextureLevel) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level out of range");
- return false;
- }
- break;
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (level >= m_maxCubeMapTextureLevel) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level out of range");
- return false;
- }
- break;
- }
- // This function only checks if level is legal, so we return true and don't
- // generate INVALID_ENUM if target is illegal.
- return true;
-}
-
-bool WebGLRenderingContextBase::validateCompressedTexFormat(GC3Denum format)
-{
- return m_compressedTextureFormats.contains(format);
-}
-
-bool WebGLRenderingContextBase::validateCompressedTexFuncData(const char* functionName,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, ArrayBufferView* pixels)
-{
- if (!pixels) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels");
- return false;
- }
- if (width < 0 || height < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
- return false;
- }
-
- unsigned int bytesRequired = 0;
-
- switch (format) {
- case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_ATC_RGB_AMD:
- {
- const int kBlockSize = 8;
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
- int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
- bytesRequired = numBlocksAcross * numBlocksDown * kBlockSize;
- }
- break;
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT:
- case Extensions3D::COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
- case Extensions3D::COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
- {
- const int kBlockSize = 16;
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
- int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
- bytesRequired = numBlocksAcross * numBlocksDown * kBlockSize;
- }
- break;
- case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
- {
- const int kBlockSize = 8;
- const int kBlockWidth = 8;
- const int kBlockHeight = 8;
- bytesRequired = (std::max(width, kBlockWidth) * std::max(height, kBlockHeight) * 4 + 7) / kBlockSize;
- }
- break;
- case Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
- {
- const int kBlockSize = 8;
- const int kBlockWidth = 16;
- const int kBlockHeight = 8;
- bytesRequired = (std::max(width, kBlockWidth) * std::max(height, kBlockHeight) * 2 + 7) / kBlockSize;
- }
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format");
- return false;
- }
-
- if (pixels->byteLength() != bytesRequired) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "length of ArrayBufferView is not correct for dimensions");
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContextBase::validateCompressedTexDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format)
-{
- switch (format) {
- case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT: {
- const GC3Dsizei kBlockWidth = 4;
- const GC3Dsizei kBlockHeight = 4;
- const GC3Dint maxTextureSize = target ? m_maxTextureSize : m_maxCubeMapTextureSize;
- const GC3Dsizei maxCompressedDimension = maxTextureSize >> level;
- bool widthValid = (level && width == 1) || (level && width == 2) || (!(width % kBlockWidth) && width <= maxCompressedDimension);
- bool heightValid = (level && height == 1) || (level && height == 2) || (!(height % kBlockHeight) && height <= maxCompressedDimension);
- if (!widthValid || !heightValid) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "width or height invalid for level");
- return false;
- }
- return true;
- }
- case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
- // Height and width must be powers of 2.
- if ((width & (width - 1)) || (height & (height - 1))) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "width or height invalid for level");
- return false;
- }
- return true;
- default:
- return false;
- }
-}
-
-bool WebGLRenderingContextBase::validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture* tex)
-{
- if (xoffset < 0 || yoffset < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "xoffset or yoffset < 0");
- return false;
- }
-
- switch (format) {
- case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT: {
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "xoffset or yoffset not multiple of 4");
- return false;
- }
- if (width - xoffset > tex->getWidth(target, level)
- || height - yoffset > tex->getHeight(target, level)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "dimensions out of range");
- return false;
- }
- return validateCompressedTexDimensions(functionName, target, level, width, height, format);
- }
- case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
- if (xoffset || yoffset) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "xoffset and yoffset must be zero");
- return false;
- }
- if (width != tex->getWidth(target, level)
- || height != tex->getHeight(target, level)) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "dimensions must match existing level");
- return false;
- }
- return validateCompressedTexDimensions(functionName, target, level, width, height, format);
- }
- default:
- return false;
- }
-}
-
-bool WebGLRenderingContextBase::validateDrawMode(const char* functionName, GC3Denum mode)
-{
- switch (mode) {
- case GraphicsContext3D::POINTS:
- case GraphicsContext3D::LINE_STRIP:
- case GraphicsContext3D::LINE_LOOP:
- case GraphicsContext3D::LINES:
- case GraphicsContext3D::TRIANGLE_STRIP:
- case GraphicsContext3D::TRIANGLE_FAN:
- case GraphicsContext3D::TRIANGLES:
- return true;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid draw mode");
- return false;
- }
-}
-
-bool WebGLRenderingContextBase::validateStencilSettings(const char* functionName)
-{
- if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "front and back stencils settings do not match");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContextBase::validateStencilFunc(const char* functionName, GC3Denum func)
-{
- switch (func) {
- case GraphicsContext3D::NEVER:
- case GraphicsContext3D::LESS:
- case GraphicsContext3D::LEQUAL:
- case GraphicsContext3D::GREATER:
- case GraphicsContext3D::GEQUAL:
- case GraphicsContext3D::EQUAL:
- case GraphicsContext3D::NOTEQUAL:
- case GraphicsContext3D::ALWAYS:
- return true;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid function");
- return false;
- }
-}
-
-void WebGLRenderingContextBase::printGLErrorToConsole(const String& message)
-{
- if (!m_numGLErrorsToConsoleAllowed)
- return;
-
- --m_numGLErrorsToConsoleAllowed;
- printWarningToConsole(message);
-
- if (!m_numGLErrorsToConsoleAllowed)
- printWarningToConsole("WebGL: too many errors, no more errors will be reported to the console for this context.");
-}
-
-void WebGLRenderingContextBase::printWarningToConsole(const String& message)
-{
- if (!canvas())
- return;
- canvas()->document().addConsoleMessage(MessageSource::Rendering, MessageLevel::Warning, message);
-}
-
-bool WebGLRenderingContextBase::validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst)
-{
- if (((src == GraphicsContext3D::CONSTANT_COLOR || src == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
- && (dst == GraphicsContext3D::CONSTANT_ALPHA || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))
- || ((dst == GraphicsContext3D::CONSTANT_COLOR || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
- && (src == GraphicsContext3D::CONSTANT_ALPHA || src == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "incompatible src and dst");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei requiredMinSize)
-{
- if (!v) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
- return false;
- }
- return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei requiredMinSize)
-{
- if (!v) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
- return false;
- }
- return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
-{
- return validateUniformMatrixParameters(functionName, location, false, v, size, requiredMinSize);
-}
-
-bool WebGLRenderingContextBase::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, GC3Dsizei requiredMinSize)
-{
- if (!v) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
- return false;
- }
- return validateUniformMatrixParameters(functionName, location, transpose, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContextBase::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
-{
- if (!location)
- return false;
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "location is not from current program");
- return false;
- }
- if (!v) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
- return false;
- }
- if (transpose) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "transpose not FALSE");
- return false;
- }
- if (size < requiredMinSize || (size % requiredMinSize)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid size");
- return false;
- }
- return true;
-}
-
-WebGLBuffer* WebGLRenderingContextBase::validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage)
-{
- WebGLBuffer* buffer = 0;
- switch (target) {
- case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
- buffer = m_boundVertexArrayObject->getElementArrayBuffer().get();
- break;
- case GraphicsContext3D::ARRAY_BUFFER:
- buffer = m_boundArrayBuffer.get();
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
- return nullptr;
- }
- if (!buffer) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no buffer");
- return nullptr;
- }
- switch (usage) {
- case GraphicsContext3D::STREAM_DRAW:
- case GraphicsContext3D::STATIC_DRAW:
- case GraphicsContext3D::DYNAMIC_DRAW:
- return buffer;
- }
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid usage");
- return nullptr;
-}
-
-bool WebGLRenderingContextBase::validateHTMLImageElement(const char* functionName, HTMLImageElement* image, ExceptionCode& ec)
-{
- if (!image || !image->cachedImage()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no image");
- return false;
- }
- const URL& url = image->cachedImage()->response().url();
- if (url.isNull() || url.isEmpty() || !url.isValid()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid image");
- return false;
- }
- if (wouldTaintOrigin(image)) {
- ec = SECURITY_ERR;
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContextBase::validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement* canvas, ExceptionCode& ec)
-{
- if (!canvas || !canvas->buffer()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no canvas");
- return false;
- }
- if (wouldTaintOrigin(canvas)) {
- ec = SECURITY_ERR;
- return false;
- }
- return true;
-}
-
-#if ENABLE(VIDEO)
-bool WebGLRenderingContextBase::validateHTMLVideoElement(const char* functionName, HTMLVideoElement* video, ExceptionCode& ec)
-{
- if (!video || !video->videoWidth() || !video->videoHeight()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no video");
- return false;
- }
- if (wouldTaintOrigin(video)) {
- ec = SECURITY_ERR;
- return false;
- }
- return true;
-}
-#endif
-
-void WebGLRenderingContextBase::vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
-{
- if (isContextLostOrPending())
- return;
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "index out of range");
- return;
- }
- // In GL, we skip setting vertexAttrib0 values.
- if (index || isGLES2Compliant()) {
- switch (expectedSize) {
- case 1:
- m_context->vertexAttrib1f(index, v0);
- break;
- case 2:
- m_context->vertexAttrib2f(index, v0, v1);
- break;
- case 3:
- m_context->vertexAttrib3f(index, v0, v1, v2);
- break;
- case 4:
- m_context->vertexAttrib4f(index, v0, v1, v2, v3);
- break;
- }
- }
- VertexAttribValue& attribValue = m_vertexAttribValue[index];
- attribValue.value[0] = v0;
- attribValue.value[1] = v1;
- attribValue.value[2] = v2;
- attribValue.value[3] = v3;
-}
-
-void WebGLRenderingContextBase::vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array* v, GC3Dsizei expectedSize)
-{
- if (isContextLostOrPending())
- return;
- if (!v) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
- return;
- }
- vertexAttribfvImpl(functionName, index, v->data(), v->length(), expectedSize);
-}
-
-void WebGLRenderingContextBase::vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat* v, GC3Dsizei size, GC3Dsizei expectedSize)
-{
- if (isContextLostOrPending())
- return;
- if (!v) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
- return;
- }
- if (size < expectedSize) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid size");
- return;
- }
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "index out of range");
- return;
- }
- // In GL, we skip setting vertexAttrib0 values.
- if (index || isGLES2Compliant()) {
- switch (expectedSize) {
- case 1:
- m_context->vertexAttrib1fv(index, v);
- break;
- case 2:
- m_context->vertexAttrib2fv(index, v);
- break;
- case 3:
- m_context->vertexAttrib3fv(index, v);
- break;
- case 4:
- m_context->vertexAttrib4fv(index, v);
- break;
- }
- }
- VertexAttribValue& attribValue = m_vertexAttribValue[index];
- attribValue.initValue();
- for (int ii = 0; ii < expectedSize; ++ii)
- attribValue.value[ii] = v[ii];
-}
-
-void WebGLRenderingContextBase::initVertexAttrib0()
-{
- WebGLVertexArrayObjectBase::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0);
-
- m_vertexAttrib0Buffer = createBuffer();
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer->object());
- m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, 0, GraphicsContext3D::DYNAMIC_DRAW);
- m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, false, 0, 0);
- state.bufferBinding = m_vertexAttrib0Buffer;
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0);
- m_context->enableVertexAttribArray(0);
- m_vertexAttrib0BufferSize = 0;
- m_vertexAttrib0BufferValue[0] = 0.0f;
- m_vertexAttrib0BufferValue[1] = 0.0f;
- m_vertexAttrib0BufferValue[2] = 0.0f;
- m_vertexAttrib0BufferValue[3] = 1.0f;
- m_forceAttrib0BufferRefill = false;
- m_vertexAttrib0UsedBefore = false;
-}
-
-bool WebGLRenderingContextBase::validateSimulatedVertexAttrib0(GC3Dsizei numVertex)
-{
- if (numVertex < 0)
- return false;
-
- if (!m_currentProgram)
- return true;
-
- bool usingVertexAttrib0 = m_currentProgram->isUsingVertexAttrib0();
- if (!usingVertexAttrib0)
- return true;
-
- auto& state = m_boundVertexArrayObject->getVertexAttribState(0);
- if (state.enabled)
- return true;
-
- Checked<GC3Dsizei, RecordOverflow> bufferSize(numVertex);
- bufferSize += 1;
- bufferSize *= Checked<GC3Dsizei>(4);
- Checked<GC3Dsizeiptr, RecordOverflow> bufferDataSize(bufferSize);
- bufferDataSize *= Checked<GC3Dsizeiptr>(sizeof(GC3Dfloat));
- return !bufferDataSize.hasOverflowed();
-}
-
-bool WebGLRenderingContextBase::simulateVertexAttrib0(GC3Dsizei numVertex)
-{
- if (!m_currentProgram)
- return false;
- bool usingVertexAttrib0 = m_currentProgram->isUsingVertexAttrib0();
- if (usingVertexAttrib0)
- m_vertexAttrib0UsedBefore = true;
-
- auto& state = m_boundVertexArrayObject->getVertexAttribState(0);
- if (state.enabled && usingVertexAttrib0)
- return false;
- if (!usingVertexAttrib0 && !m_vertexAttrib0UsedBefore)
- return false;
- m_vertexAttrib0UsedBefore = true;
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer->object());
-
- Checked<GC3Dsizei> bufferSize(numVertex);
- bufferSize += 1;
- bufferSize *= Checked<GC3Dsizei>(4);
-
- Checked<GC3Dsizeiptr> bufferDataSize(bufferSize);
- bufferDataSize *= Checked<GC3Dsizeiptr>(sizeof(GC3Dfloat));
-
- if (bufferDataSize.unsafeGet() > m_vertexAttrib0BufferSize) {
- m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, bufferDataSize.unsafeGet(), 0, GraphicsContext3D::DYNAMIC_DRAW);
- m_vertexAttrib0BufferSize = bufferDataSize.unsafeGet();
- m_forceAttrib0BufferRefill = true;
- }
-
- auto& attribValue = m_vertexAttribValue[0];
-
- if (usingVertexAttrib0
- && (m_forceAttrib0BufferRefill
- || attribValue.value[0] != m_vertexAttrib0BufferValue[0]
- || attribValue.value[1] != m_vertexAttrib0BufferValue[1]
- || attribValue.value[2] != m_vertexAttrib0BufferValue[2]
- || attribValue.value[3] != m_vertexAttrib0BufferValue[3])) {
-
- auto bufferData = std::make_unique<GC3Dfloat[]>(bufferSize.unsafeGet());
- for (GC3Dsizei ii = 0; ii < numVertex + 1; ++ii) {
- bufferData[ii * 4] = attribValue.value[0];
- bufferData[ii * 4 + 1] = attribValue.value[1];
- bufferData[ii * 4 + 2] = attribValue.value[2];
- bufferData[ii * 4 + 3] = attribValue.value[3];
- }
- m_vertexAttrib0BufferValue[0] = attribValue.value[0];
- m_vertexAttrib0BufferValue[1] = attribValue.value[1];
- m_vertexAttrib0BufferValue[2] = attribValue.value[2];
- m_vertexAttrib0BufferValue[3] = attribValue.value[3];
- m_forceAttrib0BufferRefill = false;
- m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, 0, bufferDataSize.unsafeGet(), bufferData.get());
- }
- m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, 0, 0, 0);
- return true;
-}
-
-void WebGLRenderingContextBase::restoreStatesAfterVertexAttrib0Simulation()
-{
- const WebGLVertexArrayObjectBase::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(0);
- if (state.bufferBinding != m_vertexAttrib0Buffer) {
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(state.bufferBinding.get()));
- m_context->vertexAttribPointer(0, state.size, state.type, state.normalized, state.originalStride, state.offset);
- }
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundArrayBuffer.get()));
-}
-
-void WebGLRenderingContextBase::dispatchContextLostEvent()
-{
- RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, "");
- canvas()->dispatchEvent(event);
- m_restoreAllowed = event->defaultPrevented();
- if (m_contextLostMode == RealLostContext && m_restoreAllowed)
- m_restoreTimer.startOneShot(0);
-}
-
-void WebGLRenderingContextBase::maybeRestoreContext()
-{
- ASSERT(m_contextLost);
- if (!m_contextLost)
- return;
-
- // The rendering context is not restored unless the default behavior of the
- // webglcontextlost event was prevented earlier.
- //
- // Because of the way m_restoreTimer is set up for real vs. synthetic lost
- // context events, we don't have to worry about this test short-circuiting
- // the retry loop for real context lost events.
- if (!m_restoreAllowed)
- return;
-
- int contextLostReason = m_context->getExtensions()->getGraphicsResetStatusARB();
-
- switch (contextLostReason) {
- case GraphicsContext3D::NO_ERROR:
- // The GraphicsContext3D implementation might not fully
- // support GL_ARB_robustness semantics yet. Alternatively, the
- // WEBGL_lose_context extension might have been used to force
- // a lost context.
- break;
- case Extensions3D::GUILTY_CONTEXT_RESET_ARB:
- // The rendering context is not restored if this context was
- // guilty of causing the graphics reset.
- printWarningToConsole("WARNING: WebGL content on the page caused the graphics card to reset; not restoring the context");
- return;
- case Extensions3D::INNOCENT_CONTEXT_RESET_ARB:
- // Always allow the context to be restored.
- break;
- case Extensions3D::UNKNOWN_CONTEXT_RESET_ARB:
- // Warn. Ideally, prompt the user telling them that WebGL
- // content on the page might have caused the graphics card to
- // reset and ask them whether they want to continue running
- // the content. Only if they say "yes" should we start
- // attempting to restore the context.
- printWarningToConsole("WARNING: WebGL content on the page might have caused the graphics card to reset");
- break;
- }
-
- Frame* frame = canvas()->document().frame();
- if (!frame)
- return;
-
- if (!frame->loader().client().allowWebGL(frame->settings().webGLEnabled()))
- return;
-
- FrameView* view = frame->view();
- if (!view)
- return;
- ScrollView* root = view->root();
- if (!root)
- return;
- HostWindow* hostWindow = root->hostWindow();
- if (!hostWindow)
- return;
-
- RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, hostWindow));
- if (!context) {
- if (m_contextLostMode == RealLostContext)
- m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
- else
- // This likely shouldn't happen but is the best way to report it to the WebGL app.
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "", "error restoring context");
- return;
- }
-
- m_context = context;
- m_contextLost = false;
- setupFlags();
- initializeNewContext();
- initializeVertexArrayObjects();
- canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, false, true, ""));
-}
-
-String WebGLRenderingContextBase::ensureNotNull(const String& text) const
-{
- if (text.isNull())
- return WTF::emptyString();
- return text;
-}
-
-WebGLRenderingContextBase::LRUImageBufferCache::LRUImageBufferCache(int capacity)
- : m_buffers(std::make_unique<std::unique_ptr<ImageBuffer>[]>(capacity))
- , m_capacity(capacity)
-{
-}
-
-ImageBuffer* WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer(const IntSize& size)
-{
- int i;
- for (i = 0; i < m_capacity; ++i) {
- ImageBuffer* buf = m_buffers[i].get();
- if (!buf)
- break;
- if (buf->logicalSize() != size)
- continue;
- bubbleToFront(i);
- return buf;
- }
-
- // FIXME (149423): Should this ImageBuffer be unconditionally unaccelerated?
- std::unique_ptr<ImageBuffer> temp = ImageBuffer::create(size, Unaccelerated);
- if (!temp)
- return nullptr;
- i = std::min(m_capacity - 1, i);
- m_buffers[i] = WTF::move(temp);
-
- ImageBuffer* buf = m_buffers[i].get();
- bubbleToFront(i);
- return buf;
-}
-
-void WebGLRenderingContextBase::LRUImageBufferCache::bubbleToFront(int idx)
-{
- for (int i = idx; i > 0; --i)
- m_buffers[i].swap(m_buffers[i-1]);
-}
-
-namespace {
-
- String GetErrorString(GC3Denum error)
- {
- switch (error) {
- case GraphicsContext3D::INVALID_ENUM:
- return "INVALID_ENUM";
- case GraphicsContext3D::INVALID_VALUE:
- return "INVALID_VALUE";
- case GraphicsContext3D::INVALID_OPERATION:
- return "INVALID_OPERATION";
- case GraphicsContext3D::OUT_OF_MEMORY:
- return "OUT_OF_MEMORY";
- case GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION:
- return "INVALID_FRAMEBUFFER_OPERATION";
- case GraphicsContext3D::CONTEXT_LOST_WEBGL:
- return "CONTEXT_LOST_WEBGL";
- default:
- return String::format("WebGL ERROR(%04x)", error);
- }
- }
-
-} // namespace anonymous
-
-void WebGLRenderingContextBase::synthesizeGLError(GC3Denum error, const char* functionName, const char* description, ConsoleDisplayPreference display)
-{
- if (m_synthesizedErrorsToConsole && display == DisplayInConsole) {
- String str = String("WebGL: ") + GetErrorString(error) + ": " + String(functionName) + ": " + String(description);
- printGLErrorToConsole(str);
- }
- m_context->synthesizeGLError(error);
-}
-
-
-void WebGLRenderingContextBase::printGLWarningToConsole(const char* functionName, const char* description)
-{
- if (m_synthesizedErrorsToConsole) {
- String str = String("WebGL: ") + String(functionName) + ": " + String(description);
- printGLErrorToConsole(str);
- }
-}
-
-void WebGLRenderingContextBase::applyStencilTest()
-{
- bool haveStencilBuffer = false;
-
- if (m_framebufferBinding)
- haveStencilBuffer = m_framebufferBinding->hasStencilBuffer();
- else {
- RefPtr<WebGLContextAttributes> attributes = getContextAttributes();
- haveStencilBuffer = attributes->stencil();
- }
- enableOrDisable(GraphicsContext3D::STENCIL_TEST,
- m_stencilEnabled && haveStencilBuffer);
-}
-
-void WebGLRenderingContextBase::enableOrDisable(GC3Denum capability, bool enable)
-{
- if (enable)
- m_context->enable(capability);
- else
- m_context->disable(capability);
-}
-
-IntSize WebGLRenderingContextBase::clampedCanvasSize()
-{
- return IntSize(clamp(canvas()->width(), 1, m_maxViewportDims[0]),
- clamp(canvas()->height(), 1, m_maxViewportDims[1]));
-}
-
-GC3Dint WebGLRenderingContextBase::getMaxDrawBuffers()
-{
- if (!supportsDrawBuffers())
- return 0;
- if (!m_maxDrawBuffers)
- m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &m_maxDrawBuffers);
- if (!m_maxColorAttachments)
- m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
- // WEBGL_draw_buffers requires MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
- return std::min(m_maxDrawBuffers, m_maxColorAttachments);
-}
-
-GC3Dint WebGLRenderingContextBase::getMaxColorAttachments()
-{
- if (!supportsDrawBuffers())
- return 0;
- if (!m_maxColorAttachments)
- m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
- return m_maxColorAttachments;
-}
-
-void WebGLRenderingContextBase::setBackDrawBuffer(GC3Denum buf)
-{
- m_backDrawBuffer = buf;
-}
-
-void WebGLRenderingContextBase::restoreCurrentFramebuffer()
-{
- ExceptionCode ec;
- bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_framebufferBinding.get(), ec);
-}
-
-void WebGLRenderingContextBase::restoreCurrentTexture2D()
-{
- ExceptionCode ec;
- bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureUnits[m_activeTextureUnit].texture2DBinding.get(), ec);
-}
-
-bool WebGLRenderingContextBase::supportsDrawBuffers()
-{
- if (!m_drawBuffersWebGLRequirementsChecked) {
- m_drawBuffersWebGLRequirementsChecked = true;
- m_drawBuffersSupported = WebGLDrawBuffers::supported(this);
- }
- return m_drawBuffersSupported;
-}
-
-void WebGLRenderingContextBase::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
-{
- if (!primcount) {
- markContextChanged();
- return;
- }
-
- if (!validateDrawArrays("drawArraysInstanced", mode, first, count, primcount))
- return;
-
- clearIfComposited();
-
- bool vertexAttrib0Simulated = false;
- if (!isGLES2Compliant())
- vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawArraysInstanced", true);
-
- m_context->drawArraysInstanced(mode, first, count, primcount);
-
- if (!isGLES2Compliant() && vertexAttrib0Simulated)
- restoreStatesAfterVertexAttrib0Simulation();
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawArraysInstanced", false);
- markContextChanged();
-}
-
-void WebGLRenderingContextBase::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount)
-{
- if (!primcount) {
- markContextChanged();
- return;
- }
-
- unsigned numElements = 0;
- if (!validateDrawElements("drawElementsInstanced", mode, count, type, offset, numElements, primcount))
- return;
-
- clearIfComposited();
-
- bool vertexAttrib0Simulated = false;
- if (!isGLES2Compliant()) {
- if (!numElements)
- validateIndexArrayPrecise(count, type, static_cast<GC3Dintptr>(offset), numElements);
- vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
- }
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawElementsInstanced", true);
-
- m_context->drawElementsInstanced(mode, count, type, static_cast<GC3Dintptr>(offset), primcount);
-
- if (!isGLES2Compliant() && vertexAttrib0Simulated)
- restoreStatesAfterVertexAttrib0Simulation();
- if (!isGLES2NPOTStrict())
- checkTextureCompleteness("drawElementsInstanced", false);
- markContextChanged();
-}
-
-void WebGLRenderingContextBase::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
-{
- if (isContextLostOrPending())
- return;
-
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribDivisor", "index out of range");
- return;
- }
-
- m_boundVertexArrayObject->setVertexAttribDivisor(index, divisor);
- m_context->vertexAttribDivisor(index, divisor);
-}
-
-
-} // namespace WebCore
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContextBase.h b/Source/WebCore/html/canvas/WebGLRenderingContextBase.h
deleted file mode 100644
index 73c22310f..000000000
--- a/Source/WebCore/html/canvas/WebGLRenderingContextBase.h
+++ /dev/null
@@ -1,842 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebGLRenderingContextBase_h
-#define WebGLRenderingContextBase_h
-
-#include "ActiveDOMObject.h"
-#include "CanvasRenderingContext.h"
-#include "GraphicsContext3D.h"
-#include "ImageBuffer.h"
-#include "Timer.h"
-#include "WebGLGetInfo.h"
-#include "WebGLObject.h"
-#include <memory>
-#include <runtime/Float32Array.h>
-#include <runtime/Int32Array.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class ANGLEInstancedArrays;
-class EXTBlendMinMax;
-class EXTTextureFilterAnisotropic;
-class EXTShaderTextureLOD;
-class EXTsRGB;
-class EXTFragDepth;
-class HTMLImageElement;
-class HTMLVideoElement;
-class ImageBuffer;
-class ImageData;
-class IntSize;
-class OESStandardDerivatives;
-class OESTextureFloat;
-class OESTextureFloatLinear;
-class OESTextureHalfFloat;
-class OESTextureHalfFloatLinear;
-class OESVertexArrayObject;
-class OESElementIndexUint;
-class WebGLActiveInfo;
-class WebGLBuffer;
-class WebGLContextGroup;
-class WebGLContextObject;
-class WebGLCompressedTextureATC;
-class WebGLCompressedTexturePVRTC;
-class WebGLCompressedTextureS3TC;
-class WebGLContextAttributes;
-class WebGLDebugRendererInfo;
-class WebGLDebugShaders;
-class WebGLDepthTexture;
-class WebGLDrawBuffers;
-class WebGLExtension;
-class WebGLFramebuffer;
-class WebGLLoseContext;
-class WebGLObject;
-class WebGLProgram;
-class WebGLRenderbuffer;
-class WebGLShader;
-class WebGLSharedObject;
-class WebGLShaderPrecisionFormat;
-class WebGLTexture;
-class WebGLUniformLocation;
-class WebGLVertexArrayObjectOES;
-
-typedef int ExceptionCode;
-
-inline void clip1D(GC3Dint start, GC3Dsizei range, GC3Dsizei sourceRange, GC3Dint* clippedStart, GC3Dsizei* clippedRange)
-{
- ASSERT(clippedStart && clippedRange);
- if (start < 0) {
- range += start;
- start = 0;
- }
- GC3Dint end = start + range;
- if (end > sourceRange)
- range -= end - sourceRange;
- *clippedStart = start;
- *clippedRange = range;
-}
-
-// Returns false if no clipping is necessary, i.e., x, y, width, height stay the same.
-inline bool clip2D(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height,
- GC3Dsizei sourceWidth, GC3Dsizei sourceHeight,
- GC3Dint* clippedX, GC3Dint* clippedY, GC3Dsizei* clippedWidth, GC3Dsizei*clippedHeight)
-{
- ASSERT(clippedX && clippedY && clippedWidth && clippedHeight);
- clip1D(x, width, sourceWidth, clippedX, clippedWidth);
- clip1D(y, height, sourceHeight, clippedY, clippedHeight);
- return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height);
-}
-
-class WebGLRenderingContextBase : public CanvasRenderingContext, public ActiveDOMObject {
-public:
- static std::unique_ptr<WebGLRenderingContextBase> create(HTMLCanvasElement*, WebGLContextAttributes*, const String&);
- virtual ~WebGLRenderingContextBase();
-
-#if PLATFORM(WIN)
- // FIXME: Implement accelerated 3d canvas on Windows.
- virtual bool isAccelerated() const override { return false; }
-#else
- virtual bool isAccelerated() const override { return true; }
-#endif
-
- int drawingBufferWidth() const;
- int drawingBufferHeight() const;
-
- void activeTexture(GC3Denum texture, ExceptionCode&);
- void attachShader(WebGLProgram*, WebGLShader*, ExceptionCode&);
- void bindAttribLocation(WebGLProgram*, GC3Duint index, const String& name, ExceptionCode&);
- void bindBuffer(GC3Denum target, WebGLBuffer*, ExceptionCode&);
- void bindFramebuffer(GC3Denum target, WebGLFramebuffer*, ExceptionCode&);
- void bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*, ExceptionCode&);
- void bindTexture(GC3Denum target, WebGLTexture*, ExceptionCode&);
- void blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
- void blendEquation(GC3Denum mode);
- void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha);
- void blendFunc(GC3Denum sfactor, GC3Denum dfactor);
- void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha);
-
- void bufferData(GC3Denum target, long long size, GC3Denum usage, ExceptionCode&);
- void bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage, ExceptionCode&);
- void bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage, ExceptionCode&);
- void bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data, ExceptionCode&);
- void bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data, ExceptionCode&);
-
- GC3Denum checkFramebufferStatus(GC3Denum target);
- virtual void clear(GC3Dbitfield mask) = 0;
- void clearColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
- void clearDepth(GC3Dfloat);
- void clearStencil(GC3Dint);
- void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha);
- void compileShader(WebGLShader*, ExceptionCode&);
-
- void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
- GC3Dsizei height, GC3Dint border, ArrayBufferView* data);
- void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data);
-
- virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) = 0;
- void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
-
- PassRefPtr<WebGLBuffer> createBuffer();
- PassRefPtr<WebGLFramebuffer> createFramebuffer();
- PassRefPtr<WebGLProgram> createProgram();
- PassRefPtr<WebGLRenderbuffer> createRenderbuffer();
- PassRefPtr<WebGLShader> createShader(GC3Denum type, ExceptionCode&);
- PassRefPtr<WebGLTexture> createTexture();
-
- void cullFace(GC3Denum mode);
-
- void deleteBuffer(WebGLBuffer*);
- void deleteFramebuffer(WebGLFramebuffer*);
- void deleteProgram(WebGLProgram*);
- void deleteRenderbuffer(WebGLRenderbuffer*);
- void deleteShader(WebGLShader*);
- void deleteTexture(WebGLTexture*);
-
- void depthFunc(GC3Denum);
- void depthMask(GC3Dboolean);
- void depthRange(GC3Dfloat zNear, GC3Dfloat zFar);
- void detachShader(WebGLProgram*, WebGLShader*, ExceptionCode&);
- void disable(GC3Denum cap);
- void disableVertexAttribArray(GC3Duint index, ExceptionCode&);
- void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count, ExceptionCode&);
- void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, ExceptionCode&);
-
- void enable(GC3Denum cap);
- void enableVertexAttribArray(GC3Duint index, ExceptionCode&);
- void finish();
- void flush();
- void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer*, ExceptionCode&);
- void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture*, GC3Dint level, ExceptionCode&);
- void frontFace(GC3Denum mode);
- void generateMipmap(GC3Denum target);
-
- PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GC3Duint index, ExceptionCode&);
- PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GC3Duint index, ExceptionCode&);
- bool getAttachedShaders(WebGLProgram*, Vector<RefPtr<WebGLShader>>&, ExceptionCode&);
- GC3Dint getAttribLocation(WebGLProgram*, const String& name);
- WebGLGetInfo getBufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode&);
- PassRefPtr<WebGLContextAttributes> getContextAttributes();
- GC3Denum getError();
- virtual WebGLExtension* getExtension(const String& name) = 0;
- virtual WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&) = 0;
- virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&) = 0;
- WebGLGetInfo getProgramParameter(WebGLProgram*, GC3Denum pname, ExceptionCode&);
- String getProgramInfoLog(WebGLProgram*, ExceptionCode&);
- WebGLGetInfo getRenderbufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode&);
- WebGLGetInfo getShaderParameter(WebGLShader*, GC3Denum pname, ExceptionCode&);
- String getShaderInfoLog(WebGLShader*, ExceptionCode&);
- PassRefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType, ExceptionCode&);
- String getShaderSource(WebGLShader*, ExceptionCode&);
- virtual Vector<String> getSupportedExtensions() = 0;
- WebGLGetInfo getTexParameter(GC3Denum target, GC3Denum pname, ExceptionCode&);
- WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*, ExceptionCode&);
- PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&, ExceptionCode&);
- WebGLGetInfo getVertexAttrib(GC3Duint index, GC3Denum pname, ExceptionCode&);
- long long getVertexAttribOffset(GC3Duint index, GC3Denum pname);
-
- virtual void hint(GC3Denum target, GC3Denum mode) = 0;
- GC3Dboolean isBuffer(WebGLBuffer*);
- bool isContextLost() const;
- GC3Dboolean isEnabled(GC3Denum cap);
- GC3Dboolean isFramebuffer(WebGLFramebuffer*);
- GC3Dboolean isProgram(WebGLProgram*);
- GC3Dboolean isRenderbuffer(WebGLRenderbuffer*);
- GC3Dboolean isShader(WebGLShader*);
- GC3Dboolean isTexture(WebGLTexture*);
-
- void lineWidth(GC3Dfloat);
- void linkProgram(WebGLProgram*, ExceptionCode&);
- void pixelStorei(GC3Denum pname, GC3Dint param);
- void polygonOffset(GC3Dfloat factor, GC3Dfloat units);
- void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&);
- void releaseShaderCompiler();
- virtual void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) = 0;
- void sampleCoverage(GC3Dfloat value, GC3Dboolean invert);
- void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
- void shaderSource(WebGLShader*, const String&, ExceptionCode&);
- void stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask);
- void stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask);
- void stencilMask(GC3Duint);
- void stencilMaskSeparate(GC3Denum face, GC3Duint mask);
- void stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
- void stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
-
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&);
-#if ENABLE(VIDEO)
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&);
-#endif
-
- void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param);
- void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param);
-
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&) = 0;
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&) = 0;
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&) = 0;
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&) = 0;
-#if ENABLE(VIDEO)
- virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&) = 0;
-#endif
-
- void uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode&);
- void uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
- void uniform1fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode&);
- void uniform1i(const WebGLUniformLocation* location, GC3Dint x, ExceptionCode&);
- void uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
- void uniform1iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode&);
- void uniform2f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, ExceptionCode&);
- void uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
- void uniform2fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode&);
- void uniform2i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, ExceptionCode&);
- void uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
- void uniform2iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode&);
- void uniform3f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, ExceptionCode&);
- void uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
- void uniform3fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode&);
- void uniform3i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, ExceptionCode&);
- void uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
- void uniform3iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode&);
- void uniform4f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w, ExceptionCode&);
- void uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
- void uniform4fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode&);
- void uniform4i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w, ExceptionCode&);
- void uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
- void uniform4iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode&);
- void uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value, ExceptionCode&);
- void uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei size, ExceptionCode&);
- void uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value, ExceptionCode&);
- void uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei size, ExceptionCode&);
- void uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* value, ExceptionCode&);
- void uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei size, ExceptionCode&);
-
- void useProgram(WebGLProgram*, ExceptionCode&);
- void validateProgram(WebGLProgram*, ExceptionCode&);
-
- void vertexAttrib1f(GC3Duint index, GC3Dfloat x);
- void vertexAttrib1fv(GC3Duint index, Float32Array* values);
- void vertexAttrib1fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
- void vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y);
- void vertexAttrib2fv(GC3Duint index, Float32Array* values);
- void vertexAttrib2fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
- void vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
- void vertexAttrib3fv(GC3Duint index, Float32Array* values);
- void vertexAttrib3fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
- void vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
- void vertexAttrib4fv(GC3Duint index, Float32Array* values);
- void vertexAttrib4fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
- void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized,
- GC3Dsizei stride, long long offset, ExceptionCode&);
-
- void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
-
- // WEBKIT_lose_context support
- enum LostContextMode {
- // Lost context occurred at the graphics system level.
- RealLostContext,
-
- // Lost context provoked by WEBKIT_lose_context.
- SyntheticLostContext
- };
- void forceLostContext(LostContextMode);
- void forceRestoreContext();
- void loseContextImpl(LostContextMode);
-
- GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
- WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
- virtual PlatformLayer* platformLayer() const override;
-
- void reshape(int width, int height);
-
- void markLayerComposited();
- virtual void paintRenderingResultsToCanvas() override;
- PassRefPtr<ImageData> paintRenderingResultsToImageData();
-
- void removeSharedObject(WebGLSharedObject*);
- void removeContextObject(WebGLContextObject*);
-
- unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; }
-
- // Instanced Array helper functions.
- void drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
- void drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount);
- void vertexAttribDivisor(GC3Duint index, GC3Duint divisor);
-
-protected:
- WebGLRenderingContextBase(HTMLCanvasElement*, GraphicsContext3D::Attributes);
- WebGLRenderingContextBase(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>, GraphicsContext3D::Attributes);
-
- friend class WebGLDrawBuffers;
- friend class WebGLFramebuffer;
- friend class WebGLObject;
- friend class OESVertexArrayObject;
- friend class WebGLDebugShaders;
- friend class WebGLCompressedTextureATC;
- friend class WebGLCompressedTexturePVRTC;
- friend class WebGLCompressedTextureS3TC;
- friend class WebGLRenderingContextErrorMessageCallback;
- friend class WebGLVertexArrayObjectOES;
- friend class WebGLVertexArrayObject;
- friend class WebGLVertexArrayObjectBase;
-
- virtual void initializeNewContext();
- virtual void initializeVertexArrayObjects() = 0;
- void setupFlags();
-
- // ActiveDOMObject
- virtual bool hasPendingActivity() const override;
- virtual void stop() override;
- virtual const char* activeDOMObjectName() const override;
- bool canSuspendForPageCache() const override;
-
- void addSharedObject(WebGLSharedObject*);
- void addContextObject(WebGLContextObject*);
- void detachAndRemoveAllObjects();
-
- void destroyGraphicsContext3D();
- void markContextChanged();
-
- // Query whether it is built on top of compliant GLES2 implementation.
- bool isGLES2Compliant() { return m_isGLES2Compliant; }
- // Query if the GL implementation is NPOT strict.
- bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
- // Query if the GL implementation generates errors on out-of-bounds buffer accesses.
- bool isErrorGeneratedOnOutOfBoundsAccesses() { return m_isErrorGeneratedOnOutOfBoundsAccesses; }
- // Query if the GL implementation initializes textures/renderbuffers to 0.
- bool isResourceSafe() { return m_isResourceSafe; }
- // Query if depth_stencil buffer is supported.
- bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
-
- // Helper to return the size in bytes of OpenGL data types
- // like GL_FLOAT, GL_INT, etc.
- unsigned int sizeInBytes(GC3Denum type);
-
- // Basic validation of count and offset against number of elements in element array buffer
- bool validateElementArraySize(GC3Dsizei count, GC3Denum type, GC3Dintptr offset);
-
- // Conservative but quick index validation
- virtual bool validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired) = 0;
-
- // Precise but slow index validation -- only done if conservative checks fail
- bool validateIndexArrayPrecise(GC3Dsizei count, GC3Denum type, GC3Dintptr offset, unsigned& numElementsRequired);
- bool validateVertexAttributes(unsigned elementCount, unsigned primitiveCount = 0);
-
- bool validateWebGLObject(const char*, WebGLObject*);
-
- bool validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
- bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned& numElements, GC3Dsizei primcount);
-
- // Adds a compressed texture format.
- void addCompressedTextureFormat(GC3Denum);
-
- PassRefPtr<Image> drawImageIntoBuffer(Image*, int width, int height, int deviceScaleFactor);
-
-#if ENABLE(VIDEO)
- PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy, ExceptionCode&);
-#endif
-
- RefPtr<GraphicsContext3D> m_context;
- RefPtr<WebGLContextGroup> m_contextGroup;
-
- // Dispatches a context lost event once it is determined that one is needed.
- // This is used both for synthetic and real context losses. For real ones, it's
- // likely that there's no JavaScript on the stack, but that might be dependent
- // on how exactly the platform discovers that the context was lost. For better
- // portability we always defer the dispatch of the event.
- Timer m_dispatchContextLostEventTimer;
- bool m_restoreAllowed;
- Timer m_restoreTimer;
-
- bool m_needsUpdate;
- bool m_markedCanvasDirty;
- HashSet<WebGLContextObject*> m_contextObjects;
-
- // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
- RefPtr<WebGLBuffer> m_boundArrayBuffer;
-
- RefPtr<WebGLVertexArrayObjectBase> m_defaultVertexArrayObject;
- RefPtr<WebGLVertexArrayObjectBase> m_boundVertexArrayObject;
- void setBoundVertexArrayObject(PassRefPtr<WebGLVertexArrayObjectBase> arrayObject)
- {
- if (arrayObject)
- m_boundVertexArrayObject = arrayObject;
- else
- m_boundVertexArrayObject = m_defaultVertexArrayObject;
- }
-
- class VertexAttribValue {
- public:
- VertexAttribValue()
- {
- initValue();
- }
-
- void initValue()
- {
- value[0] = 0.0f;
- value[1] = 0.0f;
- value[2] = 0.0f;
- value[3] = 1.0f;
- }
-
- GC3Dfloat value[4];
- };
- Vector<VertexAttribValue> m_vertexAttribValue;
- unsigned m_maxVertexAttribs;
- RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
- long m_vertexAttrib0BufferSize;
- GC3Dfloat m_vertexAttrib0BufferValue[4];
- bool m_forceAttrib0BufferRefill;
- bool m_vertexAttrib0UsedBefore;
-
- RefPtr<WebGLProgram> m_currentProgram;
- RefPtr<WebGLFramebuffer> m_framebufferBinding;
- RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
- struct TextureUnitState {
- RefPtr<WebGLTexture> texture2DBinding;
- RefPtr<WebGLTexture> textureCubeMapBinding;
- };
- Vector<TextureUnitState> m_textureUnits;
- unsigned long m_activeTextureUnit;
-
- RefPtr<WebGLTexture> m_blackTexture2D;
- RefPtr<WebGLTexture> m_blackTextureCubeMap;
-
- Vector<GC3Denum> m_compressedTextureFormats;
-
- // Fixed-size cache of reusable image buffers for video texImage2D calls.
- class LRUImageBufferCache {
- public:
- LRUImageBufferCache(int capacity);
- // The pointer returned is owned by the image buffer map.
- ImageBuffer* imageBuffer(const IntSize& size);
- private:
- void bubbleToFront(int idx);
- std::unique_ptr<std::unique_ptr<ImageBuffer>[]> m_buffers;
- int m_capacity;
- };
- LRUImageBufferCache m_generatedImageCache;
-
- GC3Dint m_maxTextureSize;
- GC3Dint m_maxCubeMapTextureSize;
- GC3Dint m_maxRenderbufferSize;
- GC3Dint m_maxViewportDims[2];
- GC3Dint m_maxTextureLevel;
- GC3Dint m_maxCubeMapTextureLevel;
-
- GC3Dint m_maxDrawBuffers;
- GC3Dint m_maxColorAttachments;
- GC3Denum m_backDrawBuffer;
- bool m_drawBuffersWebGLRequirementsChecked;
- bool m_drawBuffersSupported;
-
- GC3Dint m_packAlignment;
- GC3Dint m_unpackAlignment;
- bool m_unpackFlipY;
- bool m_unpackPremultiplyAlpha;
- GC3Denum m_unpackColorspaceConversion;
- bool m_contextLost;
- LostContextMode m_contextLostMode;
- GraphicsContext3D::Attributes m_attributes;
-
- bool m_layerCleared;
- GC3Dfloat m_clearColor[4];
- bool m_scissorEnabled;
- GC3Dfloat m_clearDepth;
- GC3Dint m_clearStencil;
- GC3Dboolean m_colorMask[4];
- GC3Dboolean m_depthMask;
-
- bool m_stencilEnabled;
- GC3Duint m_stencilMask, m_stencilMaskBack;
- GC3Dint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
- GC3Duint m_stencilFuncMask, m_stencilFuncMaskBack;
-
- bool m_isGLES2Compliant;
- bool m_isGLES2NPOTStrict;
- bool m_isErrorGeneratedOnOutOfBoundsAccesses;
- bool m_isResourceSafe;
- bool m_isDepthStencilSupported;
- bool m_isRobustnessEXTSupported;
-
- bool m_synthesizedErrorsToConsole;
- int m_numGLErrorsToConsoleAllowed;
-
- // A WebGLRenderingContext can be created in a state where it appears as
- // a valid and active context, but will not execute any important operations
- // until its load policy is completely resolved.
- bool m_isPendingPolicyResolution;
- bool m_hasRequestedPolicyResolution;
- bool isContextLostOrPending();
-
- // Enabled extension objects. FIXME: Move these to WebGL1RenderingContext, not needed for WebGL2
- std::unique_ptr<EXTFragDepth> m_extFragDepth;
- std::unique_ptr<EXTBlendMinMax> m_extBlendMinMax;
- std::unique_ptr<EXTsRGB> m_extsRGB;
- std::unique_ptr<EXTTextureFilterAnisotropic> m_extTextureFilterAnisotropic;
- std::unique_ptr<EXTShaderTextureLOD> m_extShaderTextureLOD;
- std::unique_ptr<OESTextureFloat> m_oesTextureFloat;
- std::unique_ptr<OESTextureFloatLinear> m_oesTextureFloatLinear;
- std::unique_ptr<OESTextureHalfFloat> m_oesTextureHalfFloat;
- std::unique_ptr<OESTextureHalfFloatLinear> m_oesTextureHalfFloatLinear;
- std::unique_ptr<OESStandardDerivatives> m_oesStandardDerivatives;
- std::unique_ptr<OESVertexArrayObject> m_oesVertexArrayObject;
- std::unique_ptr<OESElementIndexUint> m_oesElementIndexUint;
- std::unique_ptr<WebGLLoseContext> m_webglLoseContext;
- std::unique_ptr<WebGLDebugRendererInfo> m_webglDebugRendererInfo;
- std::unique_ptr<WebGLDebugShaders> m_webglDebugShaders;
- std::unique_ptr<WebGLCompressedTextureATC> m_webglCompressedTextureATC;
- std::unique_ptr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC;
- std::unique_ptr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC;
- std::unique_ptr<WebGLDepthTexture> m_webglDepthTexture;
- std::unique_ptr<WebGLDrawBuffers> m_webglDrawBuffers;
- std::unique_ptr<ANGLEInstancedArrays> m_angleInstancedArrays;
-
- // Helpers for getParameter and others
- WebGLGetInfo getBooleanParameter(GC3Denum);
- WebGLGetInfo getBooleanArrayParameter(GC3Denum);
- WebGLGetInfo getFloatParameter(GC3Denum);
- WebGLGetInfo getIntParameter(GC3Denum);
- WebGLGetInfo getUnsignedIntParameter(GC3Denum);
- WebGLGetInfo getInt64Parameter(GC3Denum);
- WebGLGetInfo getWebGLFloatArrayParameter(GC3Denum);
- WebGLGetInfo getWebGLIntArrayParameter(GC3Denum);
-
- // Clear the backbuffer if it was composited since the last operation.
- // clearMask is set to the bitfield of any clear that would happen anyway at this time
- // and the function returns true if that clear is now unnecessary.
- bool clearIfComposited(GC3Dbitfield clearMask = 0);
-
- // Helper to restore state that clearing the framebuffer may destroy.
- void restoreStateAfterClear();
-
- void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&);
- void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&);
- virtual void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&) = 0;
- virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&) = 0;
-
- void checkTextureCompleteness(const char*, bool);
-
- void createFallbackBlackTextures1x1();
-
- // Helper function for copyTex{Sub}Image, check whether the internalformat
- // and the color buffer format of the current bound framebuffer combination
- // is valid.
- bool isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat,
- GC3Denum colorBufferFormat);
-
- // Helper function to get the bound framebuffer's color buffer format.
- GC3Denum getBoundFramebufferColorFormat();
-
- // Helper function to get the bound framebuffer's width.
- int getBoundFramebufferWidth();
-
- // Helper function to get the bound framebuffer's height.
- int getBoundFramebufferHeight();
-
- // Helper function to verify limits on the length of uniform and attribute locations.
- bool validateLocationLength(const char* functionName, const String&);
-
- // Helper function to check if size is non-negative.
- // Generate GL error and return false for negative inputs; otherwise, return true.
- bool validateSize(const char* functionName, GC3Dint x, GC3Dint y);
-
- // Helper function to check if all characters in the string belong to the
- // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
- bool validateString(const char* functionName, const String&);
-
- // Helper function to check target and texture bound to the target.
- // Generate GL errors and return 0 if target is invalid or texture bound is
- // null. Otherwise, return the texture bound to the target.
- WebGLTexture* validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap);
-
- // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
- // Generates GL error and returns false if parameters are invalid.
- virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) = 0;
-
- // Helper function to check input level for functions {copy}Tex{Sub}Image.
- // Generates GL error and returns false if level is invalid.
- bool validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level);
-
- enum TexFuncValidationFunctionType {
- TexImage,
- TexSubImage,
- CopyTexImage
- };
-
- enum TexFuncValidationSourceType {
- SourceArrayBufferView,
- SourceImageData,
- SourceHTMLImageElement,
- SourceHTMLCanvasElement,
- SourceHTMLVideoElement,
- };
-
- // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
- // Otherwise, it would return quickly without doing other work.
- bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
- GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset);
-
- // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
- // Generates GL error and returns false if parameters are invalid.
- virtual bool validateTexFuncParameters(const char* functionName,
- TexFuncValidationFunctionType,
- GC3Denum target, GC3Dint level,
- GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type) = 0;
-
- enum NullDisposition {
- NullAllowed,
- NullNotAllowed
- };
-
- // Helper function to validate that the given ArrayBufferView
- // is of the correct type and contains enough data for the texImage call.
- // Generates GL error and returns false if parameters are invalid.
- virtual bool validateTexFuncData(const char* functionName, GC3Dint level,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum internalformat, GC3Denum format, GC3Denum type,
- ArrayBufferView* pixels,
- NullDisposition) = 0;
-
- // Helper function to validate a given texture format is settable as in
- // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
- // copyTexSubImage2D.
- // Generates GL error and returns false if the format is not settable.
- bool validateSettableTexFormat(const char* functionName, GC3Denum format);
-
- // Helper function to validate compressed texture data is correct size
- // for the given format and dimensions.
- bool validateCompressedTexFuncData(const char* functionName,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, ArrayBufferView* pixels);
-
- // Helper function for validating compressed texture formats.
- bool validateCompressedTexFormat(GC3Denum format);
-
- // Helper function to validate compressed texture dimensions are valid for
- // the given format.
- bool validateCompressedTexDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format);
-
- // Helper function to validate compressed texture dimensions are valid for
- // the given format.
- bool validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture*);
-
- // Helper function to validate mode for draw{Arrays/Elements}.
- bool validateDrawMode(const char* functionName, GC3Denum);
-
- // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
- bool validateStencilSettings(const char* functionName);
-
- // Helper function to validate stencil func.
- bool validateStencilFunc(const char* functionName, GC3Denum);
-
- // Helper function for texParameterf and texParameteri.
- void texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat parami, GC3Dint paramf, bool isFloat);
-
- // Helper function to print GL errors to console.
- void printGLErrorToConsole(const String&);
- void printGLWarningToConsole(const char* function, const char* reason);
-
- // Helper function to print warnings to console. Currently
- // used only to warn about use of obsolete functions.
- void printWarningToConsole(const String&);
-
- // Helper function to validate input parameters for framebuffer functions.
- // Generate GL error if parameters are illegal.
- virtual bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment) = 0;
-
- // Helper function to validate blend equation mode.
- virtual bool validateBlendEquation(const char* functionName, GC3Denum) = 0;
-
- // Helper function to validate blend func factors.
- bool validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst);
-
- // Helper function to validate a GL capability.
- virtual bool validateCapability(const char* functionName, GC3Denum) = 0;
-
- // Helper function to validate input parameters for uniform functions.
- bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GC3Dsizei mod);
- bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GC3Dsizei mod);
- bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GC3Dsizei, GC3Dsizei mod);
- bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array*, GC3Dsizei mod);
- bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei, GC3Dsizei mod);
-
- // Helper function to validate parameters for bufferData.
- // Return the current bound buffer to target, or 0 if parameters are invalid.
- WebGLBuffer* validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage);
-
- // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin.
- bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionCode&);
-
- // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin.
- bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionCode&);
-
-#if ENABLE(VIDEO)
- // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin.
- bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionCode&);
-#endif
-
- // Helper functions for vertexAttribNf{v}.
- void vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat);
- void vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array*, GC3Dsizei expectedSize);
- void vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat*, GC3Dsizei, GC3Dsizei expectedSize);
-
- // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
- // Return false if caller should return without further processing.
- bool deleteObject(WebGLObject*);
-
- // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
- // If the object has already been deleted, set deleted to true upon return.
- // Return false if caller should return without further processing.
- bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted);
-
- // Helpers for simulating vertexAttrib0.
- void initVertexAttrib0();
- bool simulateVertexAttrib0(GC3Dsizei numVertex);
- bool validateSimulatedVertexAttrib0(GC3Dsizei numVertex);
- void restoreStatesAfterVertexAttrib0Simulation();
-
- void dispatchContextLostEvent();
- // Helper for restoration after context lost.
- void maybeRestoreContext();
-
- // Determine if we are running privileged code in the browser, for example,
- // a Safari or Chrome extension.
- bool allowPrivilegedExtensions() const;
-
- enum ConsoleDisplayPreference {
- DisplayInConsole,
- DontDisplayInConsole
- };
-
- // Wrapper for GraphicsContext3D::synthesizeGLError that sends a message
- // to the JavaScript console.
- void synthesizeGLError(GC3Denum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
-
- String ensureNotNull(const String&) const;
-
- // Enable or disable stencil test based on user setting and
- // whether the current FBO has a stencil buffer.
- void applyStencilTest();
-
- // Helper for enabling or disabling a capability.
- void enableOrDisable(GC3Denum capability, bool enable);
-
- // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
- IntSize clampedCanvasSize();
-
- virtual GC3Dint getMaxDrawBuffers() = 0;
- virtual GC3Dint getMaxColorAttachments() = 0;
-
- void setBackDrawBuffer(GC3Denum);
-
- void restoreCurrentFramebuffer();
- void restoreCurrentTexture2D();
-
- // Check if EXT_draw_buffers extension is supported and if it satisfies the WebGL requirements.
- bool supportsDrawBuffers();
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl b/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl
deleted file mode 100644
index 25600ba2a..000000000
--- a/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-typedef unsigned long GLenum;
-typedef boolean GLboolean;
-typedef unsigned long GLbitfield;
-typedef byte GLbyte; /* 'byte' should be a signed 8 bit type. */
-typedef short GLshort;
-typedef long GLint;
-typedef long GLsizei;
-typedef long long GLintptr;
-typedef long long GLsizeiptr;
-typedef octet GLubyte; /* 'octet' should be an unsigned 8 bit type. */
-typedef unsigned short GLushort;
-typedef unsigned long GLuint;
-typedef unrestricted float GLfloat;
-typedef unrestricted float GLclampf;
-
-[
-NoInterfaceObject,
-Conditional=WEBGL,
-JSCustomMarkFunction,
-DoNotCheckConstants,
-] interface WebGLRenderingContextBase : CanvasRenderingContext {
-
- /* ClearBufferMask */
- const GLenum DEPTH_BUFFER_BIT = 0x00000100;
- const GLenum STENCIL_BUFFER_BIT = 0x00000400;
- const GLenum COLOR_BUFFER_BIT = 0x00004000;
-
- /* BeginMode */
- const GLenum POINTS = 0x0000;
- const GLenum LINES = 0x0001;
- const GLenum LINE_LOOP = 0x0002;
- const GLenum LINE_STRIP = 0x0003;
- const GLenum TRIANGLES = 0x0004;
- const GLenum TRIANGLE_STRIP = 0x0005;
- const GLenum TRIANGLE_FAN = 0x0006;
-
- /* AlphaFunction (not supported in ES20) */
- /* NEVER */
- /* LESS */
- /* EQUAL */
- /* LEQUAL */
- /* GREATER */
- /* NOTEQUAL */
- /* GEQUAL */
- /* ALWAYS */
-
- /* BlendingFactorDest */
- const GLenum ZERO = 0;
- const GLenum ONE = 1;
- const GLenum SRC_COLOR = 0x0300;
- const GLenum ONE_MINUS_SRC_COLOR = 0x0301;
- const GLenum SRC_ALPHA = 0x0302;
- const GLenum ONE_MINUS_SRC_ALPHA = 0x0303;
- const GLenum DST_ALPHA = 0x0304;
- const GLenum ONE_MINUS_DST_ALPHA = 0x0305;
-
- /* BlendingFactorSrc */
- /* ZERO */
- /* ONE */
- const GLenum DST_COLOR = 0x0306;
- const GLenum ONE_MINUS_DST_COLOR = 0x0307;
- const GLenum SRC_ALPHA_SATURATE = 0x0308;
- /* SRC_ALPHA */
- /* ONE_MINUS_SRC_ALPHA */
- /* DST_ALPHA */
- /* ONE_MINUS_DST_ALPHA */
-
- /* BlendEquationSeparate */
- const GLenum FUNC_ADD = 0x8006;
- const GLenum BLEND_EQUATION = 0x8009;
- const GLenum BLEND_EQUATION_RGB = 0x8009; /* same as BLEND_EQUATION */
- const GLenum BLEND_EQUATION_ALPHA = 0x883D;
-
- /* BlendSubtract */
- const GLenum FUNC_SUBTRACT = 0x800A;
- const GLenum FUNC_REVERSE_SUBTRACT = 0x800B;
-
- /* Separate Blend Functions */
- const GLenum BLEND_DST_RGB = 0x80C8;
- const GLenum BLEND_SRC_RGB = 0x80C9;
- const GLenum BLEND_DST_ALPHA = 0x80CA;
- const GLenum BLEND_SRC_ALPHA = 0x80CB;
- const GLenum CONSTANT_COLOR = 0x8001;
- const GLenum ONE_MINUS_CONSTANT_COLOR = 0x8002;
- const GLenum CONSTANT_ALPHA = 0x8003;
- const GLenum ONE_MINUS_CONSTANT_ALPHA = 0x8004;
- const GLenum BLEND_COLOR = 0x8005;
-
- /* Buffer Objects */
- const GLenum ARRAY_BUFFER = 0x8892;
- const GLenum ELEMENT_ARRAY_BUFFER = 0x8893;
- const GLenum ARRAY_BUFFER_BINDING = 0x8894;
- const GLenum ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
-
- const GLenum STREAM_DRAW = 0x88E0;
- const GLenum STATIC_DRAW = 0x88E4;
- const GLenum DYNAMIC_DRAW = 0x88E8;
-
- const GLenum BUFFER_SIZE = 0x8764;
- const GLenum BUFFER_USAGE = 0x8765;
-
- const GLenum CURRENT_VERTEX_ATTRIB = 0x8626;
-
- /* CullFaceMode */
- const GLenum FRONT = 0x0404;
- const GLenum BACK = 0x0405;
- const GLenum FRONT_AND_BACK = 0x0408;
-
- /* DepthFunction */
- /* NEVER */
- /* LESS */
- /* EQUAL */
- /* LEQUAL */
- /* GREATER */
- /* NOTEQUAL */
- /* GEQUAL */
- /* ALWAYS */
-
- /* EnableCap */
- const GLenum TEXTURE_2D = 0x0DE1;
- const GLenum CULL_FACE = 0x0B44;
- const GLenum BLEND = 0x0BE2;
- const GLenum DITHER = 0x0BD0;
- const GLenum STENCIL_TEST = 0x0B90;
- const GLenum DEPTH_TEST = 0x0B71;
- const GLenum SCISSOR_TEST = 0x0C11;
- const GLenum POLYGON_OFFSET_FILL = 0x8037;
- const GLenum SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
- const GLenum SAMPLE_COVERAGE = 0x80A0;
-
- /* ErrorCode */
- const GLenum NO_ERROR = 0;
- const GLenum INVALID_ENUM = 0x0500;
- const GLenum INVALID_VALUE = 0x0501;
- const GLenum INVALID_OPERATION = 0x0502;
- const GLenum OUT_OF_MEMORY = 0x0505;
-
- /* FrontFaceDirection */
- const GLenum CW = 0x0900;
- const GLenum CCW = 0x0901;
-
- /* GetPName */
- const GLenum LINE_WIDTH = 0x0B21;
- const GLenum ALIASED_POINT_SIZE_RANGE = 0x846D;
- const GLenum ALIASED_LINE_WIDTH_RANGE = 0x846E;
- const GLenum CULL_FACE_MODE = 0x0B45;
- const GLenum FRONT_FACE = 0x0B46;
- const GLenum DEPTH_RANGE = 0x0B70;
- const GLenum DEPTH_WRITEMASK = 0x0B72;
- const GLenum DEPTH_CLEAR_VALUE = 0x0B73;
- const GLenum DEPTH_FUNC = 0x0B74;
- const GLenum STENCIL_CLEAR_VALUE = 0x0B91;
- const GLenum STENCIL_FUNC = 0x0B92;
- const GLenum STENCIL_FAIL = 0x0B94;
- const GLenum STENCIL_PASS_DEPTH_FAIL = 0x0B95;
- const GLenum STENCIL_PASS_DEPTH_PASS = 0x0B96;
- const GLenum STENCIL_REF = 0x0B97;
- const GLenum STENCIL_VALUE_MASK = 0x0B93;
- const GLenum STENCIL_WRITEMASK = 0x0B98;
- const GLenum STENCIL_BACK_FUNC = 0x8800;
- const GLenum STENCIL_BACK_FAIL = 0x8801;
- const GLenum STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
- const GLenum STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
- const GLenum STENCIL_BACK_REF = 0x8CA3;
- const GLenum STENCIL_BACK_VALUE_MASK = 0x8CA4;
- const GLenum STENCIL_BACK_WRITEMASK = 0x8CA5;
- const GLenum VIEWPORT = 0x0BA2;
- const GLenum SCISSOR_BOX = 0x0C10;
- /* SCISSOR_TEST */
- const GLenum COLOR_CLEAR_VALUE = 0x0C22;
- const GLenum COLOR_WRITEMASK = 0x0C23;
- const GLenum UNPACK_ALIGNMENT = 0x0CF5;
- const GLenum PACK_ALIGNMENT = 0x0D05;
- const GLenum MAX_TEXTURE_SIZE = 0x0D33;
- const GLenum MAX_VIEWPORT_DIMS = 0x0D3A;
- const GLenum SUBPIXEL_BITS = 0x0D50;
- const GLenum RED_BITS = 0x0D52;
- const GLenum GREEN_BITS = 0x0D53;
- const GLenum BLUE_BITS = 0x0D54;
- const GLenum ALPHA_BITS = 0x0D55;
- const GLenum DEPTH_BITS = 0x0D56;
- const GLenum STENCIL_BITS = 0x0D57;
- const GLenum POLYGON_OFFSET_UNITS = 0x2A00;
- /* POLYGON_OFFSET_FILL */
- const GLenum POLYGON_OFFSET_FACTOR = 0x8038;
- const GLenum TEXTURE_BINDING_2D = 0x8069;
- const GLenum SAMPLE_BUFFERS = 0x80A8;
- const GLenum SAMPLES = 0x80A9;
- const GLenum SAMPLE_COVERAGE_VALUE = 0x80AA;
- const GLenum SAMPLE_COVERAGE_INVERT = 0x80AB;
-
- /* GetTextureParameter */
- /* TEXTURE_MAG_FILTER */
- /* TEXTURE_MIN_FILTER */
- /* TEXTURE_WRAP_S */
- /* TEXTURE_WRAP_T */
-
- const GLenum COMPRESSED_TEXTURE_FORMATS = 0x86A3;
-
- /* HintMode */
- const GLenum DONT_CARE = 0x1100;
- const GLenum FASTEST = 0x1101;
- const GLenum NICEST = 0x1102;
-
- /* HintTarget */
- const GLenum GENERATE_MIPMAP_HINT = 0x8192;
-
- /* DataType */
- const GLenum BYTE = 0x1400;
- const GLenum UNSIGNED_BYTE = 0x1401;
- const GLenum SHORT = 0x1402;
- const GLenum UNSIGNED_SHORT = 0x1403;
- const GLenum INT = 0x1404;
- const GLenum UNSIGNED_INT = 0x1405;
- const GLenum FLOAT = 0x1406;
-
- /* PixelFormat */
- const GLenum DEPTH_COMPONENT = 0x1902;
- const GLenum ALPHA = 0x1906;
- const GLenum RGB = 0x1907;
- const GLenum RGBA = 0x1908;
- const GLenum LUMINANCE = 0x1909;
- const GLenum LUMINANCE_ALPHA = 0x190A;
-
- /* PixelType */
- /* UNSIGNED_BYTE */
- const GLenum UNSIGNED_SHORT_4_4_4_4 = 0x8033;
- const GLenum UNSIGNED_SHORT_5_5_5_1 = 0x8034;
- const GLenum UNSIGNED_SHORT_5_6_5 = 0x8363;
-
- /* Shaders */
- const GLenum FRAGMENT_SHADER = 0x8B30;
- const GLenum VERTEX_SHADER = 0x8B31;
- const GLenum MAX_VERTEX_ATTRIBS = 0x8869;
- const GLenum MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
- const GLenum MAX_VARYING_VECTORS = 0x8DFC;
- const GLenum MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
- const GLenum MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
- const GLenum MAX_TEXTURE_IMAGE_UNITS = 0x8872;
- const GLenum MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
- const GLenum SHADER_TYPE = 0x8B4F;
- const GLenum DELETE_STATUS = 0x8B80;
- const GLenum LINK_STATUS = 0x8B82;
- const GLenum VALIDATE_STATUS = 0x8B83;
- const GLenum ATTACHED_SHADERS = 0x8B85;
- const GLenum ACTIVE_UNIFORMS = 0x8B86;
- const GLenum ACTIVE_ATTRIBUTES = 0x8B89;
- const GLenum SHADING_LANGUAGE_VERSION = 0x8B8C;
- const GLenum CURRENT_PROGRAM = 0x8B8D;
-
- /* StencilFunction */
- const GLenum NEVER = 0x0200;
- const GLenum LESS = 0x0201;
- const GLenum EQUAL = 0x0202;
- const GLenum LEQUAL = 0x0203;
- const GLenum GREATER = 0x0204;
- const GLenum NOTEQUAL = 0x0205;
- const GLenum GEQUAL = 0x0206;
- const GLenum ALWAYS = 0x0207;
-
- /* StencilOp */
- /* ZERO */
- const GLenum KEEP = 0x1E00;
- const GLenum REPLACE = 0x1E01;
- const GLenum INCR = 0x1E02;
- const GLenum DECR = 0x1E03;
- const GLenum INVERT = 0x150A;
- const GLenum INCR_WRAP = 0x8507;
- const GLenum DECR_WRAP = 0x8508;
-
- /* StringName */
- const GLenum VENDOR = 0x1F00;
- const GLenum RENDERER = 0x1F01;
- const GLenum VERSION = 0x1F02;
-
- /* TextureMagFilter */
- const GLenum NEAREST = 0x2600;
- const GLenum LINEAR = 0x2601;
-
- /* TextureMinFilter */
- /* NEAREST */
- /* LINEAR */
- const GLenum NEAREST_MIPMAP_NEAREST = 0x2700;
- const GLenum LINEAR_MIPMAP_NEAREST = 0x2701;
- const GLenum NEAREST_MIPMAP_LINEAR = 0x2702;
- const GLenum LINEAR_MIPMAP_LINEAR = 0x2703;
-
- /* TextureParameterName */
- const GLenum TEXTURE_MAG_FILTER = 0x2800;
- const GLenum TEXTURE_MIN_FILTER = 0x2801;
- const GLenum TEXTURE_WRAP_S = 0x2802;
- const GLenum TEXTURE_WRAP_T = 0x2803;
-
- /* TextureTarget */
- /* TEXTURE_2D */
- const GLenum TEXTURE = 0x1702;
-
- const GLenum TEXTURE_CUBE_MAP = 0x8513;
- const GLenum TEXTURE_BINDING_CUBE_MAP = 0x8514;
- const GLenum TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
- const GLenum TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
- const GLenum TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
- const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
- const GLenum TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
- const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
- const GLenum MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
-
- /* TextureUnit */
- const GLenum TEXTURE0 = 0x84C0;
- const GLenum TEXTURE1 = 0x84C1;
- const GLenum TEXTURE2 = 0x84C2;
- const GLenum TEXTURE3 = 0x84C3;
- const GLenum TEXTURE4 = 0x84C4;
- const GLenum TEXTURE5 = 0x84C5;
- const GLenum TEXTURE6 = 0x84C6;
- const GLenum TEXTURE7 = 0x84C7;
- const GLenum TEXTURE8 = 0x84C8;
- const GLenum TEXTURE9 = 0x84C9;
- const GLenum TEXTURE10 = 0x84CA;
- const GLenum TEXTURE11 = 0x84CB;
- const GLenum TEXTURE12 = 0x84CC;
- const GLenum TEXTURE13 = 0x84CD;
- const GLenum TEXTURE14 = 0x84CE;
- const GLenum TEXTURE15 = 0x84CF;
- const GLenum TEXTURE16 = 0x84D0;
- const GLenum TEXTURE17 = 0x84D1;
- const GLenum TEXTURE18 = 0x84D2;
- const GLenum TEXTURE19 = 0x84D3;
- const GLenum TEXTURE20 = 0x84D4;
- const GLenum TEXTURE21 = 0x84D5;
- const GLenum TEXTURE22 = 0x84D6;
- const GLenum TEXTURE23 = 0x84D7;
- const GLenum TEXTURE24 = 0x84D8;
- const GLenum TEXTURE25 = 0x84D9;
- const GLenum TEXTURE26 = 0x84DA;
- const GLenum TEXTURE27 = 0x84DB;
- const GLenum TEXTURE28 = 0x84DC;
- const GLenum TEXTURE29 = 0x84DD;
- const GLenum TEXTURE30 = 0x84DE;
- const GLenum TEXTURE31 = 0x84DF;
- const GLenum ACTIVE_TEXTURE = 0x84E0;
-
- /* TextureWrapMode */
- const GLenum REPEAT = 0x2901;
- const GLenum CLAMP_TO_EDGE = 0x812F;
- const GLenum MIRRORED_REPEAT = 0x8370;
-
- /* Uniform Types */
- const GLenum FLOAT_VEC2 = 0x8B50;
- const GLenum FLOAT_VEC3 = 0x8B51;
- const GLenum FLOAT_VEC4 = 0x8B52;
- const GLenum INT_VEC2 = 0x8B53;
- const GLenum INT_VEC3 = 0x8B54;
- const GLenum INT_VEC4 = 0x8B55;
- const GLenum BOOL = 0x8B56;
- const GLenum BOOL_VEC2 = 0x8B57;
- const GLenum BOOL_VEC3 = 0x8B58;
- const GLenum BOOL_VEC4 = 0x8B59;
- const GLenum FLOAT_MAT2 = 0x8B5A;
- const GLenum FLOAT_MAT3 = 0x8B5B;
- const GLenum FLOAT_MAT4 = 0x8B5C;
- const GLenum SAMPLER_2D = 0x8B5E;
- const GLenum SAMPLER_CUBE = 0x8B60;
-
- /* Vertex Arrays */
- const GLenum VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
- const GLenum VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
- const GLenum VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
- const GLenum VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
- const GLenum VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
- const GLenum VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
- const GLenum VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
-
- /* Read Format */
- const GLenum IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A;
- const GLenum IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B;
-
- /* Shader Source */
- const GLenum COMPILE_STATUS = 0x8B81;
-
- /* Shader Precision-Specified Types */
- const GLenum LOW_FLOAT = 0x8DF0;
- const GLenum MEDIUM_FLOAT = 0x8DF1;
- const GLenum HIGH_FLOAT = 0x8DF2;
- const GLenum LOW_INT = 0x8DF3;
- const GLenum MEDIUM_INT = 0x8DF4;
- const GLenum HIGH_INT = 0x8DF5;
-
- /* Framebuffer Object. */
- const GLenum FRAMEBUFFER = 0x8D40;
- const GLenum RENDERBUFFER = 0x8D41;
-
- const GLenum RGBA4 = 0x8056;
- const GLenum RGB5_A1 = 0x8057;
- const GLenum RGB565 = 0x8D62;
- const GLenum DEPTH_COMPONENT16 = 0x81A5;
- const GLenum STENCIL_INDEX = 0x1901;
- const GLenum STENCIL_INDEX8 = 0x8D48;
- const GLenum DEPTH_STENCIL = 0x84F9;
-
- const GLenum RENDERBUFFER_WIDTH = 0x8D42;
- const GLenum RENDERBUFFER_HEIGHT = 0x8D43;
- const GLenum RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
- const GLenum RENDERBUFFER_RED_SIZE = 0x8D50;
- const GLenum RENDERBUFFER_GREEN_SIZE = 0x8D51;
- const GLenum RENDERBUFFER_BLUE_SIZE = 0x8D52;
- const GLenum RENDERBUFFER_ALPHA_SIZE = 0x8D53;
- const GLenum RENDERBUFFER_DEPTH_SIZE = 0x8D54;
- const GLenum RENDERBUFFER_STENCIL_SIZE = 0x8D55;
-
- const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
- const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
- const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
- const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
-
- const GLenum COLOR_ATTACHMENT0 = 0x8CE0;
- const GLenum DEPTH_ATTACHMENT = 0x8D00;
- const GLenum STENCIL_ATTACHMENT = 0x8D20;
- const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A;
-
- const GLenum NONE = 0;
-
- const GLenum FRAMEBUFFER_COMPLETE = 0x8CD5;
- const GLenum FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
- const GLenum FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
- const GLenum FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
- const GLenum FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
-
- const GLenum FRAMEBUFFER_BINDING = 0x8CA6;
- const GLenum RENDERBUFFER_BINDING = 0x8CA7;
- const GLenum MAX_RENDERBUFFER_SIZE = 0x84E8;
-
- const GLenum INVALID_FRAMEBUFFER_OPERATION = 0x0506;
-
- /* WebGL-specific enums */
- const GLenum UNPACK_FLIP_Y_WEBGL = 0x9240;
- const GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
- const GLenum CONTEXT_LOST_WEBGL = 0x9242;
- const GLenum UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
- const GLenum BROWSER_DEFAULT_WEBGL = 0x9244;
-
- readonly attribute GLsizei drawingBufferWidth;
- readonly attribute GLsizei drawingBufferHeight;
-
- [StrictTypeChecking, RaisesException] void activeTexture(GLenum texture);
- [StrictTypeChecking, RaisesException] void attachShader(WebGLProgram program, WebGLShader shader);
- [StrictTypeChecking, RaisesException] void bindAttribLocation(WebGLProgram program, GLuint index, DOMString name);
- [StrictTypeChecking, RaisesException] void bindBuffer(GLenum target, WebGLBuffer buffer);
- [StrictTypeChecking, RaisesException] void bindFramebuffer(GLenum target, WebGLFramebuffer framebuffer);
- [StrictTypeChecking, RaisesException] void bindRenderbuffer(GLenum target, WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking, RaisesException] void bindTexture(GLenum target, WebGLTexture texture);
- [StrictTypeChecking] void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
- [StrictTypeChecking] void blendEquation(GLenum mode);
- [StrictTypeChecking] void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
- [StrictTypeChecking] void blendFunc(GLenum sfactor, GLenum dfactor);
- [StrictTypeChecking] void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
- [StrictTypeChecking, RaisesException] void bufferData(GLenum target, ArrayBuffer? data, GLenum usage);
- [StrictTypeChecking, RaisesException] void bufferData(GLenum target, ArrayBufferView? data, GLenum usage);
- [StrictTypeChecking, RaisesException] void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
- [StrictTypeChecking, RaisesException] void bufferSubData(GLenum target, GLintptr offset, ArrayBuffer? data);
- [StrictTypeChecking, RaisesException] void bufferSubData(GLenum target, GLintptr offset, ArrayBufferView? data);
-
- [StrictTypeChecking] GLenum checkFramebufferStatus(GLenum target);
- [StrictTypeChecking] void clear(GLbitfield mask);
- [StrictTypeChecking] void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
- [StrictTypeChecking] void clearDepth(GLclampf depth);
- [StrictTypeChecking] void clearStencil(GLint s);
- [StrictTypeChecking] void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
- [StrictTypeChecking, RaisesException] void compileShader(WebGLShader shader);
-
- [StrictTypeChecking] void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
- GLsizei width, GLsizei height, GLint border, ArrayBufferView data);
- [StrictTypeChecking] void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height, GLenum format, ArrayBufferView data);
-
- [StrictTypeChecking] void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
- [StrictTypeChecking] void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
-
- [StrictTypeChecking] WebGLBuffer createBuffer();
- [StrictTypeChecking] WebGLFramebuffer createFramebuffer();
- [StrictTypeChecking] WebGLProgram createProgram();
- [StrictTypeChecking] WebGLRenderbuffer createRenderbuffer();
- [StrictTypeChecking, RaisesException] WebGLShader createShader(GLenum type);
- [StrictTypeChecking] WebGLTexture createTexture();
-
- [StrictTypeChecking] void cullFace(GLenum mode);
-
- [StrictTypeChecking] void deleteBuffer(WebGLBuffer buffer);
- [StrictTypeChecking] void deleteFramebuffer(WebGLFramebuffer framebuffer);
- [StrictTypeChecking] void deleteProgram(WebGLProgram program);
- [StrictTypeChecking] void deleteRenderbuffer(WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking] void deleteShader(WebGLShader shader);
- [StrictTypeChecking] void deleteTexture(WebGLTexture texture);
-
- [StrictTypeChecking] void depthFunc(GLenum func);
- [StrictTypeChecking] void depthMask(GLboolean flag);
- [StrictTypeChecking] void depthRange(GLclampf zNear, GLclampf zFar);
- [StrictTypeChecking, RaisesException] void detachShader(WebGLProgram program, WebGLShader shader);
- [StrictTypeChecking] void disable(GLenum cap);
- [StrictTypeChecking, RaisesException] void disableVertexAttribArray(GLuint index);
- [StrictTypeChecking, RaisesException] void drawArrays(GLenum mode, GLint first, GLsizei count);
- [StrictTypeChecking, RaisesException] void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset);
-
- [StrictTypeChecking] void enable(GLenum cap);
- [StrictTypeChecking, RaisesException] void enableVertexAttribArray(GLuint index);
- [StrictTypeChecking] void finish();
- [StrictTypeChecking] void flush();
- [StrictTypeChecking, RaisesException] void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking, RaisesException] void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture texture, GLint level);
- [StrictTypeChecking] void frontFace(GLenum mode);
- [StrictTypeChecking] void generateMipmap(GLenum target);
-
- [StrictTypeChecking, RaisesException] WebGLActiveInfo getActiveAttrib(WebGLProgram program, GLuint index);
- [StrictTypeChecking, RaisesException] WebGLActiveInfo getActiveUniform(WebGLProgram program, GLuint index);
-
- [StrictTypeChecking, Custom, RaisesException] void getAttachedShaders(WebGLProgram program);
-
- [StrictTypeChecking] GLint getAttribLocation(WebGLProgram program, DOMString name);
-
- [StrictTypeChecking, Custom] any getBufferParameter(GLenum target, GLenum pname);
-
- [StrictTypeChecking] WebGLContextAttributes getContextAttributes();
-
- [StrictTypeChecking] GLenum getError();
-
- // object getExtension(DOMString name);
- [StrictTypeChecking, Custom] any getExtension(DOMString name);
-
- [StrictTypeChecking, Custom, RaisesException] any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
- [StrictTypeChecking, Custom, RaisesException] any getParameter(GLenum pname);
- [StrictTypeChecking, Custom, RaisesException] any getProgramParameter(WebGLProgram program, GLenum pname);
- [StrictTypeChecking, TreatReturnedNullStringAs=Null, RaisesException] DOMString getProgramInfoLog(WebGLProgram program);
- [StrictTypeChecking, Custom, RaisesException] any getRenderbufferParameter(GLenum target, GLenum pname);
- [StrictTypeChecking, Custom, RaisesException] any getShaderParameter(WebGLShader shader, GLenum pname);
-
- [StrictTypeChecking, TreatReturnedNullStringAs=Null, RaisesException] DOMString getShaderInfoLog(WebGLShader shader);
-
- [StrictTypeChecking, RaisesException] WebGLShaderPrecisionFormat getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
-
- [StrictTypeChecking, TreatReturnedNullStringAs=Null, RaisesException] DOMString getShaderSource(WebGLShader shader);
-
- [StrictTypeChecking, Custom] sequence<DOMString> getSupportedExtensions();
-
- [StrictTypeChecking, Custom, RaisesException] any getTexParameter(GLenum target, GLenum pname);
-
- [StrictTypeChecking, Custom, RaisesException] any getUniform(WebGLProgram program, WebGLUniformLocation location);
-
- [StrictTypeChecking, RaisesException] WebGLUniformLocation getUniformLocation(WebGLProgram program, DOMString name);
-
- [StrictTypeChecking, Custom, RaisesException] any getVertexAttrib(GLuint index, GLenum pname);
-
- [StrictTypeChecking] GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname);
-
- [StrictTypeChecking] void hint(GLenum target, GLenum mode);
- [StrictTypeChecking] GLboolean isBuffer(WebGLBuffer buffer);
- [StrictTypeChecking] GLboolean isContextLost();
- [StrictTypeChecking] GLboolean isEnabled(GLenum cap);
- [StrictTypeChecking] GLboolean isFramebuffer(WebGLFramebuffer framebuffer);
- [StrictTypeChecking] GLboolean isProgram(WebGLProgram program);
- [StrictTypeChecking] GLboolean isRenderbuffer(WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking] GLboolean isShader(WebGLShader shader);
- [StrictTypeChecking] GLboolean isTexture(WebGLTexture texture);
- [StrictTypeChecking] void lineWidth(GLfloat width);
- [StrictTypeChecking, RaisesException] void linkProgram(WebGLProgram program);
- [StrictTypeChecking] void pixelStorei(GLenum pname, GLint param);
- [StrictTypeChecking] void polygonOffset(GLfloat factor, GLfloat units);
-
- [StrictTypeChecking, RaisesException] void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView pixels);
-
- [StrictTypeChecking] void releaseShaderCompiler();
- [StrictTypeChecking] void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
- [StrictTypeChecking] void sampleCoverage(GLclampf value, GLboolean invert);
- [StrictTypeChecking] void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
- [StrictTypeChecking, RaisesException] void shaderSource(WebGLShader shader, DOMString string);
- [StrictTypeChecking] void stencilFunc(GLenum func, GLint ref, GLuint mask);
- [StrictTypeChecking] void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
- [StrictTypeChecking] void stencilMask(GLuint mask);
- [StrictTypeChecking] void stencilMaskSeparate(GLenum face, GLuint mask);
- [StrictTypeChecking] void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
- [StrictTypeChecking] void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
-
- [StrictTypeChecking] void texParameterf(GLenum target, GLenum pname, GLfloat param);
- [StrictTypeChecking] void texParameteri(GLenum target, GLenum pname, GLint param);
-
- // Supported forms:
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
- GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, ImageData? pixels);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, HTMLImageElement? image);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, HTMLCanvasElement? canvas);
-#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, HTMLVideoElement? video);
-#endif
-
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type, ArrayBufferView? pixels);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, ImageData? pixels);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, HTMLImageElement? image);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, HTMLCanvasElement? canvas);
-#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, HTMLVideoElement? video);
-#endif
-
- [StrictTypeChecking, RaisesException] void uniform1f(WebGLUniformLocation location, GLfloat x);
- [StrictTypeChecking, Custom, RaisesException] void uniform1fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking, RaisesException] void uniform1i(WebGLUniformLocation location, GLint x);
- [StrictTypeChecking, Custom, RaisesException] void uniform1iv(WebGLUniformLocation location, Int32Array v);
- [StrictTypeChecking, RaisesException] void uniform2f(WebGLUniformLocation location, GLfloat x, GLfloat y);
- [StrictTypeChecking, Custom, RaisesException] void uniform2fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking, RaisesException] void uniform2i(WebGLUniformLocation location, GLint x, GLint y);
- [StrictTypeChecking, Custom, RaisesException] void uniform2iv(WebGLUniformLocation location, Int32Array v);
- [StrictTypeChecking, RaisesException] void uniform3f(WebGLUniformLocation location, GLfloat x, GLfloat y, GLfloat z);
- [StrictTypeChecking, Custom, RaisesException] void uniform3fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking, RaisesException] void uniform3i(WebGLUniformLocation location, GLint x, GLint y, GLint z);
- [StrictTypeChecking, Custom, RaisesException] void uniform3iv(WebGLUniformLocation location, Int32Array v);
- [StrictTypeChecking, RaisesException] void uniform4f(WebGLUniformLocation location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- [StrictTypeChecking, Custom, RaisesException] void uniform4fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking, RaisesException] void uniform4i(WebGLUniformLocation location, GLint x, GLint y, GLint z, GLint w);
- [StrictTypeChecking, Custom, RaisesException] void uniform4iv(WebGLUniformLocation location, Int32Array v);
-
- [StrictTypeChecking, Custom, RaisesException] void uniformMatrix2fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
- [StrictTypeChecking, Custom, RaisesException] void uniformMatrix3fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
- [StrictTypeChecking, Custom, RaisesException] void uniformMatrix4fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
-
- [StrictTypeChecking, RaisesException] void useProgram(WebGLProgram program);
- [StrictTypeChecking, RaisesException] void validateProgram(WebGLProgram program);
-
- [StrictTypeChecking] void vertexAttrib1f(GLuint indx, GLfloat x);
- [StrictTypeChecking, Custom] void vertexAttrib1fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
- [StrictTypeChecking, Custom] void vertexAttrib2fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
- [StrictTypeChecking, Custom] void vertexAttrib3fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- [StrictTypeChecking, Custom] void vertexAttrib4fv(GLuint indx, Float32Array values);
- [StrictTypeChecking, RaisesException] void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized,
- GLsizei stride, GLintptr offset);
-
- [StrictTypeChecking] void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
-};
diff --git a/Source/WebCore/html/canvas/WebGLSampler.cpp b/Source/WebCore/html/canvas/WebGLSampler.cpp
deleted file mode 100644
index 769fd4e24..000000000
--- a/Source/WebCore/html/canvas/WebGLSampler.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL)
-#include "WebGLSampler.h"
-
-#include "WebGLContextGroup.h"
-#include "WebGLRenderingContextBase.h"
-
-namespace WebCore {
-
-Ref<WebGLSampler> WebGLSampler::create(WebGLRenderingContextBase* ctx)
-{
- return adoptRef(*new WebGLSampler(ctx));
-}
-
-WebGLSampler::~WebGLSampler()
-{
- deleteObject(0);
-}
-
-WebGLSampler::WebGLSampler(WebGLRenderingContextBase* ctx)
- : WebGLSharedObject(ctx)
-{
- // FIXME: Call createSampler from GraphicsContext3D.
-}
-
-void WebGLSampler::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
-{
- UNUSED_PARAM(context3d);
- UNUSED_PARAM(object);
- // FIXME: Call deleteSampler from GraphicsContext3D.
-}
-
-}
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLSampler.h b/Source/WebCore/html/canvas/WebGLSampler.h
deleted file mode 100644
index c2719b21e..000000000
--- a/Source/WebCore/html/canvas/WebGLSampler.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebGLSampler_h
-#define WebGLSampler_h
-
-#include "WebGLSharedObject.h"
-
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class WebGLSampler final : public WebGLSharedObject {
-public:
- virtual ~WebGLSampler();
-
- static Ref<WebGLSampler> create(WebGLRenderingContextBase*);
-
-protected:
- WebGLSampler(WebGLRenderingContextBase*);
-
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
-
-private:
- virtual bool isSampler() const override { return true; }
-};
-
-} // namespace WebCore
-
-#endif // WebGLSampler_h
diff --git a/Source/WebCore/html/canvas/WebGLSampler.idl b/Source/WebCore/html/canvas/WebGLSampler.idl
deleted file mode 100644
index 4e544ca6e..000000000
--- a/Source/WebCore/html/canvas/WebGLSampler.idl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- Conditional=WEBGL
-] interface WebGLSampler {
-};
diff --git a/Source/WebCore/html/canvas/WebGLShader.cpp b/Source/WebCore/html/canvas/WebGLShader.cpp
index dc73d422a..0f3315676 100644
--- a/Source/WebCore/html/canvas/WebGLShader.cpp
+++ b/Source/WebCore/html/canvas/WebGLShader.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,16 +30,16 @@
#include "WebGLShader.h"
#include "WebGLContextGroup.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-Ref<WebGLShader> WebGLShader::create(WebGLRenderingContextBase* ctx, GC3Denum type)
+PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContext* ctx, GC3Denum type)
{
- return adoptRef(*new WebGLShader(ctx, type));
+ return adoptRef(new WebGLShader(ctx, type));
}
-WebGLShader::WebGLShader(WebGLRenderingContextBase* ctx, GC3Denum type)
+WebGLShader::WebGLShader(WebGLRenderingContext* ctx, GC3Denum type)
: WebGLSharedObject(ctx)
, m_type(type)
, m_source("")
diff --git a/Source/WebCore/html/canvas/WebGLShader.h b/Source/WebCore/html/canvas/WebGLShader.h
index 4931226a6..7ed00e321 100644
--- a/Source/WebCore/html/canvas/WebGLShader.h
+++ b/Source/WebCore/html/canvas/WebGLShader.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,13 +28,15 @@
#include "WebGLSharedObject.h"
+#include <wtf/PassRefPtr.h>
+
namespace WebCore {
-class WebGLShader final : public WebGLSharedObject {
+class WebGLShader : public WebGLSharedObject {
public:
virtual ~WebGLShader();
- static Ref<WebGLShader> create(WebGLRenderingContextBase*, GC3Denum);
+ static PassRefPtr<WebGLShader> create(WebGLRenderingContext*, GC3Denum);
GC3Denum getType() const { return m_type; }
const String& getSource() const { return m_source; }
@@ -45,7 +47,7 @@ public:
void setValid(bool valid) { m_isValid = valid; }
private:
- WebGLShader(WebGLRenderingContextBase*, GC3Denum);
+ WebGLShader(WebGLRenderingContext*, GC3Denum);
virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
diff --git a/Source/WebCore/html/canvas/WebGLShader.idl b/Source/WebCore/html/canvas/WebGLShader.idl
index 52f962025..0ebae3829 100644
--- a/Source/WebCore/html/canvas/WebGLShader.idl
+++ b/Source/WebCore/html/canvas/WebGLShader.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.cpp b/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.cpp
index ed63a51cf..b9c5163a1 100644
--- a/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.cpp
+++ b/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.cpp
@@ -33,9 +33,9 @@
namespace WebCore {
// static
-Ref<WebGLShaderPrecisionFormat> WebGLShaderPrecisionFormat::create(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision)
+PassRefPtr<WebGLShaderPrecisionFormat> WebGLShaderPrecisionFormat::create(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision)
{
- return adoptRef(*new WebGLShaderPrecisionFormat(rangeMin, rangeMax, precision));
+ return adoptRef(new WebGLShaderPrecisionFormat(rangeMin, rangeMax, precision));
}
GC3Dint WebGLShaderPrecisionFormat::rangeMin() const
diff --git a/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.h b/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.h
index 37027f0a6..c4c7b7861 100644
--- a/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.h
+++ b/Source/WebCore/html/canvas/WebGLShaderPrecisionFormat.h
@@ -28,13 +28,14 @@
#define WebGLShaderPrecisionFormat_h
#include "GraphicsContext3D.h"
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
class WebGLShaderPrecisionFormat : public RefCounted<WebGLShaderPrecisionFormat> {
public:
- static Ref<WebGLShaderPrecisionFormat> create(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision);
+ static PassRefPtr<WebGLShaderPrecisionFormat> create(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision);
GC3Dint rangeMin() const;
GC3Dint rangeMax() const;
diff --git a/Source/WebCore/html/canvas/WebGLSharedObject.cpp b/Source/WebCore/html/canvas/WebGLSharedObject.cpp
index 34f7ceea5..9f76cae77 100644
--- a/Source/WebCore/html/canvas/WebGLSharedObject.cpp
+++ b/Source/WebCore/html/canvas/WebGLSharedObject.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,11 +30,11 @@
#include "WebGLSharedObject.h"
#include "WebGLContextGroup.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-WebGLSharedObject::WebGLSharedObject(WebGLRenderingContextBase* context)
+WebGLSharedObject::WebGLSharedObject(WebGLRenderingContext* context)
: WebGLObject(context),
m_contextGroup(context->contextGroup())
{
diff --git a/Source/WebCore/html/canvas/WebGLSharedObject.h b/Source/WebCore/html/canvas/WebGLSharedObject.h
index 80e56289e..a55f64871 100644
--- a/Source/WebCore/html/canvas/WebGLSharedObject.h
+++ b/Source/WebCore/html/canvas/WebGLSharedObject.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -32,7 +32,7 @@ namespace WebCore {
class GraphicsContext3D;
class WebGLContextGroup;
-class WebGLRenderingContextBase;
+class WebGLRenderingContext;
// WebGLSharedObject the base class for objects that can be shared by multiple
// WebGLRenderingContexts.
@@ -43,17 +43,13 @@ public:
WebGLContextGroup* contextGroup() const { return m_contextGroup; }
virtual bool isBuffer() const { return false; }
+ virtual bool isFramebuffer() const { return false; }
virtual bool isProgram() const { return false; }
- virtual bool isQuery() const { return false; }
virtual bool isRenderbuffer() const { return false; }
- virtual bool isSampler() const { return false; }
virtual bool isShader() const { return false; }
- virtual bool isSync() const { return false; }
virtual bool isTexture() const { return false; }
- virtual bool isTransformFeedback() const { return false; }
- virtual bool isVertexArrayObject() const { return false; }
- virtual bool validate(const WebGLContextGroup* contextGroup, const WebGLRenderingContextBase*) const override
+ virtual bool validate(const WebGLContextGroup* contextGroup, const WebGLRenderingContext*) const override
{
return contextGroup == m_contextGroup;
}
@@ -61,7 +57,7 @@ public:
void detachContextGroup();
protected:
- WebGLSharedObject(WebGLRenderingContextBase*);
+ WebGLSharedObject(WebGLRenderingContext*);
virtual bool hasGroupOrContext() const override
{
diff --git a/Source/WebCore/html/canvas/WebGLSync.cpp b/Source/WebCore/html/canvas/WebGLSync.cpp
deleted file mode 100644
index 2bd2ce82a..000000000
--- a/Source/WebCore/html/canvas/WebGLSync.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL)
-#include "WebGLSync.h"
-
-#include "WebGLContextGroup.h"
-#include "WebGLRenderingContextBase.h"
-
-namespace WebCore {
-
-Ref<WebGLSync> WebGLSync::create(WebGLRenderingContextBase* ctx)
-{
- return adoptRef(*new WebGLSync(ctx));
-}
-
-WebGLSync::~WebGLSync()
-{
- deleteObject(0);
-}
-
-WebGLSync::WebGLSync(WebGLRenderingContextBase* ctx)
- : WebGLSharedObject(ctx)
-{
- // FIXME: Call fenceSync from GraphicsContext3D.
-}
-
-void WebGLSync::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
-{
- UNUSED_PARAM(context3d);
- UNUSED_PARAM(object);
- // FIXME: Call deleteSync from GraphicsContext3D.
-}
-
-}
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLSync.h b/Source/WebCore/html/canvas/WebGLSync.h
deleted file mode 100644
index 9d8419c9a..000000000
--- a/Source/WebCore/html/canvas/WebGLSync.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebGLSync_h
-#define WebGLSync_h
-
-#include "WebGLSharedObject.h"
-
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class WebGLSync final : public WebGLSharedObject {
-public:
- virtual ~WebGLSync();
-
- static Ref<WebGLSync> create(WebGLRenderingContextBase*);
-
-protected:
- WebGLSync(WebGLRenderingContextBase*);
-
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
-
-private:
- virtual bool isSync() const override { return true; }
-};
-
-} // namespace WebCore
-
-#endif // WebGLSync_h
diff --git a/Source/WebCore/html/canvas/WebGLTexture.cpp b/Source/WebCore/html/canvas/WebGLTexture.cpp
index bdfceaa85..0872795ff 100644
--- a/Source/WebCore/html/canvas/WebGLTexture.cpp
+++ b/Source/WebCore/html/canvas/WebGLTexture.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -31,16 +31,16 @@
#include "WebGLContextGroup.h"
#include "WebGLFramebuffer.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-Ref<WebGLTexture> WebGLTexture::create(WebGLRenderingContextBase* ctx)
+PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContext* ctx)
{
- return adoptRef(*new WebGLTexture(ctx));
+ return adoptRef(new WebGLTexture(ctx));
}
-WebGLTexture::WebGLTexture(WebGLRenderingContextBase* ctx)
+WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
: WebGLSharedObject(ctx)
, m_target(0)
, m_minFilter(GraphicsContext3D::NEAREST_MIPMAP_LINEAR)
@@ -218,15 +218,6 @@ bool WebGLTexture::isValid(GC3Denum target, GC3Dint level) const
return info->valid;
}
-void WebGLTexture::markInvalid(GC3Denum target, GC3Dint level)
-{
- int index = mapTargetToIndex(target);
- if (index < 0)
- return;
- m_info[index][level].valid = false;
- update();
-}
-
bool WebGLTexture::isNPOT(GC3Dsizei width, GC3Dsizei height)
{
ASSERT(width >= 0 && height >= 0);
diff --git a/Source/WebCore/html/canvas/WebGLTexture.h b/Source/WebCore/html/canvas/WebGLTexture.h
index 133622d52..dcc3d0b45 100644
--- a/Source/WebCore/html/canvas/WebGLTexture.h
+++ b/Source/WebCore/html/canvas/WebGLTexture.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,11 +28,12 @@
#include "WebGLSharedObject.h"
+#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
-class WebGLTexture final : public WebGLSharedObject {
+class WebGLTexture : public WebGLSharedObject {
public:
enum TextureExtensionFlag {
@@ -43,7 +44,7 @@ public:
virtual ~WebGLTexture();
- static Ref<WebGLTexture> create(WebGLRenderingContextBase*);
+ static PassRefPtr<WebGLTexture> create(WebGLRenderingContext*);
void setTarget(GC3Denum target, GC3Dint maxLevel);
void setParameteri(GC3Denum pname, GC3Dint param);
@@ -64,7 +65,6 @@ public:
GC3Dsizei getWidth(GC3Denum target, GC3Dint level) const;
GC3Dsizei getHeight(GC3Denum target, GC3Dint level) const;
bool isValid(GC3Denum target, GC3Dint level) const;
- void markInvalid(GC3Denum target, GC3Dint level);
// Whether width/height is NotPowerOfTwo.
static bool isNPOT(GC3Dsizei, GC3Dsizei);
@@ -80,11 +80,12 @@ public:
static GC3Dint computeLevelCount(GC3Dsizei width, GC3Dsizei height);
-private:
- WebGLTexture(WebGLRenderingContextBase*);
+protected:
+ WebGLTexture(WebGLRenderingContext*);
virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
+private:
class LevelInfo {
public:
LevelInfo()
diff --git a/Source/WebCore/html/canvas/WebGLTexture.idl b/Source/WebCore/html/canvas/WebGLTexture.idl
index 67dfa3c4f..1ea2f2bca 100644
--- a/Source/WebCore/html/canvas/WebGLTexture.idl
+++ b/Source/WebCore/html/canvas/WebGLTexture.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/canvas/WebGLTransformFeedback.cpp b/Source/WebCore/html/canvas/WebGLTransformFeedback.cpp
deleted file mode 100644
index f365d523f..000000000
--- a/Source/WebCore/html/canvas/WebGLTransformFeedback.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL)
-#include "WebGLTransformFeedback.h"
-
-#include "WebGLContextGroup.h"
-#include "WebGLRenderingContextBase.h"
-
-namespace WebCore {
-
-Ref<WebGLTransformFeedback> WebGLTransformFeedback::create(WebGLRenderingContextBase* ctx)
-{
- return adoptRef(*new WebGLTransformFeedback(ctx));
-}
-
-WebGLTransformFeedback::~WebGLTransformFeedback()
-{
- deleteObject(0);
-}
-
-WebGLTransformFeedback::WebGLTransformFeedback(WebGLRenderingContextBase* ctx)
- : WebGLSharedObject(ctx)
-{
- // FIXME: Call createTransformFeedback from GraphicsContext3D.
-}
-
-void WebGLTransformFeedback::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
-{
- UNUSED_PARAM(context3d);
- UNUSED_PARAM(object);
- // FIXME: Call deleteTransformFeedback from GraphicsContext3D.
-}
-
-}
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLTransformFeedback.h b/Source/WebCore/html/canvas/WebGLTransformFeedback.h
deleted file mode 100644
index d29bb364f..000000000
--- a/Source/WebCore/html/canvas/WebGLTransformFeedback.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebGLTransformFeedback_h
-#define WebGLTransformFeedback_h
-
-#include "WebGLSharedObject.h"
-
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class WebGLTransformFeedback final : public WebGLSharedObject {
-public:
- virtual ~WebGLTransformFeedback();
-
- static Ref<WebGLTransformFeedback> create(WebGLRenderingContextBase*);
-
-protected:
- WebGLTransformFeedback(WebGLRenderingContextBase*);
-
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
-
-private:
- virtual bool isTransformFeedback() const override { return true; }
-};
-
-} // namespace WebCore
-
-#endif // WebGLTransformFeedback_h
diff --git a/Source/WebCore/html/canvas/WebGLTransformFeedback.idl b/Source/WebCore/html/canvas/WebGLTransformFeedback.idl
deleted file mode 100644
index 22b8847ed..000000000
--- a/Source/WebCore/html/canvas/WebGLTransformFeedback.idl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- Conditional=WEBGL
-] interface WebGLTransformFeedback {
-};
diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.cpp b/Source/WebCore/html/canvas/WebGLUniformLocation.cpp
index f16cae3c1..b467238b4 100644
--- a/Source/WebCore/html/canvas/WebGLUniformLocation.cpp
+++ b/Source/WebCore/html/canvas/WebGLUniformLocation.cpp
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -32,9 +32,9 @@
namespace WebCore {
-Ref<WebGLUniformLocation> WebGLUniformLocation::create(WebGLProgram* program, GC3Dint location, GC3Denum type)
+PassRefPtr<WebGLUniformLocation> WebGLUniformLocation::create(WebGLProgram* program, GC3Dint location, GC3Denum type)
{
- return adoptRef(*new WebGLUniformLocation(program, location, type));
+ return adoptRef(new WebGLUniformLocation(program, location, type));
}
WebGLUniformLocation::WebGLUniformLocation(WebGLProgram* program, GC3Dint location, GC3Denum type)
diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.h b/Source/WebCore/html/canvas/WebGLUniformLocation.h
index bfe0f8fbe..a268fa2fa 100644
--- a/Source/WebCore/html/canvas/WebGLUniformLocation.h
+++ b/Source/WebCore/html/canvas/WebGLUniformLocation.h
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -29,15 +29,16 @@
#include "WebGLProgram.h"
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
-class WebGLUniformLocation final : public RefCounted<WebGLUniformLocation> {
+class WebGLUniformLocation : public RefCounted<WebGLUniformLocation> {
public:
- ~WebGLUniformLocation() { }
+ virtual ~WebGLUniformLocation() { }
- static Ref<WebGLUniformLocation> create(WebGLProgram*, GC3Dint location, GC3Denum type);
+ static PassRefPtr<WebGLUniformLocation> create(WebGLProgram*, GC3Dint location, GC3Denum type);
WebGLProgram* program() const;
diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.idl b/Source/WebCore/html/canvas/WebGLUniformLocation.idl
index a086f5713..c211189de 100644
--- a/Source/WebCore/html/canvas/WebGLUniformLocation.idl
+++ b/Source/WebCore/html/canvas/WebGLUniformLocation.idl
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -25,7 +25,6 @@
*/
[
- Conditional=WEBGL,
- ImplementationLacksVTable,
+ Conditional=WEBGL
] interface WebGLUniformLocation {
};
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObject.cpp b/Source/WebCore/html/canvas/WebGLVertexArrayObject.cpp
deleted file mode 100644
index 63356e033..000000000
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObject.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL) && ENABLE(WEBGL2)
-#include "WebGLVertexArrayObject.h"
-
-#include "WebGL2RenderingContext.h"
-#include "WebGLContextGroup.h"
-
-namespace WebCore {
-
-Ref<WebGLVertexArrayObject> WebGLVertexArrayObject::create(WebGLRenderingContextBase* ctx, VAOType type)
-{
- return adoptRef(*new WebGLVertexArrayObject(ctx, type));
-}
-
-WebGLVertexArrayObject::~WebGLVertexArrayObject()
-{
- deleteObject(0);
-}
-
-WebGLVertexArrayObject::WebGLVertexArrayObject(WebGLRenderingContextBase* ctx, VAOType type)
- : WebGLVertexArrayObjectBase(ctx, type)
-{
- switch (m_type) {
- case VAOTypeDefault:
- break;
- default:
- setObject(context()->graphicsContext3D()->createVertexArray());
- break;
- }
-}
-
-void WebGLVertexArrayObject::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
-{
- switch (m_type) {
- case VAOTypeDefault:
- break;
- default:
- context3d->deleteVertexArray(object);
- break;
- }
-
- if (m_boundElementArrayBuffer)
- m_boundElementArrayBuffer->onDetached(context3d);
-
- for (size_t i = 0; i < m_vertexAttribState.size(); ++i) {
- VertexAttribState& state = m_vertexAttribState[i];
- if (state.bufferBinding)
- state.bufferBinding->onDetached(context3d);
- }
-}
-
-}
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObject.h b/Source/WebCore/html/canvas/WebGLVertexArrayObject.h
deleted file mode 100644
index 45803daf0..000000000
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObject.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebGLVertexArrayObject_h
-#define WebGLVertexArrayObject_h
-
-#if ENABLE(WEBGL2)
-
-#include "WebGLBuffer.h"
-#include "WebGLContextObject.h"
-#include "WebGLVertexArrayObjectBase.h"
-
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class WebGL2RenderingContext;
-
-class WebGLVertexArrayObject final : public WebGLVertexArrayObjectBase {
-public:
- static Ref<WebGLVertexArrayObject> create(WebGLRenderingContextBase*, VAOType);
- virtual ~WebGLVertexArrayObject();
-private:
- WebGLVertexArrayObject(WebGLRenderingContextBase*, VAOType);
- bool isTransformFeedback() const { return true; }
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
-};
-
-} // namespace WebCore
-
-#endif // WEBGL2
-
-#endif // WebGLVertexArrayObject_h
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObject.idl b/Source/WebCore/html/canvas/WebGLVertexArrayObject.idl
deleted file mode 100644
index 0bab1c977..000000000
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObject.idl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- Conditional=WEBGL2
-] interface WebGLVertexArrayObject {
-};
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.cpp b/Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.cpp
deleted file mode 100644
index f39c0ddd2..000000000
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEBGL)
-#include "WebGLVertexArrayObjectBase.h"
-
-#include "WebGLRenderingContextBase.h"
-
-namespace WebCore {
-
-WebGLVertexArrayObjectBase::WebGLVertexArrayObjectBase(WebGLRenderingContextBase* ctx, VAOType type)
- : WebGLContextObject(ctx)
- , m_type(type)
- , m_hasEverBeenBound(false)
- , m_boundElementArrayBuffer(0)
-{
- m_vertexAttribState.resize(ctx->getMaxVertexAttribs());
-}
-
-void WebGLVertexArrayObjectBase::setElementArrayBuffer(PassRefPtr<WebGLBuffer> buffer)
-{
- if (buffer)
- buffer->onAttached();
- if (m_boundElementArrayBuffer)
- m_boundElementArrayBuffer->onDetached(context()->graphicsContext3D());
- m_boundElementArrayBuffer = buffer;
-
-}
-
-void WebGLVertexArrayObjectBase::setVertexAttribState(GC3Duint index, GC3Dsizei bytesPerElement, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset, PassRefPtr<WebGLBuffer> buffer)
-{
- GC3Dsizei validatedStride = stride ? stride : bytesPerElement;
-
- VertexAttribState& state = m_vertexAttribState[index];
-
- if (buffer)
- buffer->onAttached();
- if (state.bufferBinding)
- state.bufferBinding->onDetached(context()->graphicsContext3D());
-
- state.bufferBinding = buffer;
- state.bytesPerElement = bytesPerElement;
- state.size = size;
- state.type = type;
- state.normalized = normalized;
- state.stride = validatedStride;
- state.originalStride = stride;
- state.offset = offset;
-}
-
-void WebGLVertexArrayObjectBase::unbindBuffer(PassRefPtr<WebGLBuffer> buffer)
-{
- if (m_boundElementArrayBuffer == buffer) {
- m_boundElementArrayBuffer->onDetached(context()->graphicsContext3D());
- m_boundElementArrayBuffer = nullptr;
- }
-
- for (size_t i = 0; i < m_vertexAttribState.size(); ++i) {
- VertexAttribState& state = m_vertexAttribState[i];
- if (state.bufferBinding == buffer) {
- buffer->onDetached(context()->graphicsContext3D());
-
- if (!i && !context()->isGLES2Compliant()) {
- state.bufferBinding = context()->m_vertexAttrib0Buffer;
- state.bufferBinding->onAttached();
- state.bytesPerElement = 0;
- state.size = 4;
- state.type = GraphicsContext3D::FLOAT;
- state.normalized = false;
- state.stride = 16;
- state.originalStride = 0;
- state.offset = 0;
- } else
- state.bufferBinding = nullptr;
- }
- }
-}
-
-void WebGLVertexArrayObjectBase::setVertexAttribDivisor(GC3Duint index, GC3Duint divisor)
-{
- VertexAttribState& state = m_vertexAttribState[index];
- state.divisor = divisor;
-}
-
-}
-
-#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.h b/Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.h
deleted file mode 100644
index 403040919..000000000
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObjectBase.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebGLVertexArrayObjectBase_h
-#define WebGLVertexArrayObjectBase_h
-
-#include "WebGLBuffer.h"
-#include "WebGLContextObject.h"
-
-#include <wtf/PassRefPtr.h>
-
-namespace WebCore {
-
-class WebGLVertexArrayObjectBase : public WebGLContextObject {
-public:
- enum VAOType {
- VAOTypeDefault,
- VAOTypeUser,
- };
-
- virtual ~WebGLVertexArrayObjectBase() { }
-
- // Cached values for vertex attrib range checks
- struct VertexAttribState {
- VertexAttribState()
- : enabled(false)
- , bytesPerElement(0)
- , size(4)
- , type(GraphicsContext3D::FLOAT)
- , normalized(false)
- , stride(16)
- , originalStride(0)
- , offset(0)
- , divisor(0)
- {
- }
-
- bool isBound() const { return bufferBinding && bufferBinding->object(); }
- bool validateBinding() const { return !enabled || isBound(); }
-
- bool enabled;
- RefPtr<WebGLBuffer> bufferBinding;
- GC3Dsizei bytesPerElement;
- GC3Dint size;
- GC3Denum type;
- bool normalized;
- GC3Dsizei stride;
- GC3Dsizei originalStride;
- GC3Dintptr offset;
- GC3Duint divisor;
- };
-
- bool isDefaultObject() const { return m_type == VAOTypeDefault; }
-
- bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
- void setHasEverBeenBound() { m_hasEverBeenBound = true; }
-
- PassRefPtr<WebGLBuffer> getElementArrayBuffer() const { return m_boundElementArrayBuffer; }
- void setElementArrayBuffer(PassRefPtr<WebGLBuffer>);
-
- VertexAttribState& getVertexAttribState(int index) { return m_vertexAttribState[index]; }
- void setVertexAttribState(GC3Duint, GC3Dsizei, GC3Dint, GC3Denum, GC3Dboolean, GC3Dsizei, GC3Dintptr, PassRefPtr<WebGLBuffer>);
- void unbindBuffer(PassRefPtr<WebGLBuffer>);
-
- void setVertexAttribDivisor(GC3Duint index, GC3Duint divisor);
-
-protected:
- WebGLVertexArrayObjectBase(WebGLRenderingContextBase*, VAOType);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) = 0;
-
- VAOType m_type;
- bool m_hasEverBeenBound;
- RefPtr<WebGLBuffer> m_boundElementArrayBuffer;
- Vector<VertexAttribState> m_vertexAttribState;
-};
-
-} // namespace WebCore
-
-#endif // WebGLVertexArrayObjectBase_h
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp
index 5be2e4c89..ce18a9f18 100644
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,21 +30,26 @@
#include "WebGLVertexArrayObjectOES.h"
#include "Extensions3D.h"
-#include "WebGLRenderingContextBase.h"
+#include "WebGLRenderingContext.h"
namespace WebCore {
-Ref<WebGLVertexArrayObjectOES> WebGLVertexArrayObjectOES::create(WebGLRenderingContextBase* ctx, VAOType type)
+PassRefPtr<WebGLVertexArrayObjectOES> WebGLVertexArrayObjectOES::create(WebGLRenderingContext* ctx, VaoType type)
{
- return adoptRef(*new WebGLVertexArrayObjectOES(ctx, type));
+ return adoptRef(new WebGLVertexArrayObjectOES(ctx, type));
}
-WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContextBase* ctx, VAOType type)
- : WebGLVertexArrayObjectBase(ctx, type)
+WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContext* ctx, VaoType type)
+ : WebGLContextObject(ctx)
+ , m_type(type)
+ , m_hasEverBeenBound(false)
+ , m_boundElementArrayBuffer(0)
{
+ m_vertexAttribState.resize(ctx->getMaxVertexAttribs());
+
Extensions3D* extensions = context()->graphicsContext3D()->getExtensions();
switch (m_type) {
- case VAOTypeDefault:
+ case VaoTypeDefault:
break;
default:
setObject(extensions->createVertexArrayOES());
@@ -61,7 +66,7 @@ void WebGLVertexArrayObjectOES::deleteObjectImpl(GraphicsContext3D* context3d, P
{
Extensions3D* extensions = context3d->getExtensions();
switch (m_type) {
- case VAOTypeDefault:
+ case VaoTypeDefault:
break;
default:
extensions->deleteVertexArrayOES(object);
@@ -77,6 +82,73 @@ void WebGLVertexArrayObjectOES::deleteObjectImpl(GraphicsContext3D* context3d, P
state.bufferBinding->onDetached(context3d);
}
}
+
+void WebGLVertexArrayObjectOES::setElementArrayBuffer(PassRefPtr<WebGLBuffer> buffer)
+{
+ if (buffer)
+ buffer->onAttached();
+ if (m_boundElementArrayBuffer)
+ m_boundElementArrayBuffer->onDetached(context()->graphicsContext3D());
+ m_boundElementArrayBuffer = buffer;
+
+}
+
+void WebGLVertexArrayObjectOES::setVertexAttribState(
+ GC3Duint index, GC3Dsizei bytesPerElement, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset, PassRefPtr<WebGLBuffer> buffer)
+{
+ GC3Dsizei validatedStride = stride ? stride : bytesPerElement;
+
+ VertexAttribState& state = m_vertexAttribState[index];
+
+ if (buffer)
+ buffer->onAttached();
+ if (state.bufferBinding)
+ state.bufferBinding->onDetached(context()->graphicsContext3D());
+
+ state.bufferBinding = buffer;
+ state.bytesPerElement = bytesPerElement;
+ state.size = size;
+ state.type = type;
+ state.normalized = normalized;
+ state.stride = validatedStride;
+ state.originalStride = stride;
+ state.offset = offset;
+}
+
+void WebGLVertexArrayObjectOES::unbindBuffer(PassRefPtr<WebGLBuffer> buffer)
+{
+ if (m_boundElementArrayBuffer == buffer) {
+ m_boundElementArrayBuffer->onDetached(context()->graphicsContext3D());
+ m_boundElementArrayBuffer = 0;
+ }
+
+ for (size_t i = 0; i < m_vertexAttribState.size(); ++i) {
+ VertexAttribState& state = m_vertexAttribState[i];
+ if (state.bufferBinding == buffer) {
+ buffer->onDetached(context()->graphicsContext3D());
+
+ if (!i && !context()->isGLES2Compliant()) {
+ state.bufferBinding = context()->m_vertexAttrib0Buffer;
+ state.bufferBinding->onAttached();
+ state.bytesPerElement = 0;
+ state.size = 4;
+ state.type = GraphicsContext3D::FLOAT;
+ state.normalized = false;
+ state.stride = 16;
+ state.originalStride = 0;
+ state.offset = 0;
+ } else
+ state.bufferBinding = 0;
+ }
+ }
+}
+
+void WebGLVertexArrayObjectOES::setVertexAttribDivisor(GC3Duint index, GC3Duint divisor)
+{
+ VertexAttribState& state = m_vertexAttribState[index];
+ state.divisor = divisor;
+}
+
}
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h
index 3a4ef2811..8853ff926 100644
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,17 +28,77 @@
#include "WebGLBuffer.h"
#include "WebGLContextObject.h"
-#include "WebGLVertexArrayObjectBase.h"
+
+#include <wtf/PassRefPtr.h>
namespace WebCore {
-class WebGLVertexArrayObjectOES final : public WebGLVertexArrayObjectBase {
+class WebGLVertexArrayObjectOES : public WebGLContextObject {
public:
- static Ref<WebGLVertexArrayObjectOES> create(WebGLRenderingContextBase*, VAOType);
+ enum VaoType {
+ VaoTypeDefault,
+ VaoTypeUser,
+ };
+
virtual ~WebGLVertexArrayObjectOES();
+
+ static PassRefPtr<WebGLVertexArrayObjectOES> create(WebGLRenderingContext*, VaoType);
+
+ // Cached values for vertex attrib range checks
+ struct VertexAttribState {
+ VertexAttribState()
+ : enabled(false)
+ , bytesPerElement(0)
+ , size(4)
+ , type(GraphicsContext3D::FLOAT)
+ , normalized(false)
+ , stride(16)
+ , originalStride(0)
+ , offset(0)
+ , divisor(0)
+ {
+ }
+
+ bool isBound() const { return bufferBinding && bufferBinding->object(); }
+ bool validateBinding() const { return !enabled || isBound(); }
+
+ bool enabled;
+ RefPtr<WebGLBuffer> bufferBinding;
+ GC3Dsizei bytesPerElement;
+ GC3Dint size;
+ GC3Denum type;
+ bool normalized;
+ GC3Dsizei stride;
+ GC3Dsizei originalStride;
+ GC3Dintptr offset;
+ GC3Duint divisor;
+ };
+
+ bool isDefaultObject() const { return m_type == VaoTypeDefault; }
+
+ bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
+ void setHasEverBeenBound() { m_hasEverBeenBound = true; }
+
+ PassRefPtr<WebGLBuffer> getElementArrayBuffer() const { return m_boundElementArrayBuffer; }
+ void setElementArrayBuffer(PassRefPtr<WebGLBuffer>);
+
+ VertexAttribState& getVertexAttribState(int index) { return m_vertexAttribState[index]; }
+ void setVertexAttribState(GC3Duint, GC3Dsizei, GC3Dint, GC3Denum, GC3Dboolean, GC3Dsizei, GC3Dintptr, PassRefPtr<WebGLBuffer>);
+ void unbindBuffer(PassRefPtr<WebGLBuffer>);
+
+ void setVertexAttribDivisor(GC3Duint index, GC3Duint divisor);
+
private:
- WebGLVertexArrayObjectOES(WebGLRenderingContextBase*, VAOType);
+ WebGLVertexArrayObjectOES(WebGLRenderingContext*, VaoType);
+
virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) override;
+
+ virtual bool isVertexArray() const { return true; }
+
+ VaoType m_type;
+ bool m_hasEverBeenBound;
+ RefPtr<WebGLBuffer> m_boundElementArrayBuffer;
+ Vector<VertexAttribState> m_vertexAttribState;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl
index f190a7e64..ce9f18d5f 100644
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/forms/FileIconLoader.cpp b/Source/WebCore/html/forms/FileIconLoader.cpp
index 9bcd47f77..a086d406b 100644
--- a/Source/WebCore/html/forms/FileIconLoader.cpp
+++ b/Source/WebCore/html/forms/FileIconLoader.cpp
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
diff --git a/Source/WebCore/html/forms/FileIconLoader.h b/Source/WebCore/html/forms/FileIconLoader.h
index 1fb4c2dd6..b6a3aa6b2 100644
--- a/Source/WebCore/html/forms/FileIconLoader.h
+++ b/Source/WebCore/html/forms/FileIconLoader.h
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -50,7 +50,7 @@ public:
explicit FileIconLoader(FileIconLoaderClient&);
void invalidate();
- WEBCORE_EXPORT void notifyFinished(PassRefPtr<Icon>);
+ void notifyFinished(PassRefPtr<Icon>);
private:
FileIconLoaderClient* m_client;
diff --git a/Source/WebCore/html/parser/AtomicHTMLToken.h b/Source/WebCore/html/parser/AtomicHTMLToken.h
index cc5a21555..909487c54 100644
--- a/Source/WebCore/html/parser/AtomicHTMLToken.h
+++ b/Source/WebCore/html/parser/AtomicHTMLToken.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2013 Google, Inc. All Rights Reserved.
- * Copyright (C) 2015 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,219 +26,216 @@
#ifndef AtomicHTMLToken_h
#define AtomicHTMLToken_h
+#include "Attribute.h"
#include "HTMLToken.h"
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
namespace WebCore {
class AtomicHTMLToken {
+ WTF_MAKE_NONCOPYABLE(AtomicHTMLToken);
public:
- explicit AtomicHTMLToken(HTMLToken&);
- AtomicHTMLToken(HTMLToken::Type, const AtomicString& name, Vector<Attribute>&& = Vector<Attribute>()); // Only StartTag or EndTag.
- HTMLToken::Type type() const;
-
- // StartTag, EndTag, DOCTYPE.
-
- void setName(const AtomicString&);
-
- const AtomicString& name() const;
-
- // DOCTYPE.
-
- bool forceQuirks() const;
- String publicIdentifier() const;
- String systemIdentifier() const;
-
- // StartTag, EndTag.
-
- Vector<Attribute>& attributes();
-
- bool selfClosing() const;
- const Vector<Attribute>& attributes() const;
+ bool forceQuirks() const
+ {
+ ASSERT(m_type == HTMLToken::DOCTYPE);
+ return m_doctypeData->m_forceQuirks;
+ }
- // Characters
+ HTMLToken::Type type() const { return m_type; }
- const UChar* characters() const;
- unsigned charactersLength() const;
- bool charactersIsAll8BitData() const;
+ const AtomicString& name() const
+ {
+ ASSERT(usesName());
+ return m_name;
+ }
- // Comment
+ void setName(const AtomicString& name)
+ {
+ ASSERT(usesName());
+ m_name = name;
+ }
- const String& comment() const;
+ bool selfClosing() const
+ {
+ ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
+ return m_selfClosing;
+ }
-private:
- HTMLToken::Type m_type;
+ Attribute* getAttributeItem(const QualifiedName& attributeName)
+ {
+ ASSERT(usesAttributes());
+ return findAttributeInVector(m_attributes, attributeName);
+ }
- void initializeAttributes(const HTMLToken::AttributeList& attributes);
+ Vector<Attribute>& attributes()
+ {
+ ASSERT(usesAttributes());
+ return m_attributes;
+ }
- AtomicString m_name; // StartTag, EndTag, DOCTYPE.
+ const Vector<Attribute>& attributes() const
+ {
+ ASSERT(usesAttributes());
+ return m_attributes;
+ }
- String m_data; // Comment
+ const UChar* characters() const
+ {
+ ASSERT(m_type == HTMLToken::Character);
+ return m_externalCharacters;
+ }
- // We don't want to copy the the characters out of the HTMLToken, so we keep a pointer to its buffer instead.
- // This buffer is owned by the HTMLToken and causes a lifetime dependence between these objects.
- // FIXME: Add a mechanism for "internalizing" the characters when the HTMLToken is destroyed.
- const UChar* m_externalCharacters; // Character
- unsigned m_externalCharactersLength; // Character
- bool m_externalCharactersIsAll8BitData; // Character
+ size_t charactersLength() const
+ {
+ ASSERT(m_type == HTMLToken::Character);
+ return m_externalCharactersLength;
+ }
- std::unique_ptr<DoctypeData> m_doctypeData; // DOCTYPE.
+ bool isAll8BitData() const
+ {
+ return m_isAll8BitData;
+ }
- bool m_selfClosing; // StartTag, EndTag.
- Vector<Attribute> m_attributes; // StartTag, EndTag.
-};
+ const String& comment() const
+ {
+ ASSERT(m_type == HTMLToken::Comment);
+ return m_data;
+ }
-Attribute* findAttribute(Vector<Attribute>&, const QualifiedName&);
+ // FIXME: Distinguish between a missing public identifer and an empty one.
+ Vector<UChar>& publicIdentifier() const
+ {
+ ASSERT(m_type == HTMLToken::DOCTYPE);
+ return m_doctypeData->m_publicIdentifier;
+ }
-inline HTMLToken::Type AtomicHTMLToken::type() const
-{
- return m_type;
-}
+ // FIXME: Distinguish between a missing system identifer and an empty one.
+ Vector<UChar>& systemIdentifier() const
+ {
+ ASSERT(m_type == HTMLToken::DOCTYPE);
+ return m_doctypeData->m_systemIdentifier;
+ }
-inline const AtomicString& AtomicHTMLToken::name() const
-{
- ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag || m_type == HTMLToken::DOCTYPE);
- return m_name;
-}
+ explicit AtomicHTMLToken(HTMLToken& token)
+ : m_type(token.type())
+ {
+ switch (m_type) {
+ case HTMLToken::Uninitialized:
+ ASSERT_NOT_REACHED();
+ break;
+ case HTMLToken::DOCTYPE:
+ m_name = AtomicString(token.name());
+ m_doctypeData = token.releaseDoctypeData();
+ break;
+ case HTMLToken::EndOfFile:
+ break;
+ case HTMLToken::StartTag:
+ case HTMLToken::EndTag: {
+ m_selfClosing = token.selfClosing();
+ m_name = AtomicString(token.name());
+ initializeAttributes(token.attributes());
+ break;
+ }
+ case HTMLToken::Comment:
+ if (token.isAll8BitData())
+ m_data = String::make8BitFrom16BitSource(token.comment());
+ else
+ m_data = String(token.comment());
+ break;
+ case HTMLToken::Character:
+ m_externalCharacters = token.characters().data();
+ m_externalCharactersLength = token.characters().size();
+ m_isAll8BitData = token.isAll8BitData();
+ break;
+ }
+ }
-inline void AtomicHTMLToken::setName(const AtomicString& name)
-{
- ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag || m_type == HTMLToken::DOCTYPE);
- m_name = name;
-}
+ explicit AtomicHTMLToken(HTMLToken::Type type)
+ : m_type(type)
+ , m_externalCharacters(0)
+ , m_externalCharactersLength(0)
+ , m_isAll8BitData(false)
+ , m_selfClosing(false)
+ {
+ }
-inline bool AtomicHTMLToken::selfClosing() const
-{
- ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
- return m_selfClosing;
-}
+ AtomicHTMLToken(HTMLToken::Type type, const AtomicString& name, const Vector<Attribute>& attributes = Vector<Attribute>())
+ : m_type(type)
+ , m_name(name)
+ , m_externalCharacters(0)
+ , m_externalCharactersLength(0)
+ , m_isAll8BitData(false)
+ , m_selfClosing(false)
+ , m_attributes(attributes)
+ {
+ ASSERT(usesName());
+ }
-inline Vector<Attribute>& AtomicHTMLToken::attributes()
-{
- ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
- return m_attributes;
-}
+private:
+ HTMLToken::Type m_type;
-inline const Vector<Attribute>& AtomicHTMLToken::attributes() const
-{
- ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
- return m_attributes;
-}
+ void initializeAttributes(const HTMLToken::AttributeList& attributes);
+ QualifiedName nameForAttribute(const HTMLToken::Attribute&) const;
-inline const UChar* AtomicHTMLToken::characters() const
-{
- ASSERT(m_type == HTMLToken::Character);
- return m_externalCharacters;
-}
+ bool usesName() const;
-inline unsigned AtomicHTMLToken::charactersLength() const
-{
- ASSERT(m_type == HTMLToken::Character);
- return m_externalCharactersLength;
-}
+ bool usesAttributes() const;
-inline bool AtomicHTMLToken::charactersIsAll8BitData() const
-{
- return m_externalCharactersIsAll8BitData;
-}
+ // "name" for DOCTYPE, StartTag, and EndTag
+ AtomicString m_name;
-inline const String& AtomicHTMLToken::comment() const
-{
- ASSERT(m_type == HTMLToken::Comment);
- return m_data;
-}
+ // "data" for Comment
+ String m_data;
-inline bool AtomicHTMLToken::forceQuirks() const
-{
- ASSERT(m_type == HTMLToken::DOCTYPE);
- return m_doctypeData->forceQuirks;
-}
+ // "characters" for Character
+ //
+ // We don't want to copy the the characters out of the Token, so we
+ // keep a pointer to its buffer instead. This buffer is owned by the
+ // Token and causes a lifetime dependence between these objects.
+ //
+ // FIXME: Add a mechanism for "internalizing" the characters when the
+ // HTMLToken is destructed.
+ const UChar* m_externalCharacters;
+ size_t m_externalCharactersLength;
+ bool m_isAll8BitData;
-inline String AtomicHTMLToken::publicIdentifier() const
-{
- ASSERT(m_type == HTMLToken::DOCTYPE);
- if (!m_doctypeData->hasPublicIdentifier)
- return String();
- return StringImpl::create8BitIfPossible(m_doctypeData->publicIdentifier);
-}
+ // For DOCTYPE
+ std::unique_ptr<DoctypeData> m_doctypeData;
-inline String AtomicHTMLToken::systemIdentifier() const
-{
- if (!m_doctypeData->hasSystemIdentifier)
- return String();
- return StringImpl::create8BitIfPossible(m_doctypeData->systemIdentifier);
-}
+ // For StartTag and EndTag
+ bool m_selfClosing;
-inline Attribute* findAttribute(Vector<Attribute>& attributes, const QualifiedName& name)
-{
- for (auto& attribute : attributes) {
- if (attribute.name().matches(name))
- return &attribute;
- }
- return nullptr;
-}
+ Vector<Attribute> m_attributes;
+};
inline void AtomicHTMLToken::initializeAttributes(const HTMLToken::AttributeList& attributes)
{
- unsigned size = attributes.size();
+ size_t size = attributes.size();
if (!size)
return;
+ m_attributes.clear();
m_attributes.reserveInitialCapacity(size);
- for (unsigned i = 0; i < size; ++i) {
+ for (size_t i = 0; i < size; ++i) {
const HTMLToken::Attribute& attribute = attributes[i];
if (attribute.name.isEmpty())
continue;
- QualifiedName name(nullAtom, AtomicString(attribute.name), nullAtom);
+ // FIXME: We should be able to add the following ASSERT once we fix
+ // https://bugs.webkit.org/show_bug.cgi?id=62971
+ // ASSERT(attribute.nameRange.start);
+ ASSERT(attribute.nameRange.end);
+ ASSERT(attribute.valueRange.start);
+ ASSERT(attribute.valueRange.end);
+ AtomicString value(attribute.value);
+ const QualifiedName& name = nameForAttribute(attribute);
// FIXME: This is N^2 for the number of attributes.
- if (!findAttribute(m_attributes, name))
- m_attributes.append(Attribute(name, AtomicString(attribute.value)));
- }
-}
-
-inline AtomicHTMLToken::AtomicHTMLToken(HTMLToken& token)
- : m_type(token.type())
-{
- switch (m_type) {
- case HTMLToken::Uninitialized:
- ASSERT_NOT_REACHED();
- return;
- case HTMLToken::DOCTYPE:
- m_name = AtomicString(token.name());
- m_doctypeData = token.releaseDoctypeData();
- return;
- case HTMLToken::EndOfFile:
- return;
- case HTMLToken::StartTag:
- case HTMLToken::EndTag:
- m_selfClosing = token.selfClosing();
- m_name = AtomicString(token.name());
- initializeAttributes(token.attributes());
- return;
- case HTMLToken::Comment:
- if (token.commentIsAll8BitData())
- m_data = String::make8BitFrom16BitSource(token.comment());
- else
- m_data = String(token.comment());
- return;
- case HTMLToken::Character:
- m_externalCharacters = token.characters().data();
- m_externalCharactersLength = token.characters().size();
- m_externalCharactersIsAll8BitData = token.charactersIsAll8BitData();
- return;
+ if (!findAttributeInVector(m_attributes, name))
+ m_attributes.append(Attribute(name, value));
}
- ASSERT_NOT_REACHED();
-}
-
-inline AtomicHTMLToken::AtomicHTMLToken(HTMLToken::Type type, const AtomicString& name, Vector<Attribute>&& attributes)
- : m_type(type)
- , m_name(name)
- , m_selfClosing(false)
- , m_attributes(WTF::move(attributes))
-{
- ASSERT(type == HTMLToken::StartTag || type == HTMLToken::EndTag);
}
}
diff --git a/Source/WebCore/html/parser/HTMLConstructionSite.cpp b/Source/WebCore/html/parser/HTMLConstructionSite.cpp
index 4fb3ac8c9..0f0699826 100644
--- a/Source/WebCore/html/parser/HTMLConstructionSite.cpp
+++ b/Source/WebCore/html/parser/HTMLConstructionSite.cpp
@@ -42,7 +42,6 @@
#include "HTMLScriptElement.h"
#include "HTMLTemplateElement.h"
#include "NotImplemented.h"
-#include "SVGElement.h"
#include "Text.h"
namespace WebCore {
@@ -56,18 +55,16 @@ static inline void setAttributes(Element* element, AtomicHTMLToken* token, Parse
element->parserSetAttributes(token->attributes());
}
-static bool hasImpliedEndTag(const HTMLStackItem& item)
+static bool hasImpliedEndTag(const HTMLStackItem* item)
{
- return item.hasTagName(ddTag)
- || item.hasTagName(dtTag)
- || item.hasTagName(liTag)
- || is<HTMLOptionElement>(item.node())
- || is<HTMLOptGroupElement>(item.node())
- || item.hasTagName(pTag)
- || item.hasTagName(rbTag)
- || item.hasTagName(rpTag)
- || item.hasTagName(rtTag)
- || item.hasTagName(rtcTag);
+ return item->hasTagName(ddTag)
+ || item->hasTagName(dtTag)
+ || item->hasTagName(liTag)
+ || isHTMLOptionElement(item->node())
+ || isHTMLOptGroupElement(item->node())
+ || item->hasTagName(pTag)
+ || item->hasTagName(rpTag)
+ || item->hasTagName(rtTag);
}
static bool shouldUseLengthLimit(const ContainerNode* node)
@@ -77,15 +74,6 @@ static bool shouldUseLengthLimit(const ContainerNode* node)
&& !node->hasTagName(SVGNames::scriptTag);
}
-static inline bool causesFosterParenting(const HTMLStackItem& item)
-{
- return item.hasTagName(HTMLNames::tableTag)
- || item.hasTagName(HTMLNames::tbodyTag)
- || item.hasTagName(HTMLNames::tfootTag)
- || item.hasTagName(HTMLNames::theadTag)
- || item.hasTagName(HTMLNames::trTag);
-}
-
static inline bool isAllWhitespace(const String& string)
{
return string.isAllSpecialCharacters<isHTMLSpace>();
@@ -94,8 +82,8 @@ static inline bool isAllWhitespace(const String& string)
static inline void insert(HTMLConstructionSiteTask& task)
{
#if ENABLE(TEMPLATE_ELEMENT)
- if (is<HTMLTemplateElement>(*task.parent))
- task.parent = downcast<HTMLTemplateElement>(*task.parent).content();
+ if (task.parent->hasTagName(templateTag))
+ task.parent = toHTMLTemplateElement(task.parent.get())->content();
#endif
if (ContainerNode* parent = task.child->parentNode())
@@ -167,7 +155,7 @@ static inline void executeTask(HTMLConstructionSiteTask& task)
void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtr<Node> prpChild, bool selfClosing)
{
- ASSERT(scriptingContentIsAllowed(m_parserContentPolicy) || !is<Element>(*prpChild) || !toScriptElementIfPossible(downcast<Element>(prpChild.get())));
+ ASSERT(scriptingContentIsAllowed(m_parserContentPolicy) || !prpChild.get()->isElementNode() || !toScriptElementIfPossible(toElement(prpChild.get())));
ASSERT(pluginContentIsAllowed(m_parserContentPolicy) || !prpChild->isPluginElement());
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert);
@@ -196,7 +184,7 @@ void HTMLConstructionSite::executeQueuedTasks()
// Copy the task queue into a local variable in case executeTask
// re-enters the parser.
- TaskQueue queue = WTF::move(m_taskQueue);
+ TaskQueue queue = std::move(m_taskQueue);
for (size_t i = 0; i < size; ++i)
executeTask(queue[i]);
@@ -259,10 +247,10 @@ void HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded()
void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken* token)
{
- Ref<HTMLHtmlElement> element = HTMLHtmlElement::create(*m_document);
- setAttributes(element.ptr(), token, m_parserContentPolicy);
- attachLater(m_attachmentRoot, element.ptr());
- m_openElements.pushHTMLHtmlElement(HTMLStackItem::create(element.copyRef(), *token));
+ RefPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(*m_document);
+ setAttributes(element.get(), token, m_parserContentPolicy);
+ attachLater(m_attachmentRoot, element);
+ m_openElements.pushHTMLHtmlElement(HTMLStackItem::create(element, token));
executeQueuedTasks();
element->insertedByParser();
@@ -288,12 +276,12 @@ void HTMLConstructionSite::insertHTMLHtmlStartTagInBody(AtomicHTMLToken* token)
if (m_isParsingFragment)
return;
- mergeAttributesFromTokenIntoElement(token, &m_openElements.htmlElement());
+ mergeAttributesFromTokenIntoElement(token, m_openElements.htmlElement());
}
void HTMLConstructionSite::insertHTMLBodyStartTagInBody(AtomicHTMLToken* token)
{
- mergeAttributesFromTokenIntoElement(token, &m_openElements.bodyElement());
+ mergeAttributesFromTokenIntoElement(token, m_openElements.bodyElement());
}
void HTMLConstructionSite::setDefaultCompatibilityMode()
@@ -302,12 +290,12 @@ void HTMLConstructionSite::setDefaultCompatibilityMode()
return;
if (m_document->isSrcdocDocument())
return;
- setCompatibilityMode(DocumentCompatibilityMode::QuirksMode);
+ setCompatibilityMode(Document::QuirksMode);
}
-void HTMLConstructionSite::setCompatibilityMode(DocumentCompatibilityMode mode)
+void HTMLConstructionSite::setCompatibilityMode(Document::CompatibilityMode mode)
{
- m_inQuirksMode = (mode == DocumentCompatibilityMode::QuirksMode);
+ m_inQuirksMode = (mode == Document::QuirksMode);
m_document->setCompatibilityMode(mode);
}
@@ -382,7 +370,7 @@ void HTMLConstructionSite::setCompatibilityModeFromDoctype(const String& name, c
|| equalIgnoringCase(systemId, "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd")
|| (systemId.isEmpty() && publicId.startsWith("-//W3C//DTD HTML 4.01 Frameset//", false))
|| (systemId.isEmpty() && publicId.startsWith("-//W3C//DTD HTML 4.01 Transitional//", false))) {
- setCompatibilityMode(DocumentCompatibilityMode::QuirksMode);
+ setCompatibilityMode(Document::QuirksMode);
return;
}
@@ -391,12 +379,12 @@ void HTMLConstructionSite::setCompatibilityModeFromDoctype(const String& name, c
|| publicId.startsWith("-//W3C//DTD XHTML 1.0 Transitional//", false)
|| (!systemId.isEmpty() && publicId.startsWith("-//W3C//DTD HTML 4.01 Frameset//", false))
|| (!systemId.isEmpty() && publicId.startsWith("-//W3C//DTD HTML 4.01 Transitional//", false))) {
- setCompatibilityMode(DocumentCompatibilityMode::LimitedQuirksMode);
+ setCompatibilityMode(Document::LimitedQuirksMode);
return;
}
// Otherwise we are No Quirks Mode.
- setCompatibilityMode(DocumentCompatibilityMode::NoQuirksMode);
+ setCompatibilityMode(Document::NoQuirksMode);
}
void HTMLConstructionSite::finishedParsing()
@@ -408,9 +396,8 @@ void HTMLConstructionSite::insertDoctype(AtomicHTMLToken* token)
{
ASSERT(token->type() == HTMLToken::DOCTYPE);
- String publicId = token->publicIdentifier();
- String systemId = token->systemIdentifier();
-
+ const String& publicId = StringImpl::create8BitIfPossible(token->publicIdentifier());
+ const String& systemId = StringImpl::create8BitIfPossible(token->systemIdentifier());
RefPtr<DocumentType> doctype = DocumentType::create(*m_document, token->name(), publicId, systemId);
attachLater(m_attachmentRoot, doctype.release());
@@ -424,15 +411,16 @@ void HTMLConstructionSite::insertDoctype(AtomicHTMLToken* token)
return;
if (token->forceQuirks())
- setCompatibilityMode(DocumentCompatibilityMode::QuirksMode);
- else
+ setCompatibilityMode(Document::QuirksMode);
+ else {
setCompatibilityModeFromDoctype(token->name(), publicId, systemId);
+ }
}
void HTMLConstructionSite::insertComment(AtomicHTMLToken* token)
{
ASSERT(token->type() == HTMLToken::Comment);
- attachLater(&currentNode(), Comment::create(ownerDocumentForCurrentNode(), token->comment()));
+ attachLater(currentNode(), Comment::create(ownerDocumentForCurrentNode(), token->comment()));
}
void HTMLConstructionSite::insertCommentOnDocument(AtomicHTMLToken* token)
@@ -444,15 +432,15 @@ void HTMLConstructionSite::insertCommentOnDocument(AtomicHTMLToken* token)
void HTMLConstructionSite::insertCommentOnHTMLHtmlElement(AtomicHTMLToken* token)
{
ASSERT(token->type() == HTMLToken::Comment);
- ContainerNode& parent = m_openElements.rootNode();
- attachLater(&parent, Comment::create(parent.document(), token->comment()));
+ ContainerNode* parent = m_openElements.rootNode();
+ attachLater(parent, Comment::create(parent->document(), token->comment()));
}
void HTMLConstructionSite::insertHTMLHeadElement(AtomicHTMLToken* token)
{
ASSERT(!shouldFosterParent());
- m_head = HTMLStackItem::create(*createHTMLElement(token), *token);
- attachLater(&currentNode(), &m_head->element());
+ m_head = HTMLStackItem::create(createHTMLElement(token), token);
+ attachLater(currentNode(), m_head->element());
m_openElements.pushHTMLHeadElement(m_head);
}
@@ -460,25 +448,27 @@ void HTMLConstructionSite::insertHTMLBodyElement(AtomicHTMLToken* token)
{
ASSERT(!shouldFosterParent());
RefPtr<Element> body = createHTMLElement(token);
- attachLater(&currentNode(), body.get());
- m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body.releaseNonNull(), *token));
+ attachLater(currentNode(), body);
+ m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body.release(), token));
}
void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, bool isDemoted)
{
RefPtr<Element> element = createHTMLElement(token);
- ASSERT(is<HTMLFormElement>(*element));
- m_form = static_pointer_cast<HTMLFormElement>(element.release());
- m_form->setDemoted(isDemoted);
- attachLater(&currentNode(), m_form);
- m_openElements.push(HTMLStackItem::create(*m_form, *token));
+ ASSERT(isHTMLFormElement(element.get()));
+ RefPtr<HTMLFormElement> form = static_pointer_cast<HTMLFormElement>(element.release());
+ if (!insideTemplateElement())
+ m_form = form;
+ form->setDemoted(isDemoted);
+ attachLater(currentNode(), form);
+ m_openElements.push(HTMLStackItem::create(form.release(), token));
}
void HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken* token)
{
RefPtr<Element> element = createHTMLElement(token);
- attachLater(&currentNode(), element);
- m_openElements.push(HTMLStackItem::create(element.releaseNonNull(), *token));
+ attachLater(currentNode(), element);
+ m_openElements.push(HTMLStackItem::create(element.release(), token));
}
void HTMLConstructionSite::insertSelfClosingHTMLElement(AtomicHTMLToken* token)
@@ -487,7 +477,7 @@ void HTMLConstructionSite::insertSelfClosingHTMLElement(AtomicHTMLToken* token)
// Normally HTMLElementStack is responsible for calling finishParsingChildren,
// but self-closing elements are never in the element stack so the stack
// doesn't get a chance to tell them that we're done parsing their children.
- attachLater(&currentNode(), createHTMLElement(token), true);
+ attachLater(currentNode(), createHTMLElement(token), true);
// FIXME: Do we want to acknowledge the token's self-closing flag?
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#acknowledge-self-closing-flag
}
@@ -498,7 +488,7 @@ void HTMLConstructionSite::insertFormattingElement(AtomicHTMLToken* token)
// Possible active formatting elements include:
// a, b, big, code, em, font, i, nobr, s, small, strike, strong, tt, and u.
insertHTMLElement(token);
- m_activeFormattingElements.append(&currentStackItem());
+ m_activeFormattingElements.append(currentElementRecord()->stackItem());
}
void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token)
@@ -513,8 +503,8 @@ void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token)
RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(scriptTag, ownerDocumentForCurrentNode(), parserInserted, alreadyStarted);
setAttributes(element.get(), token, m_parserContentPolicy);
if (scriptingContentIsAllowed(m_parserContentPolicy))
- attachLater(&currentNode(), element);
- m_openElements.push(HTMLStackItem::create(element.releaseNonNull(), *token));
+ attachLater(currentNode(), element);
+ m_openElements.push(HTMLStackItem::create(element.release(), token));
}
void HTMLConstructionSite::insertForeignElement(AtomicHTMLToken* token, const AtomicString& namespaceURI)
@@ -524,22 +514,22 @@ void HTMLConstructionSite::insertForeignElement(AtomicHTMLToken* token, const At
RefPtr<Element> element = createElement(token, namespaceURI);
if (scriptingContentIsAllowed(m_parserContentPolicy) || !toScriptElementIfPossible(element.get()))
- attachLater(&currentNode(), element, token->selfClosing());
+ attachLater(currentNode(), element, token->selfClosing());
if (!token->selfClosing())
- m_openElements.push(HTMLStackItem::create(element.releaseNonNull(), *token, namespaceURI));
+ m_openElements.push(HTMLStackItem::create(element.release(), token, namespaceURI));
}
void HTMLConstructionSite::insertTextNode(const String& characters, WhitespaceMode whitespaceMode)
{
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert);
- task.parent = &currentNode();
+ task.parent = currentNode();
if (shouldFosterParent())
findFosterSite(task);
#if ENABLE(TEMPLATE_ELEMENT)
- if (is<HTMLTemplateElement>(*task.parent))
- task.parent = downcast<HTMLTemplateElement>(*task.parent).content();
+ if (task.parent->hasTagName(templateTag))
+ task.parent = toHTMLTemplateElement(task.parent.get())->content();
#endif
// Strings composed entirely of whitespace are likely to be repeated.
@@ -554,15 +544,15 @@ void HTMLConstructionSite::insertTextNode(const String& characters, WhitespaceMo
// for performance, see <https://bugs.webkit.org/show_bug.cgi?id=55898>.
Node* previousChild = task.nextChild ? task.nextChild->previousSibling() : task.parent->lastChild();
- if (is<Text>(previousChild)) {
+ if (previousChild && previousChild->isTextNode()) {
// FIXME: We're only supposed to append to this text node if it
// was the last text node inserted by the parser.
- Text& textNode = downcast<Text>(*previousChild);
- currentPosition = textNode.parserAppendData(characters, 0, lengthLimit);
+ Text* textNode = toText(previousChild);
+ currentPosition = textNode->parserAppendData(characters, 0, lengthLimit);
}
while (currentPosition < characters.length()) {
- Ref<Text> textNode = Text::createWithLengthLimit(task.parent->document(), shouldUseAtomicString ? AtomicString(characters).string() : characters, currentPosition, lengthLimit);
+ RefPtr<Text> textNode = Text::createWithLengthLimit(task.parent->document(), shouldUseAtomicString ? AtomicString(characters).string() : characters, currentPosition, lengthLimit);
// If we have a whole string of unbreakable characters the above could lead to an infinite loop. Exceeding the length limit is the lesser evil.
if (!textNode->length()) {
String substring = characters.substring(currentPosition);
@@ -571,7 +561,7 @@ void HTMLConstructionSite::insertTextNode(const String& characters, WhitespaceMo
currentPosition += textNode->length();
ASSERT(currentPosition <= characters.length());
- task.child = WTF::move(textNode);
+ task.child = textNode.release();
executeTask(task);
}
@@ -580,37 +570,37 @@ void HTMLConstructionSite::insertTextNode(const String& characters, WhitespaceMo
void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord& newParent, HTMLElementStack::ElementRecord& child)
{
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Reparent);
- task.parent = &newParent.node();
- task.child = &child.element();
+ task.parent = newParent.node();
+ task.child = child.element();
m_taskQueue.append(task);
}
void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord& newParent, HTMLStackItem& child)
{
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Reparent);
- task.parent = &newParent.node();
- task.child = &child.element();
+ task.parent = newParent.node();
+ task.child = child.element();
m_taskQueue.append(task);
}
void HTMLConstructionSite::insertAlreadyParsedChild(HTMLStackItem& newParent, HTMLElementStack::ElementRecord& child)
{
- if (causesFosterParenting(newParent)) {
- fosterParent(&child.element());
+ if (newParent.causesFosterParenting()) {
+ fosterParent(child.element());
return;
}
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertAlreadyParsedChild);
- task.parent = &newParent.node();
- task.child = &child.element();
+ task.parent = newParent.node();
+ task.child = child.element();
m_taskQueue.append(task);
}
void HTMLConstructionSite::takeAllChildren(HTMLStackItem& newParent, HTMLElementStack::ElementRecord& oldParent)
{
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::TakeAllChildren);
- task.parent = &newParent.node();
- task.child = &oldParent.node();
+ task.parent = newParent.node();
+ task.child = oldParent.node();
m_taskQueue.append(task);
}
@@ -625,10 +615,15 @@ PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken* token,
inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode()
{
#if ENABLE(TEMPLATE_ELEMENT)
- if (is<HTMLTemplateElement>(currentNode()))
- return downcast<HTMLTemplateElement>(currentNode()).content()->document();
+ if (currentNode()->hasTagName(templateTag))
+ return toHTMLTemplateElement(currentElement())->content()->document();
#endif
- return currentNode().document();
+ return currentNode()->document();
+}
+
+inline bool HTMLConstructionSite::insideTemplateElement()
+{
+ return !ownerDocumentForCurrentNode().frame();
}
PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token)
@@ -650,12 +645,12 @@ PassRefPtr<HTMLStackItem> HTMLConstructionSite::createElementFromSavedToken(HTML
{
RefPtr<Element> element;
// NOTE: Moving from item -> token -> item copies the Attribute vector twice!
- AtomicHTMLToken fakeToken(HTMLToken::StartTag, item->localName(), Vector<Attribute>(item->attributes()));
+ AtomicHTMLToken fakeToken(HTMLToken::StartTag, item->localName(), item->attributes());
if (item->namespaceURI() == HTMLNames::xhtmlNamespaceURI)
element = createHTMLElement(&fakeToken);
else
element = createElement(&fakeToken, item->namespaceURI());
- return HTMLStackItem::create(element.releaseNonNull(), fakeToken, item->namespaceURI());
+ return HTMLStackItem::create(element.release(), &fakeToken, item->namespaceURI());
}
bool HTMLConstructionSite::indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const
@@ -666,7 +661,7 @@ bool HTMLConstructionSite::indexOfFirstUnopenFormattingElement(unsigned& firstUn
do {
--index;
const HTMLFormattingElementList::Entry& entry = m_activeFormattingElements.at(index);
- if (entry.isMarker() || m_openElements.contains(&entry.element())) {
+ if (entry.isMarker() || m_openElements.contains(entry.element())) {
firstUnopenElementIndex = index + 1;
return firstUnopenElementIndex < m_activeFormattingElements.size();
}
@@ -685,8 +680,8 @@ void HTMLConstructionSite::reconstructTheActiveFormattingElements()
ASSERT(unopenEntryIndex < m_activeFormattingElements.size());
for (; unopenEntryIndex < m_activeFormattingElements.size(); ++unopenEntryIndex) {
HTMLFormattingElementList::Entry& unopenedEntry = m_activeFormattingElements.at(unopenEntryIndex);
- RefPtr<HTMLStackItem> reconstructed = createElementFromSavedToken(unopenedEntry.stackItem());
- attachLater(&currentNode(), &reconstructed->node());
+ RefPtr<HTMLStackItem> reconstructed = createElementFromSavedToken(unopenedEntry.stackItem().get());
+ attachLater(currentNode(), reconstructed->node());
m_openElements.push(reconstructed);
unopenedEntry.replaceElement(reconstructed.release());
}
@@ -694,7 +689,7 @@ void HTMLConstructionSite::reconstructTheActiveFormattingElements()
void HTMLConstructionSite::generateImpliedEndTagsWithExclusion(const AtomicString& tagName)
{
- while (hasImpliedEndTag(currentStackItem()) && !currentStackItem().matchesHTMLTag(tagName))
+ while (hasImpliedEndTag(currentStackItem()) && !currentStackItem()->matchesHTMLTag(tagName))
m_openElements.pop();
}
@@ -715,7 +710,7 @@ void HTMLConstructionSite::findFosterSite(HTMLConstructionSiteTask& task)
// When a node is to be foster parented, the last template element with no table element is below it in the stack of open elements is the foster parent element (NOT the template's parent!)
HTMLElementStack::ElementRecord* lastTemplateElement = m_openElements.topmost(templateTag.localName());
if (lastTemplateElement && !m_openElements.inTableScope(tableTag)) {
- task.parent = &lastTemplateElement->element();
+ task.parent = lastTemplateElement->element();
return;
}
@@ -723,30 +718,31 @@ void HTMLConstructionSite::findFosterSite(HTMLConstructionSiteTask& task)
HTMLElementStack::ElementRecord* lastTableElementRecord = m_openElements.topmost(tableTag.localName());
if (lastTableElementRecord) {
- Element& lastTableElement = lastTableElementRecord->element();
- ContainerNode* parent = lastTableElement.parentNode();
+ Element* lastTableElement = lastTableElementRecord->element();
+ ContainerNode* parent = lastTableElement->parentNode();
// When parsing HTML fragments, we skip step 4.2 ("Let root be a new html element with no attributes") for efficiency,
// and instead use the DocumentFragment as a root node. So we must treat the root node (DocumentFragment) as if it is a html element here.
- bool parentCanBeFosterParent = parent && (parent->isElementNode() || (m_isParsingFragment && parent == &m_openElements.rootNode()));
+ bool parentCanBeFosterParent = parent && (parent->isElementNode() || (m_isParsingFragment && parent == m_openElements.rootNode()));
#if ENABLE(TEMPLATE_ELEMENT)
- parentCanBeFosterParent = parentCanBeFosterParent || (is<DocumentFragment>(parent) && downcast<DocumentFragment>(parent)->isTemplateContent());
+ parentCanBeFosterParent = parentCanBeFosterParent || (parent && parent->isDocumentFragment() && toDocumentFragment(parent)->isTemplateContent());
#endif
if (parentCanBeFosterParent) {
task.parent = parent;
- task.nextChild = &lastTableElement;
+ task.nextChild = lastTableElement;
return;
}
- task.parent = &lastTableElementRecord->next()->element();
+ task.parent = lastTableElementRecord->next()->element();
return;
}
// Fragment case
- task.parent = &m_openElements.rootNode(); // DocumentFragment
+ task.parent = m_openElements.rootNode(); // DocumentFragment
}
bool HTMLConstructionSite::shouldFosterParent() const
{
return m_redirectAttachToFosterParent
- && causesFosterParenting(currentStackItem());
+ && currentStackItem()->isElementNode()
+ && currentStackItem()->causesFosterParenting();
}
void HTMLConstructionSite::fosterParent(PassRefPtr<Node> node)
diff --git a/Source/WebCore/html/parser/HTMLConstructionSite.h b/Source/WebCore/html/parser/HTMLConstructionSite.h
index af73bec36..acd4c823e 100644
--- a/Source/WebCore/html/parser/HTMLConstructionSite.h
+++ b/Source/WebCore/html/parser/HTMLConstructionSite.h
@@ -56,7 +56,7 @@ struct HTMLConstructionSiteTask {
// It's sort of ugly, but we store the |oldParent| in the |child| field
// of the task so that we don't bloat the HTMLConstructionSiteTask
// object in the common case of the Insert operation.
- return downcast<ContainerNode>(child.get());
+ return toContainerNode(child.get());
}
Operation operation;
@@ -138,16 +138,18 @@ public:
bool inQuirksMode();
bool isEmpty() const { return !m_openElements.stackDepth(); }
- Element& currentElement() const { return m_openElements.top(); }
- ContainerNode& currentNode() const { return m_openElements.topNode(); }
- HTMLStackItem& currentStackItem() const { return m_openElements.topStackItem(); }
+ HTMLElementStack::ElementRecord* currentElementRecord() const { return m_openElements.topRecord(); }
+ Element* currentElement() const { return m_openElements.top(); }
+ ContainerNode* currentNode() const { return m_openElements.topNode(); }
+ HTMLStackItem* currentStackItem() const { return m_openElements.topStackItem(); }
HTMLStackItem* oneBelowTop() const { return m_openElements.oneBelowTop(); }
Document& ownerDocumentForCurrentNode();
- HTMLElementStack& openElements() const { return m_openElements; }
- HTMLFormattingElementList& activeFormattingElements() const { return m_activeFormattingElements; }
- bool currentIsRootNode() { return &m_openElements.topNode() == &m_openElements.rootNode(); }
+ bool insideTemplateElement();
+ HTMLElementStack* openElements() const { return &m_openElements; }
+ HTMLFormattingElementList* activeFormattingElements() const { return &m_activeFormattingElements; }
+ bool currentIsRootNode() { return m_openElements.topNode() == m_openElements.rootNode(); }
- Element& head() const { return m_head->element(); }
+ Element* head() const { return m_head->element(); }
HTMLStackItem* headStackItem() const { return m_head.get(); }
void setForm(HTMLFormElement*);
@@ -156,7 +158,7 @@ public:
ParserContentPolicy parserContentPolicy() { return m_parserContentPolicy; }
-#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+#if PLATFORM(IOS)
bool isTelephoneNumberParsingEnabled() { return m_document->isTelephoneNumberParsingEnabled(); }
#endif
@@ -185,7 +187,7 @@ private:
// tokens produce only one DOM mutation.
typedef Vector<HTMLConstructionSiteTask, 1> TaskQueue;
- void setCompatibilityMode(DocumentCompatibilityMode);
+ void setCompatibilityMode(Document::CompatibilityMode);
void setCompatibilityModeFromDoctype(const String& name, const String& publicId, const String& systemId);
void attachLater(ContainerNode* parent, PassRefPtr<Node> child, bool selfClosing = false);
diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.cpp b/Source/WebCore/html/parser/HTMLDocumentParser.cpp
index 93c5f9397..488862049 100644
--- a/Source/WebCore/html/parser/HTMLDocumentParser.cpp
+++ b/Source/WebCore/html/parser/HTMLDocumentParser.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2010 Google, Inc. All Rights Reserved.
- * Copyright (C) 2015 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,59 +26,90 @@
#include "config.h"
#include "HTMLDocumentParser.h"
+#include "ContentSecurityPolicy.h"
#include "DocumentFragment.h"
+#include "DocumentLoader.h"
+#include "Frame.h"
#include "HTMLParserScheduler.h"
-#include "HTMLPreloadScanner.h"
#include "HTMLScriptRunner.h"
#include "HTMLTreeBuilder.h"
#include "HTMLDocument.h"
#include "InspectorInstrumentation.h"
+#include "Settings.h"
+#include <wtf/Ref.h>
namespace WebCore {
using namespace HTMLNames;
+// This is a direct transcription of step 4 from:
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
+static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElement, bool reportErrors, const HTMLParserOptions& options)
+{
+ if (!contextElement)
+ return HTMLTokenizer::DataState;
+
+ const QualifiedName& contextTag = contextElement->tagQName();
+
+ if (contextTag.matches(titleTag) || contextTag.matches(textareaTag))
+ return HTMLTokenizer::RCDATAState;
+ if (contextTag.matches(styleTag)
+ || contextTag.matches(xmpTag)
+ || contextTag.matches(iframeTag)
+ || (contextTag.matches(noembedTag) && options.pluginsEnabled)
+ || (contextTag.matches(noscriptTag) && options.scriptEnabled)
+ || contextTag.matches(noframesTag))
+ return reportErrors ? HTMLTokenizer::RAWTEXTState : HTMLTokenizer::PLAINTEXTState;
+ if (contextTag.matches(scriptTag))
+ return reportErrors ? HTMLTokenizer::ScriptDataState : HTMLTokenizer::PLAINTEXTState;
+ if (contextTag.matches(plaintextTag))
+ return HTMLTokenizer::PLAINTEXTState;
+ return HTMLTokenizer::DataState;
+}
+
HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document)
: ScriptableDocumentParser(document)
, m_options(document)
- , m_tokenizer(m_options)
+ , m_token(std::make_unique<HTMLToken>())
+ , m_tokenizer(std::make_unique<HTMLTokenizer>(m_options))
, m_scriptRunner(std::make_unique<HTMLScriptRunner>(document, static_cast<HTMLScriptRunnerHost&>(*this)))
, m_treeBuilder(std::make_unique<HTMLTreeBuilder>(*this, document, parserContentPolicy(), m_options))
, m_parserScheduler(std::make_unique<HTMLParserScheduler>(*this))
, m_xssAuditorDelegate(document)
, m_preloader(std::make_unique<HTMLResourcePreloader>(document))
+ , m_endWasDelayed(false)
+ , m_haveBackgroundParser(false)
+ , m_pumpSessionNestingLevel(0)
{
+ ASSERT(m_token);
+ ASSERT(m_tokenizer);
}
-Ref<HTMLDocumentParser> HTMLDocumentParser::create(HTMLDocument& document)
-{
- return adoptRef(*new HTMLDocumentParser(document));
-}
-
-inline HTMLDocumentParser::HTMLDocumentParser(DocumentFragment& fragment, Element& contextElement, ParserContentPolicy rawPolicy)
- : ScriptableDocumentParser(fragment.document(), rawPolicy)
+// FIXME: Member variables should be grouped into self-initializing structs to
+// minimize code duplication between these constructors.
+HTMLDocumentParser::HTMLDocumentParser(DocumentFragment& fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
+ : ScriptableDocumentParser(fragment.document(), parserContentPolicy)
, m_options(fragment.document())
- , m_tokenizer(m_options)
- , m_treeBuilder(std::make_unique<HTMLTreeBuilder>(*this, fragment, contextElement, parserContentPolicy(), m_options))
+ , m_token(std::make_unique<HTMLToken>())
+ , m_tokenizer(std::make_unique<HTMLTokenizer>(m_options))
+ , m_treeBuilder(std::make_unique<HTMLTreeBuilder>(*this, fragment, contextElement, this->parserContentPolicy(), m_options))
, m_xssAuditorDelegate(fragment.document())
+ , m_endWasDelayed(false)
+ , m_haveBackgroundParser(false)
+ , m_pumpSessionNestingLevel(0)
{
- // https://html.spec.whatwg.org/multipage/syntax.html#parsing-html-fragments
- if (contextElement.isHTMLElement())
- m_tokenizer.updateStateFor(contextElement.tagQName().localName());
+ bool reportErrors = false; // For now document fragment parsing never reports errors.
+ m_tokenizer->setState(tokenizerStateForContextElement(contextElement, reportErrors, m_options));
m_xssAuditor.initForFragment();
}
-inline Ref<HTMLDocumentParser> HTMLDocumentParser::create(DocumentFragment& fragment, Element& contextElement, ParserContentPolicy parserContentPolicy)
-{
- return adoptRef(*new HTMLDocumentParser(fragment, contextElement, parserContentPolicy));
-}
-
HTMLDocumentParser::~HTMLDocumentParser()
{
ASSERT(!m_parserScheduler);
ASSERT(!m_pumpSessionNestingLevel);
ASSERT(!m_preloadScanner);
ASSERT(!m_insertionPreloadScanner);
+ ASSERT(!m_haveBackgroundParser);
}
void HTMLDocumentParser::detach()
@@ -88,6 +118,7 @@ void HTMLDocumentParser::detach()
if (m_scriptRunner)
m_scriptRunner->detach();
+ m_treeBuilder->detach();
// FIXME: It seems wrong that we would have a preload scanner here.
// Yet during fast/dom/HTMLScriptElement/script-load-events.html we do.
m_preloadScanner = nullptr;
@@ -102,10 +133,12 @@ void HTMLDocumentParser::stopParsing()
}
// This kicks off "Once the user agent stops parsing" as described by:
-// https://html.spec.whatwg.org/multipage/syntax.html#the-end
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end
void HTMLDocumentParser::prepareToStopParsing()
{
- ASSERT(!hasInsertionPoint());
+ // FIXME: It may not be correct to disable this for the background parser.
+ // That means hasInsertionPoint() may not be correct in some cases.
+ ASSERT(!hasInsertionPoint() || m_haveBackgroundParser);
// pumpTokenizer can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
@@ -132,16 +165,6 @@ void HTMLDocumentParser::prepareToStopParsing()
attemptToRunDeferredScriptsAndEnd();
}
-inline bool HTMLDocumentParser::inPumpSession() const
-{
- return m_pumpSessionNestingLevel > 0;
-}
-
-inline bool HTMLDocumentParser::shouldDelayEnd() const
-{
- return inPumpSession() || isWaitingForScripts() || isScheduledForResume() || isExecutingScript();
-}
-
bool HTMLDocumentParser::isParsingFragment() const
{
return m_treeBuilder->isParsingFragment();
@@ -149,7 +172,7 @@ bool HTMLDocumentParser::isParsingFragment() const
bool HTMLDocumentParser::processingData() const
{
- return isScheduledForResume() || inPumpSession();
+ return isScheduledForResume() || inPumpSession() || m_haveBackgroundParser;
}
void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode)
@@ -178,8 +201,8 @@ void HTMLDocumentParser::resumeParsingAfterYield()
// but we need to ensure it isn't deleted yet.
Ref<HTMLDocumentParser> protect(*this);
- // We should never be here unless we can pump immediately.
- // Call pumpTokenizer() directly so that ASSERTS will fire if we're wrong.
+ // We should never be here unless we can pump immediately. Call pumpTokenizer()
+ // directly so that ASSERTS will fire if we're wrong.
pumpTokenizer(AllowYield);
endIfDelayed();
}
@@ -189,11 +212,10 @@ void HTMLDocumentParser::runScriptsForPausedTreeBuilder()
ASSERT(scriptingContentIsAllowed(parserContentPolicy()));
TextPosition scriptStartPosition = TextPosition::belowRangePosition();
- if (auto scriptElement = m_treeBuilder->takeScriptToProcess(scriptStartPosition)) {
- // We will not have a scriptRunner when parsing a DocumentFragment.
- if (m_scriptRunner)
- m_scriptRunner->execute(scriptElement.release(), scriptStartPosition);
- }
+ RefPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptStartPosition);
+ // We will not have a scriptRunner when parsing a DocumentFragment.
+ if (m_scriptRunner)
+ m_scriptRunner->execute(scriptElement.release(), scriptStartPosition);
}
bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& session)
@@ -201,6 +223,8 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses
if (isStopped())
return false;
+ ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous);
+
if (isWaitingForScripts()) {
if (mode == AllowYield)
m_parserScheduler->checkForYieldBeforeScript(session);
@@ -215,11 +239,14 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses
return false;
}
- // FIXME: It's wrong for the HTMLDocumentParser to reach back to the Frame, but this approach is
- // how the parser has always handled stopping when the page assigns window.location. What should
- // happen instead is that assigning window.location causes the parser to stop parsing cleanly.
- // The problem is we're not prepared to do that at every point where we run JavaScript.
- if (!isParsingFragment() && document()->frame() && document()->frame()->navigationScheduler().locationChangePending())
+ // FIXME: It's wrong for the HTMLDocumentParser to reach back to the
+ // Frame, but this approach is how the old parser handled
+ // stopping when the page assigns window.location. What really
+ // should happen is that assigning window.location causes the
+ // parser to stop parsing cleanly. The problem is we're not
+ // perpared to do that at every point where we run JavaScript.
+ if (!isParsingFragment()
+ && document()->frame() && document()->frame()->navigationScheduler().locationChangePending())
return false;
if (mode == AllowYield)
@@ -228,12 +255,17 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses
return true;
}
+void HTMLDocumentParser::forcePlaintextForTextDocument()
+{
+ m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
+}
+
Document* HTMLDocumentParser::contextForParsingSession()
{
// The parsing session should interact with the document only when parsing
// non-fragments. Otherwise, we might delay the load event mistakenly.
if (isParsingFragment())
- return nullptr;
+ return 0;
return document();
}
@@ -241,9 +273,11 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
{
ASSERT(!isStopped());
ASSERT(!isScheduledForResume());
-
- // This is an attempt to check that this object is both attached to the Document and protected by something.
+ // ASSERT that this object is both attached to the Document and protected.
ASSERT(refCount() >= 2);
+ ASSERT(m_tokenizer);
+ ASSERT(m_token);
+ ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous);
PumpSession session(m_pumpSessionNestingLevel, contextForParsingSession());
@@ -252,28 +286,28 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
// FIXME: m_input.current().length() is only accurate if we
// end up parsing the whole buffer in this pump. We should pass how
// much we parsed as part of didWriteHTML instead of willWriteHTML.
- auto cookie = InspectorInstrumentation::willWriteHTML(document(), m_input.current().currentLine().zeroBasedInt());
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteHTML(document(), m_input.current().currentLine().zeroBasedInt());
m_xssAuditor.init(document(), &m_xssAuditorDelegate);
while (canTakeNextToken(mode, session) && !session.needsYield) {
if (!isParsingFragment())
- m_sourceTracker.startToken(m_input.current(), m_tokenizer);
+ m_sourceTracker.start(m_input.current(), m_tokenizer.get(), token());
- auto token = m_tokenizer.nextToken(m_input.current());
- if (!token)
+ if (!m_tokenizer->nextToken(m_input.current(), token()))
break;
if (!isParsingFragment()) {
- m_sourceTracker.endToken(m_input.current(), m_tokenizer);
+ m_sourceTracker.end(m_input.current(), m_tokenizer.get(), token());
// We do not XSS filter innerHTML, which means we (intentionally) fail
// http/tests/security/xssAuditor/dom-write-innerHTML.html
- if (auto xssInfo = m_xssAuditor.filterToken(FilterTokenRequest(*token, m_sourceTracker, m_tokenizer.shouldAllowCDATA())))
+ if (auto xssInfo = m_xssAuditor.filterToken(FilterTokenRequest(token(), m_sourceTracker, m_tokenizer->shouldAllowCDATA())))
m_xssAuditorDelegate.didBlockScript(*xssInfo);
}
- constructTreeFromHTMLToken(token);
+ constructTreeFromHTMLToken(token());
+ ASSERT(token().isUninitialized());
}
// Ensure we haven't been totally deref'ed after pumping. Any caller of this
@@ -287,20 +321,20 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
m_parserScheduler->scheduleForResume();
if (isWaitingForScripts()) {
- ASSERT(m_tokenizer.isInDataState());
+ ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState);
if (!m_preloadScanner) {
m_preloadScanner = std::make_unique<HTMLPreloadScanner>(m_options, document()->url(), document()->deviceScaleFactor());
m_preloadScanner->appendToEnd(m_input.current());
}
- m_preloadScanner->scan(*m_preloader, *document());
+ m_preloadScanner->scan(m_preloader.get(), document()->baseElementURL());
}
InspectorInstrumentation::didWriteHTML(cookie, m_input.current().currentLine().zeroBasedInt());
}
-void HTMLDocumentParser::constructTreeFromHTMLToken(HTMLTokenizer::TokenPtr& rawToken)
+void HTMLDocumentParser::constructTreeFromHTMLToken(HTMLToken& rawToken)
{
- AtomicHTMLToken token(*rawToken);
+ AtomicHTMLToken token(rawToken);
// We clear the rawToken in case constructTreeFromAtomicToken
// synchronously re-enters the parser. We don't clear the token immedately
@@ -312,21 +346,24 @@ void HTMLDocumentParser::constructTreeFromHTMLToken(HTMLTokenizer::TokenPtr& raw
// FIXME: Stop clearing the rawToken once we start running the parser off
// the main thread or once we stop allowing synchronous JavaScript
// execution from parseAttribute.
- if (rawToken->type() != HTMLToken::Character) {
- // Clearing the TokenPtr makes sure we don't clear the HTMLToken a second time
- // later when the TokenPtr is destroyed.
+ if (rawToken.type() != HTMLToken::Character)
rawToken.clear();
- }
- m_treeBuilder->constructTree(token);
+ m_treeBuilder->constructTree(&token);
+
+ if (!rawToken.isUninitialized()) {
+ ASSERT(rawToken.type() == HTMLToken::Character);
+ rawToken.clear();
+ }
}
bool HTMLDocumentParser::hasInsertionPoint()
{
// FIXME: The wasCreatedByScript() branch here might not be fully correct.
- // Our model of the EOF character differs slightly from the one in the spec
- // because our treatment is uniform between network-sourced and script-sourced
- // input streams whereas the spec treats them differently.
+ // Our model of the EOF character differs slightly from the one in
+ // the spec because our treatment is uniform between network-sourced
+ // and script-sourced input streams whereas the spec treats them
+ // differently.
return m_input.hasInsertionPoint() || (wasCreatedByScript() && !m_input.haveSeenEndOfFile());
}
@@ -347,10 +384,11 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
if (isWaitingForScripts()) {
// Check the document.write() output with a separate preload scanner as
// the main scanner can't deal with insertions.
- if (!m_insertionPreloadScanner)
+ if (!m_insertionPreloadScanner) {
m_insertionPreloadScanner = std::make_unique<HTMLPreloadScanner>(m_options, document()->url(), document()->deviceScaleFactor());
+ }
m_insertionPreloadScanner->appendToEnd(source);
- m_insertionPreloadScanner->scan(*m_preloader, *document());
+ m_insertionPreloadScanner->scan(m_preloader.get(), document()->baseElementURL());
}
endIfDelayed();
@@ -364,7 +402,6 @@ void HTMLDocumentParser::append(PassRefPtr<StringImpl> inputSource)
// pumpTokenizer can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
Ref<HTMLDocumentParser> protect(*this);
-
String source(inputSource);
if (m_preloadScanner) {
@@ -375,7 +412,7 @@ void HTMLDocumentParser::append(PassRefPtr<StringImpl> inputSource)
} else {
m_preloadScanner->appendToEnd(source);
if (isWaitingForScripts())
- m_preloadScanner->scan(*m_preloader, *document());
+ m_preloadScanner->scan(m_preloader.get(), document()->baseElementURL());
}
}
@@ -405,7 +442,9 @@ void HTMLDocumentParser::end()
void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd()
{
ASSERT(isStopping());
- ASSERT(!hasInsertionPoint());
+ // FIXME: It may not be correct to disable this for the background parser.
+ // That means hasInsertionPoint() may not be correct in some cases.
+ ASSERT(!hasInsertionPoint() || m_haveBackgroundParser);
if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing())
return;
end();
@@ -453,18 +492,18 @@ void HTMLDocumentParser::finish()
bool HTMLDocumentParser::isExecutingScript() const
{
- return m_scriptRunner && m_scriptRunner->isExecutingScript();
+ if (!m_scriptRunner)
+ return false;
+ return m_scriptRunner->isExecutingScript();
}
TextPosition HTMLDocumentParser::textPosition() const
{
- auto& currentString = m_input.current();
- return TextPosition(currentString.currentLine(), currentString.currentColumn());
-}
+ const SegmentedString& currentString = m_input.current();
+ OrdinalNumber line = currentString.currentLine();
+ OrdinalNumber column = currentString.currentColumn();
-bool HTMLDocumentParser::shouldAssociateConsoleMessagesWithTextPosition() const
-{
- return inPumpSession() && !isExecutingScript();
+ return TextPosition(line, column);
}
bool HTMLDocumentParser::isWaitingForScripts() const
@@ -488,10 +527,6 @@ void HTMLDocumentParser::resumeParsingAfterScriptExecution()
ASSERT(!isExecutingScript());
ASSERT(!isWaitingForScripts());
- // pumpTokenizer can cause this parser to be detached from the Document,
- // but we need to ensure it isn't deleted yet.
- Ref<HTMLDocumentParser> protect(*this);
-
m_insertionPreloadScanner = nullptr;
pumpTokenizerIfPossible(AllowYield);
endIfDelayed();
@@ -510,12 +545,12 @@ void HTMLDocumentParser::stopWatchingForLoad(CachedResource* cachedScript)
{
cachedScript->removeClient(this);
}
-
+
void HTMLDocumentParser::appendCurrentInputStreamToPreloadScannerAndScan()
{
ASSERT(m_preloadScanner);
m_preloadScanner->appendToEnd(m_input.current());
- m_preloadScanner->scan(*m_preloader, *document());
+ m_preloadScanner->scan(m_preloader.get(), document()->baseElementURL());
}
void HTMLDocumentParser::notifyFinished(CachedResource* cachedResource)
@@ -555,13 +590,13 @@ void HTMLDocumentParser::executeScriptsWaitingForStylesheets()
resumeParsingAfterScriptExecution();
}
-void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFragment& fragment, Element& contextElement, ParserContentPolicy parserContentPolicy)
+void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFragment& fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
{
- auto parser = create(fragment, contextElement, parserContentPolicy);
+ RefPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
parser->insert(source); // Use insert() so that the parser will not yield.
parser->finish();
- ASSERT(!parser->processingData());
- parser->detach();
+ ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/3963151>
+ parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction.
}
void HTMLDocumentParser::suspendScheduledTasks()
diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.h b/Source/WebCore/html/parser/HTMLDocumentParser.h
index 47984c6c9..89d44960d 100644
--- a/Source/WebCore/html/parser/HTMLDocumentParser.h
+++ b/Source/WebCore/html/parser/HTMLDocumentParser.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2010 Google, Inc. All Rights Reserved.
- * Copyright (C) 2015 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,84 +27,107 @@
#define HTMLDocumentParser_h
#include "CachedResourceClient.h"
+#include "FragmentScriptingPermission.h"
#include "HTMLInputStream.h"
+#include "HTMLParserOptions.h"
+#include "HTMLPreloadScanner.h"
#include "HTMLScriptRunnerHost.h"
#include "HTMLSourceTracker.h"
+#include "HTMLToken.h"
#include "HTMLTokenizer.h"
#include "ScriptableDocumentParser.h"
+#include "SegmentedString.h"
#include "XSSAuditor.h"
#include "XSSAuditorDelegate.h"
+#include <wtf/Deque.h>
+#include <wtf/WeakPtr.h>
+#include <wtf/text/TextPosition.h>
namespace WebCore {
+class BackgroundHTMLParser;
+class CompactHTMLToken;
+class Document;
class DocumentFragment;
class HTMLDocument;
class HTMLParserScheduler;
-class HTMLPreloadScanner;
class HTMLScriptRunner;
class HTMLTreeBuilder;
class HTMLResourcePreloader;
+class ScriptController;
+class ScriptSourceCode;
+
class PumpSession;
-class HTMLDocumentParser : public ScriptableDocumentParser, private HTMLScriptRunnerHost, private CachedResourceClient {
+class HTMLDocumentParser : public ScriptableDocumentParser, HTMLScriptRunnerHost, CachedResourceClient {
WTF_MAKE_FAST_ALLOCATED;
public:
- static Ref<HTMLDocumentParser> create(HTMLDocument&);
+ static PassRefPtr<HTMLDocumentParser> create(HTMLDocument& document)
+ {
+ return adoptRef(new HTMLDocumentParser(document));
+ }
virtual ~HTMLDocumentParser();
- static void parseDocumentFragment(const String&, DocumentFragment&, Element& contextElement, ParserContentPolicy = AllowScriptingContent);
-
- // For HTMLParserScheduler.
+ // Exposed for HTMLParserScheduler
void resumeParsingAfterYield();
- // For HTMLTreeBuilder.
- HTMLTokenizer& tokenizer();
- virtual TextPosition textPosition() const override final;
+ static void parseDocumentFragment(const String&, DocumentFragment&, Element* contextElement, ParserContentPolicy = AllowScriptingContent);
-protected:
- explicit HTMLDocumentParser(HTMLDocument&);
+ HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); }
+
+ virtual TextPosition textPosition() const override;
- virtual void insert(const SegmentedString&) override final;
+ virtual void suspendScheduledTasks() override;
+ virtual void resumeScheduledTasks() override;
+
+protected:
+ virtual void insert(const SegmentedString&) override;
virtual void append(PassRefPtr<StringImpl>) override;
virtual void finish() override;
- HTMLTreeBuilder& treeBuilder();
+ explicit HTMLDocumentParser(HTMLDocument&);
+ HTMLDocumentParser(DocumentFragment&, Element* contextElement, ParserContentPolicy);
+
+ HTMLTreeBuilder* treeBuilder() const { return m_treeBuilder.get(); }
+
+ void forcePlaintextForTextDocument();
private:
- HTMLDocumentParser(DocumentFragment&, Element& contextElement, ParserContentPolicy);
- static Ref<HTMLDocumentParser> create(DocumentFragment&, Element& contextElement, ParserContentPolicy);
+ static PassRefPtr<HTMLDocumentParser> create(DocumentFragment& fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
+ {
+ return adoptRef(new HTMLDocumentParser(fragment, contextElement, parserContentPolicy));
+ }
// DocumentParser
- virtual void detach() override final;
- virtual bool hasInsertionPoint() override final;
- virtual bool processingData() const override final;
- virtual void prepareToStopParsing() override final;
- virtual void stopParsing() override final;
+ virtual void detach() override;
+ virtual bool hasInsertionPoint() override;
+ virtual bool processingData() const override;
+ virtual void prepareToStopParsing() override;
+ virtual void stopParsing() override;
virtual bool isWaitingForScripts() const override;
- virtual bool isExecutingScript() const override final;
- virtual void executeScriptsWaitingForStylesheets() override final;
- virtual void suspendScheduledTasks() override final;
- virtual void resumeScheduledTasks() override final;
-
- virtual bool shouldAssociateConsoleMessagesWithTextPosition() const override final;
+ virtual bool isExecutingScript() const override;
+ virtual void executeScriptsWaitingForStylesheets() override;
// HTMLScriptRunnerHost
- virtual void watchForLoad(CachedResource*) override final;
- virtual void stopWatchingForLoad(CachedResource*) override final;
- virtual HTMLInputStream& inputStream() override final;
- virtual bool hasPreloadScanner() const override final;
- virtual void appendCurrentInputStreamToPreloadScannerAndScan() override final;
+ virtual void watchForLoad(CachedResource*) override;
+ virtual void stopWatchingForLoad(CachedResource*) override;
+ virtual HTMLInputStream& inputStream() override { return m_input; }
+ virtual bool hasPreloadScanner() const override { return m_preloadScanner.get(); }
+ virtual void appendCurrentInputStreamToPreloadScannerAndScan() override;
// CachedResourceClient
- virtual void notifyFinished(CachedResource*) override final;
+ virtual void notifyFinished(CachedResource*) override;
Document* contextForParsingSession();
- enum SynchronousMode { AllowYield, ForceSynchronous };
+ enum SynchronousMode {
+ AllowYield,
+ ForceSynchronous,
+ };
bool canTakeNextToken(SynchronousMode, PumpSession&);
void pumpTokenizer(SynchronousMode);
void pumpTokenizerIfPossible(SynchronousMode);
- void constructTreeFromHTMLToken(HTMLTokenizer::TokenPtr&);
+ void constructTreeFromHTMLToken(HTMLToken&);
void runScriptsForPausedTreeBuilder();
void resumeParsingAfterScriptExecution();
@@ -117,13 +139,16 @@ private:
bool isParsingFragment() const;
bool isScheduledForResume() const;
- bool inPumpSession() const;
- bool shouldDelayEnd() const;
+ bool inPumpSession() const { return m_pumpSessionNestingLevel > 0; }
+ bool shouldDelayEnd() const { return inPumpSession() || isWaitingForScripts() || isScheduledForResume() || isExecutingScript(); }
+
+ HTMLToken& token() { return *m_token.get(); }
HTMLParserOptions m_options;
HTMLInputStream m_input;
- HTMLTokenizer m_tokenizer;
+ std::unique_ptr<HTMLToken> m_token;
+ std::unique_ptr<HTMLTokenizer> m_tokenizer;
std::unique_ptr<HTMLScriptRunner> m_scriptRunner;
std::unique_ptr<HTMLTreeBuilder> m_treeBuilder;
std::unique_ptr<HTMLPreloadScanner> m_preloadScanner;
@@ -136,31 +161,11 @@ private:
std::unique_ptr<HTMLResourcePreloader> m_preloader;
- bool m_endWasDelayed { false };
- unsigned m_pumpSessionNestingLevel { 0 };
+ bool m_endWasDelayed;
+ bool m_haveBackgroundParser;
+ unsigned m_pumpSessionNestingLevel;
};
-inline HTMLTokenizer& HTMLDocumentParser::tokenizer()
-{
- return m_tokenizer;
-}
-
-inline HTMLInputStream& HTMLDocumentParser::inputStream()
-{
- return m_input;
-}
-
-inline bool HTMLDocumentParser::hasPreloadScanner() const
-{
- return m_preloadScanner.get();
-}
-
-inline HTMLTreeBuilder& HTMLDocumentParser::treeBuilder()
-{
- ASSERT(m_treeBuilder);
- return *m_treeBuilder;
-}
-
}
#endif
diff --git a/Source/WebCore/html/parser/HTMLElementStack.cpp b/Source/WebCore/html/parser/HTMLElementStack.cpp
index ed5a456b0..2aaf6db92 100644
--- a/Source/WebCore/html/parser/HTMLElementStack.cpp
+++ b/Source/WebCore/html/parser/HTMLElementStack.cpp
@@ -36,97 +36,98 @@ namespace WebCore {
using namespace HTMLNames;
+
namespace {
-inline bool isRootNode(HTMLStackItem& item)
-{
- return item.isDocumentFragment()
- || item.hasTagName(htmlTag);
-}
-
-inline bool isScopeMarker(HTMLStackItem& item)
-{
- return item.hasTagName(appletTag)
- || item.hasTagName(captionTag)
- || item.hasTagName(marqueeTag)
- || item.hasTagName(objectTag)
- || is<HTMLTableElement>(item.node())
- || item.hasTagName(tdTag)
- || item.hasTagName(thTag)
- || item.hasTagName(MathMLNames::miTag)
- || item.hasTagName(MathMLNames::moTag)
- || item.hasTagName(MathMLNames::mnTag)
- || item.hasTagName(MathMLNames::msTag)
- || item.hasTagName(MathMLNames::mtextTag)
- || item.hasTagName(MathMLNames::annotation_xmlTag)
- || item.hasTagName(SVGNames::foreignObjectTag)
- || item.hasTagName(SVGNames::descTag)
- || item.hasTagName(SVGNames::titleTag)
+inline bool isRootNode(HTMLStackItem* item)
+{
+ return item->isDocumentFragmentNode()
+ || item->hasTagName(htmlTag);
+}
+
+inline bool isScopeMarker(HTMLStackItem* item)
+{
+ return item->hasTagName(appletTag)
+ || item->hasTagName(captionTag)
+ || item->hasTagName(marqueeTag)
+ || item->hasTagName(objectTag)
+ || isHTMLTableElement(item->node())
+ || item->hasTagName(tdTag)
+ || item->hasTagName(thTag)
+ || item->hasTagName(MathMLNames::miTag)
+ || item->hasTagName(MathMLNames::moTag)
+ || item->hasTagName(MathMLNames::mnTag)
+ || item->hasTagName(MathMLNames::msTag)
+ || item->hasTagName(MathMLNames::mtextTag)
+ || item->hasTagName(MathMLNames::annotation_xmlTag)
+ || item->hasTagName(SVGNames::foreignObjectTag)
+ || item->hasTagName(SVGNames::descTag)
+ || item->hasTagName(SVGNames::titleTag)
#if ENABLE(TEMPLATE_ELEMENT)
- || item.hasTagName(templateTag)
+ || item->hasTagName(templateTag)
#endif
|| isRootNode(item);
}
-inline bool isListItemScopeMarker(HTMLStackItem& item)
+inline bool isListItemScopeMarker(HTMLStackItem* item)
{
return isScopeMarker(item)
- || item.hasTagName(olTag)
- || item.hasTagName(ulTag);
+ || item->hasTagName(olTag)
+ || item->hasTagName(ulTag);
}
-inline bool isTableScopeMarker(HTMLStackItem& item)
+inline bool isTableScopeMarker(HTMLStackItem* item)
{
- return is<HTMLTableElement>(item.node())
+ return isHTMLTableElement(item->node())
#if ENABLE(TEMPLATE_ELEMENT)
- || item.hasTagName(templateTag)
+ || item->hasTagName(templateTag)
#endif
|| isRootNode(item);
}
-inline bool isTableBodyScopeMarker(HTMLStackItem& item)
+inline bool isTableBodyScopeMarker(HTMLStackItem* item)
{
- return item.hasTagName(tbodyTag)
- || item.hasTagName(tfootTag)
- || item.hasTagName(theadTag)
+ return item->hasTagName(tbodyTag)
+ || item->hasTagName(tfootTag)
+ || item->hasTagName(theadTag)
#if ENABLE(TEMPLATE_ELEMENT)
- || item.hasTagName(templateTag)
+ || item->hasTagName(templateTag)
#endif
|| isRootNode(item);
}
-inline bool isTableRowScopeMarker(HTMLStackItem& item)
+inline bool isTableRowScopeMarker(HTMLStackItem* item)
{
- return item.hasTagName(trTag)
+ return item->hasTagName(trTag)
#if ENABLE(TEMPLATE_ELEMENT)
- || item.hasTagName(templateTag)
+ || item->hasTagName(templateTag)
#endif
|| isRootNode(item);
}
-inline bool isForeignContentScopeMarker(HTMLStackItem& item)
+inline bool isForeignContentScopeMarker(HTMLStackItem* item)
{
return HTMLElementStack::isMathMLTextIntegrationPoint(item)
|| HTMLElementStack::isHTMLIntegrationPoint(item)
- || isInHTMLNamespace(item);
+ || item->isInHTMLNamespace();
}
-inline bool isButtonScopeMarker(HTMLStackItem& item)
+inline bool isButtonScopeMarker(HTMLStackItem* item)
{
return isScopeMarker(item)
- || item.hasTagName(buttonTag);
+ || item->hasTagName(buttonTag);
}
-inline bool isSelectScopeMarker(HTMLStackItem& item)
+inline bool isSelectScopeMarker(HTMLStackItem* item)
{
- return !is<HTMLOptGroupElement>(item.node()) && !is<HTMLOptionElement>(item.node());
+ return !isHTMLOptGroupElement(item->node()) && !isHTMLOptionElement(item->node());
}
}
HTMLElementStack::ElementRecord::ElementRecord(PassRefPtr<HTMLStackItem> item, std::unique_ptr<ElementRecord> next)
: m_item(item)
- , m_next(WTF::move(next))
+ , m_next(std::move(next))
{
ASSERT(m_item);
}
@@ -138,7 +139,7 @@ HTMLElementStack::ElementRecord::~ElementRecord()
void HTMLElementStack::ElementRecord::replaceElement(PassRefPtr<HTMLStackItem> item)
{
ASSERT(item);
- ASSERT(!m_item || m_item->isElement());
+ ASSERT(!m_item || m_item->isElementNode());
// FIXME: Should this call finishParsingChildren?
m_item = item;
}
@@ -166,7 +167,7 @@ HTMLElementStack::~HTMLElementStack()
bool HTMLElementStack::hasOnlyOneElement() const
{
- return !topRecord().next();
+ return !topRecord()->next();
}
bool HTMLElementStack::secondElementIsHTMLBodyElement() const
@@ -183,15 +184,15 @@ bool HTMLElementStack::secondElementIsHTMLBodyElement() const
void HTMLElementStack::popHTMLHeadElement()
{
- ASSERT(&top() == m_headElement);
- m_headElement = nullptr;
+ ASSERT(top() == m_headElement);
+ m_headElement = 0;
popCommon();
}
void HTMLElementStack::popHTMLBodyElement()
{
- ASSERT(&top() == m_bodyElement);
- m_bodyElement = nullptr;
+ ASSERT(top() == m_bodyElement);
+ m_bodyElement = 0;
popCommon();
}
@@ -202,20 +203,20 @@ void HTMLElementStack::popAll()
m_bodyElement = 0;
m_stackDepth = 0;
while (m_top) {
- topNode().finishParsingChildren();
+ topNode()->finishParsingChildren();
m_top = m_top->releaseNext();
}
}
void HTMLElementStack::pop()
{
- ASSERT(!topStackItem().hasTagName(HTMLNames::headTag));
+ ASSERT(!topStackItem()->hasTagName(HTMLNames::headTag));
popCommon();
}
void HTMLElementStack::popUntil(const AtomicString& tagName)
{
- while (!topStackItem().matchesHTMLTag(tagName)) {
+ while (!topStackItem()->matchesHTMLTag(tagName)) {
// pop() will ASSERT if a <body>, <head> or <html> will be popped.
pop();
}
@@ -229,14 +230,14 @@ void HTMLElementStack::popUntilPopped(const AtomicString& tagName)
void HTMLElementStack::popUntilNumberedHeaderElementPopped()
{
- while (!isNumberedHeaderElement(topStackItem()))
+ while (!topStackItem()->isNumberedHeaderElement())
pop();
pop();
}
void HTMLElementStack::popUntil(Element* element)
{
- while (&top() != element)
+ while (top() != element)
pop();
}
@@ -268,20 +269,24 @@ void HTMLElementStack::popUntilTableRowScopeMarker()
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#mathml-text-integration-point
-bool HTMLElementStack::isMathMLTextIntegrationPoint(HTMLStackItem& item)
+bool HTMLElementStack::isMathMLTextIntegrationPoint(HTMLStackItem* item)
{
- return item.hasTagName(MathMLNames::miTag)
- || item.hasTagName(MathMLNames::moTag)
- || item.hasTagName(MathMLNames::mnTag)
- || item.hasTagName(MathMLNames::msTag)
- || item.hasTagName(MathMLNames::mtextTag);
+ if (!item->isElementNode())
+ return false;
+ return item->hasTagName(MathMLNames::miTag)
+ || item->hasTagName(MathMLNames::moTag)
+ || item->hasTagName(MathMLNames::mnTag)
+ || item->hasTagName(MathMLNames::msTag)
+ || item->hasTagName(MathMLNames::mtextTag);
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#html-integration-point
-bool HTMLElementStack::isHTMLIntegrationPoint(HTMLStackItem& item)
+bool HTMLElementStack::isHTMLIntegrationPoint(HTMLStackItem* item)
{
- if (item.hasTagName(MathMLNames::annotation_xmlTag)) {
- const Attribute* encodingAttr = item.findAttribute(MathMLNames::encodingAttr);
+ if (!item->isElementNode())
+ return false;
+ if (item->hasTagName(MathMLNames::annotation_xmlTag)) {
+ Attribute* encodingAttr = item->getAttributeItem(MathMLNames::encodingAttr);
if (encodingAttr) {
const String& encoding = encodingAttr->value();
return equalIgnoringCase(encoding, "text/html")
@@ -289,9 +294,9 @@ bool HTMLElementStack::isHTMLIntegrationPoint(HTMLStackItem& item)
}
return false;
}
- return item.hasTagName(SVGNames::foreignObjectTag)
- || item.hasTagName(SVGNames::descTag)
- || item.hasTagName(SVGNames::titleTag);
+ return item->hasTagName(SVGNames::foreignObjectTag)
+ || item->hasTagName(SVGNames::descTag)
+ || item->hasTagName(SVGNames::titleTag);
}
void HTMLElementStack::popUntilForeignContentScopeMarker()
@@ -302,7 +307,7 @@ void HTMLElementStack::popUntilForeignContentScopeMarker()
void HTMLElementStack::pushRootNode(PassRefPtr<HTMLStackItem> rootItem)
{
- ASSERT(rootItem->isDocumentFragment());
+ ASSERT(rootItem->isDocumentFragmentNode());
pushRootNodeCommon(rootItem);
}
@@ -316,7 +321,7 @@ void HTMLElementStack::pushRootNodeCommon(PassRefPtr<HTMLStackItem> rootItem)
{
ASSERT(!m_top);
ASSERT(!m_rootNode);
- m_rootNode = &rootItem->node();
+ m_rootNode = rootItem->node();
pushCommon(rootItem);
}
@@ -324,7 +329,7 @@ void HTMLElementStack::pushHTMLHeadElement(PassRefPtr<HTMLStackItem> item)
{
ASSERT(item->hasTagName(HTMLNames::headTag));
ASSERT(!m_headElement);
- m_headElement = &item->element();
+ m_headElement = item->element();
pushCommon(item);
}
@@ -332,7 +337,7 @@ void HTMLElementStack::pushHTMLBodyElement(PassRefPtr<HTMLStackItem> item)
{
ASSERT(item->hasTagName(HTMLNames::bodyTag));
ASSERT(!m_bodyElement);
- m_bodyElement = &item->element();
+ m_bodyElement = item->element();
pushCommon(item);
}
@@ -365,16 +370,16 @@ void HTMLElementStack::insertAbove(PassRefPtr<HTMLStackItem> item, ElementRecord
m_stackDepth++;
recordAbove->setNext(std::make_unique<ElementRecord>(item, recordAbove->releaseNext()));
- recordAbove->next()->element().beginParsingChildren();
+ recordAbove->next()->element()->beginParsingChildren();
return;
}
ASSERT_NOT_REACHED();
}
-HTMLElementStack::ElementRecord& HTMLElementStack::topRecord() const
+HTMLElementStack::ElementRecord* HTMLElementStack::topRecord() const
{
ASSERT(m_top);
- return *m_top;
+ return m_top.get();
}
HTMLStackItem* HTMLElementStack::oneBelowTop() const
@@ -382,26 +387,26 @@ HTMLStackItem* HTMLElementStack::oneBelowTop() const
// We should never call this if there are fewer than 2 elements on the stack.
ASSERT(m_top);
ASSERT(m_top->next());
- if (m_top->next()->stackItem().isElement())
- return &m_top->next()->stackItem();
- return nullptr;
+ if (m_top->next()->stackItem()->isElementNode())
+ return m_top->next()->stackItem().get();
+ return 0;
}
void HTMLElementStack::removeHTMLHeadElement(Element* element)
{
ASSERT(m_headElement == element);
- if (&m_top->element() == element) {
+ if (m_top->element() == element) {
popHTMLHeadElement();
return;
}
- m_headElement = nullptr;
+ m_headElement = 0;
removeNonTopCommon(element);
}
void HTMLElementStack::remove(Element* element)
{
ASSERT(!element->hasTagName(HTMLNames::headTag));
- if (&m_top->element() == element) {
+ if (m_top->element() == element) {
pop();
return;
}
@@ -410,20 +415,20 @@ void HTMLElementStack::remove(Element* element)
HTMLElementStack::ElementRecord* HTMLElementStack::find(Element* element) const
{
- for (ElementRecord* record = m_top.get(); record; record = record->next()) {
- if (&record->node() == element)
- return record;
+ for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
+ if (pos->node() == element)
+ return pos;
}
- return nullptr;
+ return 0;
}
HTMLElementStack::ElementRecord* HTMLElementStack::topmost(const AtomicString& tagName) const
{
- for (ElementRecord* record = m_top.get(); record; record = record->next()) {
- if (record->stackItem().matchesHTMLTag(tagName))
- return record;
+ for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
+ if (pos->stackItem()->matchesHTMLTag(tagName))
+ return pos;
}
- return nullptr;
+ return 0;
}
bool HTMLElementStack::contains(Element* element) const
@@ -436,11 +441,12 @@ bool HTMLElementStack::contains(const AtomicString& tagName) const
return !!topmost(tagName);
}
-template <bool isMarker(HTMLStackItem&)> bool inScopeCommon(HTMLElementStack::ElementRecord* top, const AtomicString& targetTag)
+template <bool isMarker(HTMLStackItem*)>
+bool inScopeCommon(HTMLElementStack::ElementRecord* top, const AtomicString& targetTag)
{
- for (auto* record = top; record; record = record->next()) {
- HTMLStackItem& item = record->stackItem();
- if (item.matchesHTMLTag(targetTag))
+ for (HTMLElementStack::ElementRecord* pos = top; pos; pos = pos->next()) {
+ HTMLStackItem* item = pos->stackItem().get();
+ if (item->matchesHTMLTag(targetTag))
return true;
if (isMarker(item))
return false;
@@ -452,8 +458,8 @@ template <bool isMarker(HTMLStackItem&)> bool inScopeCommon(HTMLElementStack::El
bool HTMLElementStack::hasNumberedHeaderElementInScope() const
{
for (ElementRecord* record = m_top.get(); record; record = record->next()) {
- HTMLStackItem& item = record->stackItem();
- if (isNumberedHeaderElement(item))
+ HTMLStackItem* item = record->stackItem().get();
+ if (item->isNumberedHeaderElement())
return true;
if (isScopeMarker(item))
return false;
@@ -464,9 +470,9 @@ bool HTMLElementStack::hasNumberedHeaderElementInScope() const
bool HTMLElementStack::inScope(Element* targetElement) const
{
- for (ElementRecord* record = m_top.get(); record; record = record->next()) {
- HTMLStackItem& item = record->stackItem();
- if (&item.node() == targetElement)
+ for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
+ HTMLStackItem* item = pos->stackItem().get();
+ if (item->node() == targetElement)
return true;
if (isScopeMarker(item))
return false;
@@ -532,27 +538,28 @@ bool HTMLElementStack::hasTemplateInHTMLScope() const
}
#endif
-Element& HTMLElementStack::htmlElement() const
+Element* HTMLElementStack::htmlElement() const
{
- return downcast<Element>(rootNode());
+ ASSERT(m_rootNode);
+ return toElement(m_rootNode);
}
-Element& HTMLElementStack::headElement() const
+Element* HTMLElementStack::headElement() const
{
ASSERT(m_headElement);
- return *m_headElement;
+ return m_headElement;
}
-Element& HTMLElementStack::bodyElement() const
+Element* HTMLElementStack::bodyElement() const
{
ASSERT(m_bodyElement);
- return *m_bodyElement;
+ return m_bodyElement;
}
-ContainerNode& HTMLElementStack::rootNode() const
+ContainerNode* HTMLElementStack::rootNode() const
{
ASSERT(m_rootNode);
- return *m_rootNode;
+ return m_rootNode;
}
void HTMLElementStack::pushCommon(PassRefPtr<HTMLStackItem> item)
@@ -560,16 +567,15 @@ void HTMLElementStack::pushCommon(PassRefPtr<HTMLStackItem> item)
ASSERT(m_rootNode);
m_stackDepth++;
- m_top = std::make_unique<ElementRecord>(item, WTF::move(m_top));
+ m_top = std::make_unique<ElementRecord>(item, std::move(m_top));
}
void HTMLElementStack::popCommon()
{
- ASSERT(!topStackItem().hasTagName(HTMLNames::htmlTag));
- ASSERT(!topStackItem().hasTagName(HTMLNames::headTag) || !m_headElement);
- ASSERT(!topStackItem().hasTagName(HTMLNames::bodyTag) || !m_bodyElement);
-
- top().finishParsingChildren();
+ ASSERT(!topStackItem()->hasTagName(HTMLNames::htmlTag));
+ ASSERT(!topStackItem()->hasTagName(HTMLNames::headTag) || !m_headElement);
+ ASSERT(!topStackItem()->hasTagName(HTMLNames::bodyTag) || !m_bodyElement);
+ top()->finishParsingChildren();
m_top = m_top->releaseNext();
m_stackDepth--;
@@ -579,13 +585,13 @@ void HTMLElementStack::removeNonTopCommon(Element* element)
{
ASSERT(!element->hasTagName(HTMLNames::htmlTag));
ASSERT(!element->hasTagName(HTMLNames::bodyTag));
- ASSERT(&top() != element);
- for (ElementRecord* record = m_top.get(); record; record = record->next()) {
- if (&record->next()->element() == element) {
+ ASSERT(top() != element);
+ for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
+ if (pos->next()->element() == element) {
// FIXME: Is it OK to call finishParsingChildren()
// when the children aren't actually finished?
element->finishParsingChildren();
- record->setNext(record->next()->releaseNext());
+ pos->setNext(pos->next()->releaseNext());
m_stackDepth--;
return;
}
@@ -595,23 +601,23 @@ void HTMLElementStack::removeNonTopCommon(Element* element)
HTMLElementStack::ElementRecord* HTMLElementStack::furthestBlockForFormattingElement(Element* formattingElement) const
{
- ElementRecord* furthestBlock = nullptr;
- for (ElementRecord* record = m_top.get(); record; record = record->next()) {
- if (&record->element() == formattingElement)
+ ElementRecord* furthestBlock = 0;
+ for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
+ if (pos->element() == formattingElement)
return furthestBlock;
- if (isSpecialNode(record->stackItem()))
- furthestBlock = record;
+ if (pos->stackItem()->isSpecialNode())
+ furthestBlock = pos;
}
ASSERT_NOT_REACHED();
- return nullptr;
+ return 0;
}
-#if ENABLE(TREE_DEBUGGING)
+#ifndef NDEBUG
void HTMLElementStack::show()
{
for (ElementRecord* record = m_top.get(); record; record = record->next())
- record->element().showNode();
+ record->element()->showNode();
}
#endif
diff --git a/Source/WebCore/html/parser/HTMLElementStack.h b/Source/WebCore/html/parser/HTMLElementStack.h
index 8658c09f2..a2c4f54de 100644
--- a/Source/WebCore/html/parser/HTMLElementStack.h
+++ b/Source/WebCore/html/parser/HTMLElementStack.h
@@ -53,21 +53,20 @@ public:
ElementRecord(PassRefPtr<HTMLStackItem>, std::unique_ptr<ElementRecord>);
~ElementRecord();
- Element& element() const { return m_item->element(); }
- ContainerNode& node() const { return m_item->node(); }
+ Element* element() const { return m_item->element(); }
+ ContainerNode* node() const { return m_item->node(); }
const AtomicString& namespaceURI() const { return m_item->namespaceURI(); }
- HTMLStackItem& stackItem() const { return *m_item; }
+ PassRefPtr<HTMLStackItem> stackItem() const { return m_item; }
void replaceElement(PassRefPtr<HTMLStackItem>);
bool isAbove(ElementRecord*) const;
ElementRecord* next() const { return m_next.get(); }
-
private:
friend class HTMLElementStack;
- std::unique_ptr<ElementRecord> releaseNext() { return WTF::move(m_next); }
- void setNext(std::unique_ptr<ElementRecord> next) { m_next = WTF::move(next); }
+ std::unique_ptr<ElementRecord> releaseNext() { return std::move(m_next); }
+ void setNext(std::unique_ptr<ElementRecord> next) { m_next = std::move(next); }
RefPtr<HTMLStackItem> m_item;
std::unique_ptr<ElementRecord> m_next;
@@ -77,23 +76,26 @@ public:
// Inlining this function is a (small) performance win on the parsing
// benchmark.
- Element& top() const
+ Element* top() const
{
+ ASSERT(m_top->element());
return m_top->element();
}
- ContainerNode& topNode() const
+ ContainerNode* topNode() const
{
+ ASSERT(m_top->node());
return m_top->node();
}
- HTMLStackItem& topStackItem() const
+ HTMLStackItem* topStackItem() const
{
- return m_top->stackItem();
+ ASSERT(m_top->stackItem());
+ return m_top->stackItem().get();
}
HTMLStackItem* oneBelowTop() const;
- ElementRecord& topRecord() const;
+ ElementRecord* topRecord() const;
ElementRecord* find(Element*) const;
ElementRecord* furthestBlockForFormattingElement(Element*) const;
ElementRecord* topmost(const AtomicString& tagName) const;
@@ -122,8 +124,8 @@ public:
void popHTMLBodyElement();
void popAll();
- static bool isMathMLTextIntegrationPoint(HTMLStackItem&);
- static bool isHTMLIntegrationPoint(HTMLStackItem&);
+ static bool isMathMLTextIntegrationPoint(HTMLStackItem*);
+ static bool isHTMLIntegrationPoint(HTMLStackItem*);
void remove(Element*);
void removeHTMLHeadElement(Element*);
@@ -150,13 +152,13 @@ public:
#if ENABLE(TEMPLATE_ELEMENT)
bool hasTemplateInHTMLScope() const;
#endif
- Element& htmlElement() const;
- Element& headElement() const;
- Element& bodyElement() const;
-
- ContainerNode& rootNode() const;
+ Element* htmlElement() const;
+ Element* headElement() const;
+ Element* bodyElement() const;
+
+ ContainerNode* rootNode() const;
-#if ENABLE(TREE_DEBUGGING)
+#ifndef NDEBUG
void show();
#endif
diff --git a/Source/WebCore/html/parser/HTMLEntityParser.cpp b/Source/WebCore/html/parser/HTMLEntityParser.cpp
index dbffadf76..8d2177fd2 100644
--- a/Source/WebCore/html/parser/HTMLEntityParser.cpp
+++ b/Source/WebCore/html/parser/HTMLEntityParser.cpp
@@ -32,7 +32,8 @@
#include "HTMLEntitySearch.h"
#include "HTMLEntityTable.h"
#include <wtf/text/StringBuilder.h>
-#include <wtf/unicode/CharacterNames.h>
+
+using namespace WTF;
namespace WebCore {
@@ -43,20 +44,33 @@ static const UChar windowsLatin1ExtensionArray[32] = {
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x017E, 0x0178, // 98-9F
};
+static inline bool isAlphaNumeric(UChar cc)
+{
+ return (cc >= '0' && cc <= '9') || (cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z');
+}
+
class HTMLEntityParser {
public:
- static UChar32 legalEntityFor(UChar32 value)
+ inline static UChar adjustEntity(UChar32 value)
{
- if (value <= 0 || value > UCHAR_MAX_VALUE || U_IS_SURROGATE(value))
- return replacementCharacter;
- if ((value & ~0x1F) != 0x80)
+ if ((value & ~0x1F) != 0x0080)
return value;
return windowsLatin1ExtensionArray[value - 0x80];
}
- static bool acceptMalformed() { return true; }
+ inline static UChar32 legalEntityFor(UChar32 value)
+ {
+ // FIXME: A number of specific entity values generate parse errors.
+ if (!value || value > 0x10FFFF || (value >= 0xD800 && value <= 0xDFFF))
+ return 0xFFFD;
+ if (U_IS_BMP(value))
+ return adjustEntity(value);
+ return value;
+ }
+
+ inline static bool acceptMalformed() { return true; }
- static bool consumeNamedEntity(SegmentedString& source, StringBuilder& decodedEntity, bool& notEnoughCharacters, UChar additionalAllowedCharacter, UChar& cc)
+ inline static bool consumeNamedEntity(SegmentedString& source, StringBuilder& decodedEntity, bool& notEnoughCharacters, UChar additionalAllowedCharacter, UChar& cc)
{
StringBuilder consumedCharacters;
HTMLEntitySearch entitySearch;
@@ -66,7 +80,7 @@ public:
if (!entitySearch.isEntityPrefix())
break;
consumedCharacters.append(cc);
- source.advance();
+ source.advanceAndASSERT(cc);
}
notEnoughCharacters = source.isEmpty();
if (notEnoughCharacters) {
@@ -91,14 +105,14 @@ public:
cc = source.currentChar();
ASSERT_UNUSED(reference, cc == *reference++);
consumedCharacters.append(cc);
- source.advance();
+ source.advanceAndASSERT(cc);
ASSERT(!source.isEmpty());
}
cc = source.currentChar();
}
if (entitySearch.mostRecentMatch()->lastCharacter() == ';'
|| !additionalAllowedCharacter
- || !(isASCIIAlphanumeric(cc) || cc == '=')) {
+ || !(isAlphaNumeric(cc) || cc == '=')) {
decodedEntity.append(entitySearch.mostRecentMatch()->firstValue);
if (entitySearch.mostRecentMatch()->secondValue)
decodedEntity.append(entitySearch.mostRecentMatch()->secondValue);
diff --git a/Source/WebCore/html/parser/HTMLFormattingElementList.cpp b/Source/WebCore/html/parser/HTMLFormattingElementList.cpp
index 44edf1c43..f38a9384e 100644
--- a/Source/WebCore/html/parser/HTMLFormattingElementList.cpp
+++ b/Source/WebCore/html/parser/HTMLFormattingElementList.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "HTMLFormattingElementList.h"
+#include "NotImplemented.h"
+
#ifndef NDEBUG
#include <stdio.h>
#endif
@@ -50,11 +52,11 @@ Element* HTMLFormattingElementList::closestElementInScopeWithName(const AtomicSt
for (unsigned i = 1; i <= m_entries.size(); ++i) {
const Entry& entry = m_entries[m_entries.size() - i];
if (entry.isMarker())
- return nullptr;
+ return 0;
if (entry.stackItem()->matchesHTMLTag(targetName))
- return &entry.element();
+ return entry.element();
}
- return nullptr;
+ return 0;
}
bool HTMLFormattingElementList::contains(Element* element)
@@ -82,9 +84,9 @@ HTMLFormattingElementList::Bookmark HTMLFormattingElementList::bookmarkFor(Eleme
void HTMLFormattingElementList::swapTo(Element* oldElement, PassRefPtr<HTMLStackItem> newItem, const Bookmark& bookmark)
{
ASSERT(contains(oldElement));
- ASSERT(!contains(&newItem->element()));
+ ASSERT(!contains(newItem->element()));
if (!bookmark.hasBeenMoved()) {
- ASSERT(&bookmark.mark()->element() == oldElement);
+ ASSERT(bookmark.mark()->element() == oldElement);
bookmark.mark()->replaceElement(newItem);
return;
}
@@ -143,7 +145,7 @@ void HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly(HTMLStackIte
break;
// Quickly reject obviously non-matching candidates.
- HTMLStackItem* candidate = entry.stackItem();
+ HTMLStackItem* candidate = entry.stackItem().get();
if (newItem->localName() != candidate->localName() || newItem->namespaceURI() != candidate->namespaceURI())
continue;
if (candidate->attributes().size() != newItemAttributeCount)
@@ -181,7 +183,7 @@ void HTMLFormattingElementList::ensureNoahsArkCondition(HTMLStackItem* newItem)
ASSERT(newItem->attributes().size() == candidate->attributes().size());
ASSERT(newItem->localName() == candidate->localName() && newItem->namespaceURI() == candidate->namespaceURI());
- const Attribute* candidateAttribute = candidate->findAttribute(attribute.name());
+ Attribute* candidateAttribute = candidate->getAttributeItem(attribute.name());
if (candidateAttribute && candidateAttribute->value() == attribute.value())
remainingCandidates.append(candidate);
}
@@ -197,10 +199,10 @@ void HTMLFormattingElementList::ensureNoahsArkCondition(HTMLStackItem* newItem)
// however, that we wil spin the loop more than once because of how the
// formatting element list gets permuted.
for (size_t i = kNoahsArkCapacity - 1; i < candidates.size(); ++i)
- remove(&candidates[i]->element());
+ remove(candidates[i]->element());
}
-#if ENABLE(TREE_DEBUGGING)
+#ifndef NDEBUG
void HTMLFormattingElementList::show()
{
@@ -209,7 +211,7 @@ void HTMLFormattingElementList::show()
if (entry.isMarker())
fprintf(stderr, "marker\n");
else
- entry.element().showNode();
+ entry.element()->showNode();
}
}
diff --git a/Source/WebCore/html/parser/HTMLFormattingElementList.h b/Source/WebCore/html/parser/HTMLFormattingElementList.h
index 8b251b27e..35ac17cc2 100644
--- a/Source/WebCore/html/parser/HTMLFormattingElementList.h
+++ b/Source/WebCore/html/parser/HTMLFormattingElementList.h
@@ -61,8 +61,8 @@ public:
bool isMarker() const { return !m_item; }
- HTMLStackItem* stackItem() const { return m_item.get(); }
- Element& element() const
+ PassRefPtr<HTMLStackItem> stackItem() const { return m_item; }
+ Element* element() const
{
// The fact that !m_item == isMarker() is an implementation detail
// callers should check isMarker() before calling element().
@@ -72,8 +72,8 @@ public:
void replaceElement(PassRefPtr<HTMLStackItem> item) { m_item = item; }
// Needed for use with Vector. These are super-hot and must be inline.
- bool operator==(Element* element) const { return !m_item ? !element : &m_item->element() == element; }
- bool operator!=(Element* element) const { return !m_item ? !!element : &m_item->element() != element; }
+ bool operator==(Element* element) const { return !m_item ? !element : m_item->element() == element; }
+ bool operator!=(Element* element) const { return !m_item ? !!element : m_item->element() != element; }
private:
RefPtr<HTMLStackItem> m_item;
@@ -121,7 +121,7 @@ public:
const Entry& at(size_t i) const { return m_entries[i]; }
Entry& at(size_t i) { return m_entries[i]; }
-#if ENABLE(TREE_DEBUGGING)
+#ifndef NDEBUG
void show();
#endif
diff --git a/Source/WebCore/html/parser/HTMLInputStream.h b/Source/WebCore/html/parser/HTMLInputStream.h
index e738f5f34..a7b86b3ba 100644
--- a/Source/WebCore/html/parser/HTMLInputStream.h
+++ b/Source/WebCore/html/parser/HTMLInputStream.h
@@ -28,7 +28,6 @@
#include "InputStreamPreprocessor.h"
#include "SegmentedString.h"
-#include <wtf/text/TextPosition.h>
namespace WebCore {
diff --git a/Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp b/Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp
index 752dbeedb..11e14a46e 100644
--- a/Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp
+++ b/Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2010 Google Inc. All Rights Reserved.
- * Copyright (C) 2015 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,26 +28,41 @@
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
+#include "HTMLTokenizer.h"
+#include "TextCodec.h"
#include "TextEncodingRegistry.h"
+using namespace WTF;
+
namespace WebCore {
using namespace HTMLNames;
HTMLMetaCharsetParser::HTMLMetaCharsetParser()
- : m_codec(newTextCodec(Latin1Encoding()))
+ : m_tokenizer(std::make_unique<HTMLTokenizer>(HTMLParserOptions()))
+ , m_assumedCodec(newTextCodec(Latin1Encoding()))
+ , m_inHeadSection(true)
+ , m_doneChecking(false)
+{
+}
+
+HTMLMetaCharsetParser::~HTMLMetaCharsetParser()
{
}
-static StringView extractCharset(const String& value)
+static const char charsetString[] = "charset";
+static const size_t charsetLength = sizeof("charset") - 1;
+
+String HTMLMetaCharsetParser::extractCharset(const String& value)
{
+ size_t pos = 0;
unsigned length = value.length();
- for (size_t pos = 0; pos < length; ) {
- pos = value.find("charset", pos, false);
+
+ while (pos < length) {
+ pos = value.find(charsetString, pos, false);
if (pos == notFound)
break;
- static const size_t charsetLength = sizeof("charset") - 1;
pos += charsetLength;
// Skip whitespace.
@@ -63,10 +77,12 @@ static StringView extractCharset(const String& value)
while (pos < length && value[pos] <= ' ')
++pos;
- UChar quoteMark = 0;
- if (pos < length && (value[pos] == '"' || value[pos] == '\''))
- quoteMark = value[pos++];
-
+ char quoteMark = 0;
+ if (pos < length && (value[pos] == '"' || value[pos] == '\'')) {
+ quoteMark = static_cast<char>(value[pos++]);
+ ASSERT(!(quoteMark & 0x80));
+ }
+
if (pos == length)
break;
@@ -77,17 +93,19 @@ static StringView extractCharset(const String& value)
if (quoteMark && (end == length))
break; // Close quote not found.
- return StringView(value).substring(pos, end - pos);
+ return value.substring(pos, end - pos);
}
- return StringView();
+
+ return "";
}
-bool HTMLMetaCharsetParser::processMeta(HTMLToken& token)
+bool HTMLMetaCharsetParser::processMeta()
{
+ const HTMLToken::AttributeList& tokenAttributes = m_token.attributes();
AttributeList attributes;
- for (auto& attribute : token.attributes()) {
- String attributeName = StringImpl::create8BitIfPossible(attribute.name);
- String attributeValue = StringImpl::create8BitIfPossible(attribute.value);
+ for (HTMLToken::AttributeList::const_iterator iter = tokenAttributes.begin(); iter != tokenAttributes.end(); ++iter) {
+ String attributeName = StringImpl::create8BitIfPossible(iter->name);
+ String attributeValue = StringImpl::create8BitIfPossible(iter->value);
attributes.append(std::make_pair(attributeName, attributeValue));
}
@@ -98,12 +116,12 @@ bool HTMLMetaCharsetParser::processMeta(HTMLToken& token)
TextEncoding HTMLMetaCharsetParser::encodingFromMetaAttributes(const AttributeList& attributes)
{
bool gotPragma = false;
- enum { None, Charset, Pragma } mode = None;
- StringView charset;
+ Mode mode = None;
+ String charset;
- for (auto& attribute : attributes) {
- const String& attributeName = attribute.first;
- const String& attributeValue = attribute.second;
+ for (AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
+ const AtomicString& attributeName = iter->first;
+ const String& attributeValue = iter->second;
if (attributeName == http_equivAttr) {
if (equalIgnoringCase(attributeValue, "content-type"))
@@ -121,11 +139,13 @@ TextEncoding HTMLMetaCharsetParser::encodingFromMetaAttributes(const AttributeLi
}
if (mode == Charset || (mode == Pragma && gotPragma))
- return TextEncoding(stripLeadingAndTrailingHTMLSpaces(charset.toStringWithoutCopying()));
+ return TextEncoding(stripLeadingAndTrailingHTMLSpaces(charset));
return TextEncoding();
}
+static const int bytesToCheckUnconditionally = 1024; // That many input bytes will be checked for meta charset even if <head> section is over.
+
bool HTMLMetaCharsetParser::checkForMetaCharset(const char* data, size_t length)
{
if (m_doneChecking)
@@ -136,32 +156,30 @@ bool HTMLMetaCharsetParser::checkForMetaCharset(const char* data, size_t length)
// We still don't have an encoding, and are in the head.
// The following tags are allowed in <head>:
// SCRIPT|STYLE|META|LINK|OBJECT|TITLE|BASE
- //
+
// We stop scanning when a tag that is not permitted in <head>
// is seen, rather when </head> is seen, because that more closely
// matches behavior in other browsers; more details in
// <http://bugs.webkit.org/show_bug.cgi?id=3590>.
- //
+
// Additionally, we ignore things that looks like tags in <title>, <script>
// and <noscript>; see <http://bugs.webkit.org/show_bug.cgi?id=4560>,
// <http://bugs.webkit.org/show_bug.cgi?id=12165> and
// <http://bugs.webkit.org/show_bug.cgi?id=12389>.
- //
+
// Since many sites have charset declarations after <body> or other tags
// that are disallowed in <head>, we don't bail out until we've checked at
// least bytesToCheckUnconditionally bytes of input.
- static const int bytesToCheckUnconditionally = 1024;
-
- m_input.append(SegmentedString(m_codec->decode(data, length)));
+ m_input.append(SegmentedString(m_assumedCodec->decode(data, length)));
- while (auto token = m_tokenizer.nextToken(m_input)) {
- bool isEnd = token->type() == HTMLToken::EndTag;
- if (isEnd || token->type() == HTMLToken::StartTag) {
- AtomicString tagName(token->name());
- if (!isEnd) {
- m_tokenizer.updateStateFor(tagName);
- if (tagName == metaTag && processMeta(*token)) {
+ while (m_tokenizer->nextToken(m_input, m_token)) {
+ bool end = m_token.type() == HTMLToken::EndTag;
+ if (end || m_token.type() == HTMLToken::StartTag) {
+ AtomicString tagName(m_token.name());
+ if (!end) {
+ m_tokenizer->updateStateFor(tagName);
+ if (tagName == metaTag && processMeta()) {
m_doneChecking = true;
return true;
}
@@ -171,8 +189,7 @@ bool HTMLMetaCharsetParser::checkForMetaCharset(const char* data, size_t length)
&& tagName != styleTag && tagName != linkTag
&& tagName != metaTag && tagName != objectTag
&& tagName != titleTag && tagName != baseTag
- && (isEnd || tagName != htmlTag)
- && (isEnd || tagName != headTag)) {
+ && (end || tagName != htmlTag) && (end || tagName != headTag)) {
m_inHeadSection = false;
}
}
@@ -181,6 +198,8 @@ bool HTMLMetaCharsetParser::checkForMetaCharset(const char* data, size_t length)
m_doneChecking = true;
return true;
}
+
+ m_token.clear();
}
return false;
diff --git a/Source/WebCore/html/parser/HTMLMetaCharsetParser.h b/Source/WebCore/html/parser/HTMLMetaCharsetParser.h
index 2c6d7c57e..618ce7ff6 100644
--- a/Source/WebCore/html/parser/HTMLMetaCharsetParser.h
+++ b/Source/WebCore/html/parser/HTMLMetaCharsetParser.h
@@ -26,36 +26,49 @@
#ifndef HTMLMetaCharsetParser_h
#define HTMLMetaCharsetParser_h
-#include "HTMLTokenizer.h"
+#include "HTMLToken.h"
#include "SegmentedString.h"
#include "TextEncoding.h"
+#include <wtf/Noncopyable.h>
namespace WebCore {
+class HTMLTokenizer;
class TextCodec;
class HTMLMetaCharsetParser {
WTF_MAKE_NONCOPYABLE(HTMLMetaCharsetParser); WTF_MAKE_FAST_ALLOCATED;
public:
HTMLMetaCharsetParser();
+ ~HTMLMetaCharsetParser();
// Returns true if done checking, regardless whether an encoding is found.
bool checkForMetaCharset(const char*, size_t);
const TextEncoding& encoding() { return m_encoding; }
- // The returned encoding might not be valid.
typedef Vector<std::pair<String, String>> AttributeList;
- static TextEncoding encodingFromMetaAttributes(const AttributeList&);
+ // The returned encoding might not be valid.
+ static TextEncoding encodingFromMetaAttributes(const AttributeList&
+);
private:
- bool processMeta(HTMLToken&);
+ bool processMeta();
+ static String extractCharset(const String&);
- HTMLTokenizer m_tokenizer;
- const std::unique_ptr<TextCodec> m_codec;
+ enum Mode {
+ None,
+ Charset,
+ Pragma,
+ };
+
+ std::unique_ptr<HTMLTokenizer> m_tokenizer;
+ OwnPtr<TextCodec> m_assumedCodec;
SegmentedString m_input;
- bool m_inHeadSection { true };
- bool m_doneChecking { false };
+ HTMLToken m_token;
+ bool m_inHeadSection;
+
+ bool m_doneChecking;
TextEncoding m_encoding;
};
diff --git a/Source/WebCore/html/parser/HTMLParserIdioms.cpp b/Source/WebCore/html/parser/HTMLParserIdioms.cpp
index 91a6606a9..43dd13ce4 100644
--- a/Source/WebCore/html/parser/HTMLParserIdioms.cpp
+++ b/Source/WebCore/html/parser/HTMLParserIdioms.cpp
@@ -71,7 +71,7 @@ String stripLeadingAndTrailingHTMLSpaces(const String& string)
if (string.is8Bit())
return stripLeadingAndTrailingHTMLSpaces(string, string.characters8(), length);
- return stripLeadingAndTrailingHTMLSpaces(string, string.characters16(), length);
+ return stripLeadingAndTrailingHTMLSpaces(string, string.deprecatedCharacters(), length);
}
String serializeForNumberType(const Decimal& number)
@@ -267,27 +267,161 @@ bool parseHTMLNonNegativeInteger(const String& input, unsigned& value)
// Step 1
// Step 2
unsigned length = input.length();
- if (!length || input.is8Bit()) {
+ if (length && input.is8Bit()) {
const LChar* start = input.characters8();
return parseHTMLNonNegativeIntegerInternal(start, start + length, value);
}
- const UChar* start = input.characters16();
+ const UChar* start = input.deprecatedCharacters();
return parseHTMLNonNegativeIntegerInternal(start, start + length, value);
}
-static bool threadSafeEqual(const StringImpl& a, const StringImpl& b)
+static bool threadSafeEqual(const StringImpl* a, const StringImpl* b)
{
- if (&a == &b)
+ if (a == b)
return true;
- if (a.hash() != b.hash())
+ if (a->hash() != b->hash())
return false;
- return equal(a, b);
+ return equalNonNull(a, b);
}
bool threadSafeMatch(const QualifiedName& a, const QualifiedName& b)
{
- return threadSafeEqual(*a.localName().impl(), *b.localName().impl());
+ return threadSafeEqual(a.localName().impl(), b.localName().impl());
+}
+
+struct ImageWithScale {
+ unsigned imageURLStart;
+ unsigned imageURLLength;
+ float scaleFactor;
+
+ ImageWithScale()
+ : imageURLStart(0)
+ , imageURLLength(0)
+ , scaleFactor(1)
+ {
+ }
+
+ bool hasImageURL() const
+ {
+ return imageURLLength;
+ }
+};
+typedef Vector<ImageWithScale> ImageCandidates;
+
+static inline bool compareByScaleFactor(const ImageWithScale& first, const ImageWithScale& second)
+{
+ return first.scaleFactor < second.scaleFactor;
+}
+
+static inline bool isHTMLSpaceOrComma(UChar character)
+{
+ return isHTMLSpace(character) || character == ',';
+}
+
+// See the specifications for more details about the algorithm to follow.
+// http://www.w3.org/TR/2013/WD-html-srcset-20130228/#processing-the-image-candidates.
+static void parseImagesWithScaleFromSrcsetAttribute(const String& srcsetAttribute, ImageCandidates& imageCandidates)
+{
+ ASSERT(imageCandidates.isEmpty());
+
+ size_t imageCandidateStart = 0;
+ unsigned srcsetAttributeLength = srcsetAttribute.length();
+
+ while (imageCandidateStart < srcsetAttributeLength) {
+ float imageScaleFactor = 1;
+ size_t separator;
+
+ // 4. Splitting loop: Skip whitespace.
+ size_t imageURLStart = srcsetAttribute.find(isNotHTMLSpace, imageCandidateStart);
+ if (imageURLStart == notFound)
+ break;
+ // If The current candidate is either totally empty or only contains space, skipping.
+ if (srcsetAttribute[imageURLStart] == ',') {
+ imageCandidateStart = imageURLStart + 1;
+ continue;
+ }
+ // 5. Collect a sequence of characters that are not space characters, and let that be url.
+ size_t imageURLEnd = srcsetAttribute.find(isHTMLSpace, imageURLStart + 1);
+ if (imageURLEnd == notFound) {
+ imageURLEnd = srcsetAttributeLength;
+ separator = srcsetAttributeLength;
+ } else if (srcsetAttribute[imageURLEnd - 1] == ',') {
+ --imageURLEnd;
+ separator = imageURLEnd;
+ } else {
+ // 7. Collect a sequence of characters that are not "," (U+002C) characters, and let that be descriptors.
+ size_t imageScaleStart = srcsetAttribute.find(isNotHTMLSpace, imageURLEnd + 1);
+ if (imageScaleStart == notFound)
+ separator = srcsetAttributeLength;
+ else if (srcsetAttribute[imageScaleStart] == ',')
+ separator = imageScaleStart;
+ else {
+ // This part differs from the spec as the current implementation only supports pixel density descriptors for now.
+ size_t imageScaleEnd = srcsetAttribute.find(isHTMLSpaceOrComma, imageScaleStart + 1);
+ imageScaleEnd = (imageScaleEnd == notFound) ? srcsetAttributeLength : imageScaleEnd;
+ size_t commaPosition = imageScaleEnd;
+ // Make sure there are no other descriptors.
+ while ((commaPosition < srcsetAttributeLength - 1) && isHTMLSpace(srcsetAttribute[commaPosition]))
+ ++commaPosition;
+ // If the first not html space character after the scale modifier is not a comma,
+ // the current candidate is an invalid input.
+ if ((commaPosition < srcsetAttributeLength - 1) && srcsetAttribute[commaPosition] != ',') {
+ // Find the nearest comma and skip the input.
+ commaPosition = srcsetAttribute.find(',', commaPosition + 1);
+ if (commaPosition == notFound)
+ break;
+ imageCandidateStart = commaPosition + 1;
+ continue;
+ }
+ separator = commaPosition;
+ if (srcsetAttribute[imageScaleEnd - 1] != 'x') {
+ imageCandidateStart = separator + 1;
+ continue;
+ }
+ bool validScaleFactor = false;
+ size_t scaleFactorLengthWithoutUnit = imageScaleEnd - imageScaleStart - 1;
+ imageScaleFactor = charactersToFloat(srcsetAttribute.deprecatedCharacters() + imageScaleStart, scaleFactorLengthWithoutUnit, &validScaleFactor);
+
+ if (!validScaleFactor) {
+ imageCandidateStart = separator + 1;
+ continue;
+ }
+ }
+ }
+ ImageWithScale image;
+ image.imageURLStart = imageURLStart;
+ image.imageURLLength = imageURLEnd - imageURLStart;
+ image.scaleFactor = imageScaleFactor;
+
+ imageCandidates.append(image);
+ // 11. Return to the step labeled splitting loop.
+ imageCandidateStart = separator + 1;
+ }
+}
+
+String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, const String& srcsetAttribute)
+{
+ ImageCandidates imageCandidates;
+
+ parseImagesWithScaleFromSrcsetAttribute(srcsetAttribute, imageCandidates);
+
+ if (!srcAttribute.isEmpty()) {
+ ImageWithScale srcPlaceholderImage;
+ imageCandidates.append(srcPlaceholderImage);
+ }
+
+ if (imageCandidates.isEmpty())
+ return String();
+
+ std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareByScaleFactor);
+
+ for (size_t i = 0; i < imageCandidates.size() - 1; ++i) {
+ if (imageCandidates[i].scaleFactor >= deviceScaleFactor)
+ return imageCandidates[i].hasImageURL() ? srcsetAttribute.substringSharingImpl(imageCandidates[i].imageURLStart, imageCandidates[i].imageURLLength) : srcAttribute;
+ }
+ const ImageWithScale& lastCandidate = imageCandidates.last();
+ return lastCandidate.hasImageURL() ? srcsetAttribute.substringSharingImpl(lastCandidate.imageURLStart, lastCandidate.imageURLLength) : srcAttribute;
}
}
diff --git a/Source/WebCore/html/parser/HTMLParserIdioms.h b/Source/WebCore/html/parser/HTMLParserIdioms.h
index 248d7d082..7c5914248 100644
--- a/Source/WebCore/html/parser/HTMLParserIdioms.h
+++ b/Source/WebCore/html/parser/HTMLParserIdioms.h
@@ -34,12 +34,18 @@ namespace WebCore {
class Decimal;
// Space characters as defined by the HTML specification.
+bool isHTMLSpace(UChar);
bool isHTMLLineBreak(UChar);
bool isNotHTMLSpace(UChar);
bool isHTMLSpaceButNotLineBreak(UChar character);
// Strip leading and trailing whitespace as defined by the HTML specification.
-WEBCORE_EXPORT String stripLeadingAndTrailingHTMLSpaces(const String&);
+String stripLeadingAndTrailingHTMLSpaces(const String&);
+template<size_t inlineCapacity>
+String stripLeadingAndTrailingHTMLSpaces(const Vector<UChar, inlineCapacity>& vector)
+{
+ return stripLeadingAndTrailingHTMLSpaces(StringImpl::create8BitIfPossible(vector));
+}
// An implementation of the HTML specification's algorithm to convert a number to a string for number and range types.
String serializeForNumberType(const Decimal&);
@@ -60,8 +66,8 @@ bool parseHTMLInteger(const String&, int&);
bool parseHTMLNonNegativeInteger(const String&, unsigned int&);
// Inline implementations of some of the functions declared above.
-template<typename CharType>
-inline bool isHTMLSpace(CharType character)
+
+inline bool isHTMLSpace(UChar character)
{
// Histogram from Apple's page load test combined with some ad hoc browsing some other test suites.
//
@@ -81,18 +87,6 @@ inline bool isHTMLLineBreak(UChar character)
return character <= '\r' && (character == '\n' || character == '\r');
}
-template<typename CharType>
-inline bool isComma(CharType character)
-{
- return character == ',';
-}
-
-template<typename CharType>
-inline bool isHTMLSpaceOrComma(CharType character)
-{
- return isComma(character) || isHTMLSpace<CharType>(character);
-}
-
inline bool isNotHTMLSpace(UChar character)
{
return !isHTMLSpace(character);
@@ -105,6 +99,8 @@ inline bool isHTMLSpaceButNotLineBreak(UChar character)
bool threadSafeMatch(const QualifiedName&, const QualifiedName&);
+String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, const String& sourceSetAttribute);
+
}
#endif
diff --git a/Source/WebCore/html/parser/HTMLParserOptions.cpp b/Source/WebCore/html/parser/HTMLParserOptions.cpp
index d9323ee4c..000d4b02b 100644
--- a/Source/WebCore/html/parser/HTMLParserOptions.cpp
+++ b/Source/WebCore/html/parser/HTMLParserOptions.cpp
@@ -47,7 +47,7 @@ HTMLParserOptions::HTMLParserOptions(Document& document)
{
Frame* frame = document.frame();
scriptEnabled = frame && frame->script().canExecuteScripts(NotAboutToExecuteScript);
- pluginsEnabled = frame && frame->loader().subframeLoader().allowPlugins();
+ pluginsEnabled = frame && frame->loader().subframeLoader().allowPlugins(NotAboutToInstantiatePlugin);
Settings* settings = document.settings();
usePreHTML5ParserQuirks = settings && settings->usePreHTML5ParserQuirks();
diff --git a/Source/WebCore/html/parser/HTMLParserScheduler.cpp b/Source/WebCore/html/parser/HTMLParserScheduler.cpp
index 0e42fdef0..974fcbec9 100644
--- a/Source/WebCore/html/parser/HTMLParserScheduler.cpp
+++ b/Source/WebCore/html/parser/HTMLParserScheduler.cpp
@@ -52,6 +52,16 @@ static double parserTimeLimit(Page* page)
return defaultParserTimeLimit;
}
+static int parserChunkSize(Page* page)
+{
+ // FIXME: We may need to divide the value from customHTMLTokenizerChunkSize
+ // by some constant to translate from the "character" based behavior of the
+ // old LegacyHTMLDocumentParser to the token-based behavior of this parser.
+ if (page && page->hasCustomHTMLTokenizerChunkSize())
+ return page->customHTMLTokenizerChunkSize();
+ return defaultParserChunkSize;
+}
+
ActiveParserSession::ActiveParserSession(Document* document)
: m_document(document)
{
@@ -87,8 +97,8 @@ PumpSession::~PumpSession()
HTMLParserScheduler::HTMLParserScheduler(HTMLDocumentParser& parser)
: m_parser(parser)
, m_parserTimeLimit(parserTimeLimit(m_parser.document()->page()))
- , m_parserChunkSize(defaultParserChunkSize)
- , m_continueNextChunkTimer(*this, &HTMLParserScheduler::continueNextChunkTimerFired)
+ , m_parserChunkSize(parserChunkSize(m_parser.document()->page()))
+ , m_continueNextChunkTimer(this, &HTMLParserScheduler::continueNextChunkTimerFired)
, m_isSuspendedWithActiveTimer(false)
#if !ASSERT_DISABLED
, m_suspended(false)
@@ -101,9 +111,10 @@ HTMLParserScheduler::~HTMLParserScheduler()
m_continueNextChunkTimer.stop();
}
-void HTMLParserScheduler::continueNextChunkTimerFired()
+void HTMLParserScheduler::continueNextChunkTimerFired(Timer<HTMLParserScheduler>& timer)
{
ASSERT(!m_suspended);
+ ASSERT_UNUSED(timer, &timer == &m_continueNextChunkTimer);
// FIXME: The timer class should handle timer priorities instead of this code.
// If a layout is scheduled, wait again to let the layout timer run first.
diff --git a/Source/WebCore/html/parser/HTMLParserScheduler.h b/Source/WebCore/html/parser/HTMLParserScheduler.h
index 8bfdcc0ca..862bb62a4 100644
--- a/Source/WebCore/html/parser/HTMLParserScheduler.h
+++ b/Source/WebCore/html/parser/HTMLParserScheduler.h
@@ -29,6 +29,7 @@
#include "NestingLevelIncrementer.h"
#include "Timer.h"
#include <wtf/CurrentTime.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/RefPtr.h>
#if PLATFORM(IOS)
@@ -97,13 +98,13 @@ public:
void resume();
private:
- void continueNextChunkTimerFired();
+ void continueNextChunkTimerFired(Timer<HTMLParserScheduler>&);
HTMLDocumentParser& m_parser;
double m_parserTimeLimit;
int m_parserChunkSize;
- Timer m_continueNextChunkTimer;
+ Timer<HTMLParserScheduler> m_continueNextChunkTimer;
bool m_isSuspendedWithActiveTimer;
#if !ASSERT_DISABLED
bool m_suspended;
diff --git a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
index 1736675e8..51c81e189 100644
--- a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
+++ b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
@@ -30,11 +30,9 @@
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
-#include "HTMLSrcsetParser.h"
#include "HTMLTokenizer.h"
#include "InputTypeNames.h"
#include "LinkRelAttribute.h"
-#include "SourceSizeList.h"
#include <wtf/MainThread.h>
namespace WebCore {
@@ -58,8 +56,6 @@ TokenPreloadScanner::TagId TokenPreloadScanner::tagIdFor(const HTMLToken::DataVe
return TagId::Base;
if (tagName == templateTag)
return TagId::Template;
- if (tagName == metaTag)
- return TagId::Meta;
return TagId::Unknown;
}
@@ -78,7 +74,6 @@ String TokenPreloadScanner::initiatorFor(TagId tagId)
case TagId::Style:
case TagId::Base:
case TagId::Template:
- case TagId::Meta:
ASSERT_NOT_REACHED();
return "unknown";
}
@@ -91,34 +86,27 @@ public:
explicit StartTagScanner(TagId tagId, float deviceScaleFactor = 1.0)
: m_tagId(tagId)
, m_linkIsStyleSheet(false)
- , m_metaIsViewport(false)
, m_inputIsImage(false)
, m_deviceScaleFactor(deviceScaleFactor)
{
}
- void processAttributes(const HTMLToken::AttributeList& attributes, Document& document)
+ void processAttributes(const HTMLToken::AttributeList& attributes)
{
ASSERT(isMainThread());
if (m_tagId >= TagId::Unknown)
return;
-
for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
AtomicString attributeName(iter->name);
String attributeValue = StringImpl::create8BitIfPossible(iter->value);
processAttribute(attributeName, attributeValue);
}
- // Resolve between src and srcSet if we have them and the tag is img.
- if (m_tagId == TagId::Img && !m_srcSetAttribute.isEmpty()) {
- float sourceSize = 0;
- sourceSize = parseSizesAttribute(m_sizesAttribute, document.renderView(), document.frame());
- ImageCandidate imageCandidate = bestFitSourceForImageAttributes(m_deviceScaleFactor, m_urlToLoad, m_srcSetAttribute, sourceSize);
- setUrlToLoad(imageCandidate.string.toString(), true);
+ // Resolve between src and srcSet if we have them.
+ if (!m_srcSetAttribute.isEmpty()) {
+ String srcMatchingScale = bestFitSourceForImageAttributes(m_deviceScaleFactor, m_urlToLoad, m_srcSetAttribute);
+ setUrlToLoad(srcMatchingScale, true);
}
-
- if (m_metaIsViewport && !m_metaContent.isNull())
- document.processViewport(m_metaContent, ViewportArguments::ViewportMeta);
}
std::unique_ptr<PreloadRequest> createPreloadRequest(const URL& predictedBaseURL)
@@ -140,67 +128,38 @@ public:
}
private:
- void processImageAndScriptAttribute(const AtomicString& attributeName, const String& attributeValue)
+ template<typename NameType>
+ void processAttribute(const NameType& attributeName, const String& attributeValue)
{
- if (match(attributeName, srcAttr))
- setUrlToLoad(attributeValue);
- else if (match(attributeName, crossoriginAttr) && !attributeValue.isNull())
- m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeValue);
- else if (match(attributeName, charsetAttr))
+ if (match(attributeName, charsetAttr))
m_charset = attributeValue;
- }
- void processAttribute(const AtomicString& attributeName, const String& attributeValue)
- {
- switch (m_tagId) {
- case TagId::Img:
- if (match(attributeName, srcsetAttr) && m_srcSetAttribute.isNull()) {
+ if (m_tagId == TagId::Script || m_tagId == TagId::Img) {
+ if (match(attributeName, srcAttr))
+ setUrlToLoad(attributeValue);
+ else if (match(attributeName, srcsetAttr))
m_srcSetAttribute = attributeValue;
- break;
- }
- if (match(attributeName, sizesAttr) && m_sizesAttribute.isNull()) {
- m_sizesAttribute = attributeValue;
- break;
- }
- processImageAndScriptAttribute(attributeName, attributeValue);
- break;
- case TagId::Script:
- processImageAndScriptAttribute(attributeName, attributeValue);
- break;
- case TagId::Link:
+ else if (match(attributeName, crossoriginAttr) && !attributeValue.isNull())
+ m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeValue);
+ } else if (m_tagId == TagId::Link) {
if (match(attributeName, hrefAttr))
setUrlToLoad(attributeValue);
else if (match(attributeName, relAttr))
m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue);
else if (match(attributeName, mediaAttr))
m_mediaAttribute = attributeValue;
- else if (match(attributeName, charsetAttr))
- m_charset = attributeValue;
- break;
- case TagId::Input:
+ } else if (m_tagId == TagId::Input) {
if (match(attributeName, srcAttr))
setUrlToLoad(attributeValue);
else if (match(attributeName, typeAttr))
m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image());
- break;
- case TagId::Meta:
- if (match(attributeName, contentAttr))
- m_metaContent = attributeValue;
- else if (match(attributeName, nameAttr))
- m_metaIsViewport = equalIgnoringCase(attributeValue, "viewport");
- break;
- case TagId::Base:
- case TagId::Style:
- case TagId::Template:
- case TagId::Unknown:
- break;
}
}
static bool relAttributeIsStyleSheet(const String& attributeValue)
{
- LinkRelAttribute parsedAttribute { attributeValue };
- return parsedAttribute.isStyleSheet && !parsedAttribute.isAlternate && parsedAttribute.iconType == InvalidIcon && !parsedAttribute.isDNSPrefetch;
+ LinkRelAttribute rel(attributeValue);
+ return rel.m_isStyleSheet && !rel.m_isAlternate && rel.m_iconType == InvalidIcon && !rel.m_isDNSPrefetch;
}
void setUrlToLoad(const String& value, bool allowReplacement = false)
@@ -217,6 +176,9 @@ private:
const String& charset() const
{
+ // FIXME: Its not clear that this if is needed, the loader probably ignores charset for image requests anyway.
+ if (m_tagId == TagId::Img)
+ return emptyString();
return m_charset;
}
@@ -237,9 +199,6 @@ private:
if (m_urlToLoad.isEmpty())
return false;
- if (protocolIs(m_urlToLoad, "data"))
- return false;
-
if (m_tagId == TagId::Link && !m_linkIsStyleSheet)
return false;
@@ -257,34 +216,63 @@ private:
TagId m_tagId;
String m_urlToLoad;
String m_srcSetAttribute;
- String m_sizesAttribute;
String m_charset;
String m_crossOriginMode;
bool m_linkIsStyleSheet;
String m_mediaAttribute;
- String m_metaContent;
- bool m_metaIsViewport;
bool m_inputIsImage;
float m_deviceScaleFactor;
};
TokenPreloadScanner::TokenPreloadScanner(const URL& documentURL, float deviceScaleFactor)
: m_documentURL(documentURL)
+ , m_inStyle(false)
, m_deviceScaleFactor(deviceScaleFactor)
+#if ENABLE(TEMPLATE_ELEMENT)
+ , m_templateCount(0)
+#endif
+{
+}
+
+TokenPreloadScanner::~TokenPreloadScanner()
+{
+}
+
+TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint()
+{
+ TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size();
+ m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle
+#if ENABLE(TEMPLATE_ELEMENT)
+ , m_templateCount
+#endif
+ ));
+ return checkpoint;
+}
+
+void TokenPreloadScanner::rewindTo(TokenPreloadScannerCheckpoint checkpointIndex)
{
+ ASSERT(checkpointIndex < m_checkpoints.size()); // If this ASSERT fires, checkpointIndex is invalid.
+ const Checkpoint& checkpoint = m_checkpoints[checkpointIndex];
+ m_predictedBaseElementURL = checkpoint.predictedBaseElementURL;
+ m_inStyle = checkpoint.inStyle;
+#if ENABLE(TEMPLATE_ELEMENT)
+ m_templateCount = checkpoint.templateCount;
+#endif
+ m_cssScanner.reset();
+ m_checkpoints.clear();
}
-void TokenPreloadScanner::scan(const HTMLToken& token, Vector<std::unique_ptr<PreloadRequest>>& requests, Document& document)
+void TokenPreloadScanner::scan(const HTMLToken& token, Vector<std::unique_ptr<PreloadRequest>>& requests)
{
switch (token.type()) {
case HTMLToken::Character:
if (!m_inStyle)
return;
- m_cssScanner.scan(token.characters(), requests);
+ m_cssScanner.scan(token.data(), requests);
return;
case HTMLToken::EndTag: {
- TagId tagId = tagIdFor(token.name());
+ TagId tagId = tagIdFor(token.data());
#if ENABLE(TEMPLATE_ELEMENT)
if (tagId == TagId::Template) {
if (m_templateCount)
@@ -305,7 +293,7 @@ void TokenPreloadScanner::scan(const HTMLToken& token, Vector<std::unique_ptr<Pr
if (m_templateCount)
return;
#endif
- TagId tagId = tagIdFor(token.name());
+ TagId tagId = tagIdFor(token.data());
#if ENABLE(TEMPLATE_ELEMENT)
if (tagId == TagId::Template) {
++m_templateCount;
@@ -325,9 +313,9 @@ void TokenPreloadScanner::scan(const HTMLToken& token, Vector<std::unique_ptr<Pr
}
StartTagScanner scanner(tagId, m_deviceScaleFactor);
- scanner.processAttributes(token.attributes(), document);
+ scanner.processAttributes(token.attributes());
if (auto request = scanner.createPreloadRequest(m_predictedBaseElementURL))
- requests.append(WTF::move(request));
+ requests.append(std::move(request));
return;
}
@@ -336,16 +324,21 @@ void TokenPreloadScanner::scan(const HTMLToken& token, Vector<std::unique_ptr<Pr
}
}
-void TokenPreloadScanner::updatePredictedBaseURL(const HTMLToken& token)
+template<typename Token>
+void TokenPreloadScanner::updatePredictedBaseURL(const Token& token)
{
ASSERT(m_predictedBaseElementURL.isEmpty());
- if (auto* hrefAttribute = findAttribute(token.attributes(), hrefAttr.localName().string()))
- m_predictedBaseElementURL = URL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(StringImpl::create8BitIfPossible(hrefAttribute->value))).isolatedCopy();
+ if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem(hrefAttr))
+ m_predictedBaseElementURL = URL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(hrefAttribute->value)).copy();
}
HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const URL& documentURL, float deviceScaleFactor)
: m_scanner(documentURL, deviceScaleFactor)
- , m_tokenizer(options)
+ , m_tokenizer(std::make_unique<HTMLTokenizer>(options))
+{
+}
+
+HTMLPreloadScanner::~HTMLPreloadScanner()
{
}
@@ -354,36 +347,24 @@ void HTMLPreloadScanner::appendToEnd(const SegmentedString& source)
m_source.append(source);
}
-void HTMLPreloadScanner::scan(HTMLResourcePreloader& preloader, Document& document)
+void HTMLPreloadScanner::scan(HTMLResourcePreloader* preloader, const URL& startingBaseElementURL)
{
ASSERT(isMainThread()); // HTMLTokenizer::updateStateFor only works on the main thread.
- const URL& startingBaseElementURL = document.baseElementURL();
-
// When we start scanning, our best prediction of the baseElementURL is the real one!
if (!startingBaseElementURL.isEmpty())
m_scanner.setPredictedBaseElementURL(startingBaseElementURL);
PreloadRequestStream requests;
- while (auto token = m_tokenizer.nextToken(m_source)) {
- if (token->type() == HTMLToken::StartTag)
- m_tokenizer.updateStateFor(AtomicString(token->name()));
- m_scanner.scan(*token, requests, document);
+ while (m_tokenizer->nextToken(m_source, m_token)) {
+ if (m_token.type() == HTMLToken::StartTag)
+ m_tokenizer->updateStateFor(AtomicString(m_token.name()));
+ m_scanner.scan(m_token, requests);
+ m_token.clear();
}
- preloader.preload(WTF::move(requests));
-}
-
-bool testPreloadScannerViewportSupport(Document* document)
-{
- ASSERT(document);
- HTMLParserOptions options(*document);
- HTMLPreloadScanner scanner(options, document->url());
- HTMLResourcePreloader preloader(*document);
- scanner.appendToEnd(String("<meta name=viewport content='width=400'>"));
- scanner.scan(preloader, *document);
- return (document->viewportArguments().width == 400);
+ preloader->preload(std::move(requests));
}
}
diff --git a/Source/WebCore/html/parser/HTMLPreloadScanner.h b/Source/WebCore/html/parser/HTMLPreloadScanner.h
index b51a2d343..963c6b92e 100644
--- a/Source/WebCore/html/parser/HTMLPreloadScanner.h
+++ b/Source/WebCore/html/parser/HTMLPreloadScanner.h
@@ -28,20 +28,39 @@
#define HTMLPreloadScanner_h
#include "CSSPreloadScanner.h"
-#include "HTMLTokenizer.h"
+#include "HTMLToken.h"
#include "SegmentedString.h"
+#include <wtf/Vector.h>
namespace WebCore {
+typedef size_t TokenPreloadScannerCheckpoint;
+
+class HTMLParserOptions;
+class HTMLTokenizer;
+class SegmentedString;
+
class TokenPreloadScanner {
- WTF_MAKE_NONCOPYABLE(TokenPreloadScanner);
+ WTF_MAKE_NONCOPYABLE(TokenPreloadScanner); WTF_MAKE_FAST_ALLOCATED;
public:
explicit TokenPreloadScanner(const URL& documentURL, float deviceScaleFactor = 1.0);
+ ~TokenPreloadScanner();
- void scan(const HTMLToken&, PreloadRequestStream&, Document&);
+ void scan(const HTMLToken&, PreloadRequestStream& requests);
void setPredictedBaseElementURL(const URL& url) { m_predictedBaseElementURL = url; }
+ // A TokenPreloadScannerCheckpoint is valid until the next call to rewindTo,
+ // at which point all outstanding checkpoints are invalidated.
+ TokenPreloadScannerCheckpoint createCheckpoint();
+ void rewindTo(TokenPreloadScannerCheckpoint);
+
+ bool isSafeToSendToAnotherThread()
+ {
+ return m_documentURL.isSafeToSendToAnotherThread()
+ && m_predictedBaseElementURL.isSafeToSendToAnotherThread();
+ }
+
private:
enum class TagId {
// These tags are scanned by the StartTagScanner.
@@ -49,7 +68,6 @@ private:
Input,
Link,
Script,
- Meta,
// These tags are not scanned by the StartTagScanner.
Unknown,
@@ -64,35 +82,59 @@ private:
static String initiatorFor(TagId);
- void updatePredictedBaseURL(const HTMLToken&);
+ template<typename Token>
+ void updatePredictedBaseURL(const Token&);
+
+ struct Checkpoint {
+ Checkpoint(const URL& predictedBaseElementURL, bool inStyle
+#if ENABLE(TEMPLATE_ELEMENT)
+ , size_t templateCount
+#endif
+ )
+ : predictedBaseElementURL(predictedBaseElementURL)
+ , inStyle(inStyle)
+#if ENABLE(TEMPLATE_ELEMENT)
+ , templateCount(templateCount)
+#endif
+ {
+ }
+
+ URL predictedBaseElementURL;
+ bool inStyle;
+#if ENABLE(TEMPLATE_ELEMENT)
+ size_t templateCount;
+#endif
+ };
CSSPreloadScanner m_cssScanner;
const URL m_documentURL;
- const float m_deviceScaleFactor { 1 };
-
URL m_predictedBaseElementURL;
- bool m_inStyle { false };
+ bool m_inStyle;
+ float m_deviceScaleFactor;
+
#if ENABLE(TEMPLATE_ELEMENT)
- unsigned m_templateCount { 0 };
+ size_t m_templateCount;
#endif
+
+ Vector<Checkpoint> m_checkpoints;
};
class HTMLPreloadScanner {
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_NONCOPYABLE(HTMLPreloadScanner); WTF_MAKE_FAST_ALLOCATED;
public:
HTMLPreloadScanner(const HTMLParserOptions&, const URL& documentURL, float deviceScaleFactor = 1.0);
+ ~HTMLPreloadScanner();
void appendToEnd(const SegmentedString&);
- void scan(HTMLResourcePreloader&, Document&);
+ void scan(HTMLResourcePreloader*, const URL& documentBaseElementURL);
private:
TokenPreloadScanner m_scanner;
SegmentedString m_source;
- HTMLTokenizer m_tokenizer;
+ HTMLToken m_token;
+ std::unique_ptr<HTMLTokenizer> m_tokenizer;
};
-WEBCORE_EXPORT bool testPreloadScannerViewportSupport(Document*);
-
}
#endif
diff --git a/Source/WebCore/html/parser/HTMLResourcePreloader.cpp b/Source/WebCore/html/parser/HTMLResourcePreloader.cpp
index 5e79d4c11..cfd2342b2 100644
--- a/Source/WebCore/html/parser/HTMLResourcePreloader.cpp
+++ b/Source/WebCore/html/parser/HTMLResourcePreloader.cpp
@@ -35,6 +35,15 @@
namespace WebCore {
+bool PreloadRequest::isSafeToSendToAnotherThread() const
+{
+ return m_initiator.isSafeToSendToAnotherThread()
+ && m_charset.isSafeToSendToAnotherThread()
+ && m_resourceURL.isSafeToSendToAnotherThread()
+ && m_mediaAttribute.isSafeToSendToAnotherThread()
+ && m_baseURL.isSafeToSendToAnotherThread();
+}
+
URL PreloadRequest::completeURL(Document& document)
{
return document.completeURL(m_resourceURL, m_baseURL.isEmpty() ? document.url() : m_baseURL);
@@ -55,7 +64,7 @@ CachedResourceRequest PreloadRequest::resourceRequest(Document& document)
void HTMLResourcePreloader::preload(PreloadRequestStream requests)
{
for (auto& request : requests)
- preload(WTF::move(request));
+ preload(std::move(request));
}
static bool mediaAttributeMatches(Frame* frame, RenderStyle* renderStyle, const String& attributeValue)
@@ -73,7 +82,7 @@ void HTMLResourcePreloader::preload(std::unique_ptr<PreloadRequest> preload)
return;
CachedResourceRequest request = preload->resourceRequest(m_document);
- m_document.cachedResourceLoader().preload(preload->resourceType(), request, preload->charset());
+ m_document.cachedResourceLoader()->preload(preload->resourceType(), request, preload->charset());
}
diff --git a/Source/WebCore/html/parser/HTMLResourcePreloader.h b/Source/WebCore/html/parser/HTMLResourcePreloader.h
index bc2f4fa65..f93a093bd 100644
--- a/Source/WebCore/html/parser/HTMLResourcePreloader.h
+++ b/Source/WebCore/html/parser/HTMLResourcePreloader.h
@@ -32,18 +32,19 @@
namespace WebCore {
class PreloadRequest {
- WTF_MAKE_FAST_ALLOCATED;
public:
PreloadRequest(const String& initiator, const String& resourceURL, const URL& baseURL, CachedResource::Type resourceType, const String& mediaAttribute)
: m_initiator(initiator)
- , m_resourceURL(resourceURL)
- , m_baseURL(baseURL.isolatedCopy())
+ , m_resourceURL(resourceURL.isolatedCopy())
+ , m_baseURL(baseURL.copy())
, m_resourceType(resourceType)
- , m_mediaAttribute(mediaAttribute)
+ , m_mediaAttribute(mediaAttribute.isolatedCopy())
, m_crossOriginModeAllowsCookies(false)
{
}
+ bool isSafeToSendToAnotherThread() const;
+
CachedResourceRequest resourceRequest(Document&);
const String& charset() const { return m_charset; }
diff --git a/Source/WebCore/html/parser/HTMLScriptRunner.cpp b/Source/WebCore/html/parser/HTMLScriptRunner.cpp
index eea0ec757..41e725f60 100644
--- a/Source/WebCore/html/parser/HTMLScriptRunner.cpp
+++ b/Source/WebCore/html/parser/HTMLScriptRunner.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "HTMLScriptRunner.h"
+#include "Attribute.h"
#include "CachedScript.h"
#include "CachedResourceLoader.h"
#include "Element.h"
@@ -35,7 +36,6 @@
#include "HTMLNames.h"
#include "HTMLScriptRunnerHost.h"
#include "IgnoreDestructiveWriteCountIncrementer.h"
-#include "MicroTask.h"
#include "MutationObserver.h"
#include "NestingLevelIncrementer.h"
#include "NotImplemented.h"
@@ -129,10 +129,8 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
if (pendingScript.cachedScript() && pendingScript.watchingForLoad())
stopWatchingForLoad(pendingScript);
- if (!isExecutingScript()) {
+ if (!isExecutingScript())
MutationObserver::deliverAllMutations();
- MicroTaskQueue::singleton().runMicroTasks();
- }
// Clear the pending script before possible rentrancy from executeScript()
RefPtr<Element> element = pendingScript.releaseElementAndClear();
@@ -233,8 +231,6 @@ bool HTMLScriptRunner::executeScriptsWaitingForParsing()
if (!m_document)
return false;
}
- if (!isExecutingScript())
- MicroTaskQueue::singleton().runMicroTasks();
return true;
}
@@ -297,10 +293,8 @@ void HTMLScriptRunner::runScript(Element* script, const TextPosition& scriptStar
// every script element, even if it's not ready to execute yet. There's
// unfortuantely no obvious way to tell if prepareScript is going to
// execute the script from out here.
- if (!isExecutingScript()) {
+ if (!isExecutingScript())
MutationObserver::deliverAllMutations();
- MicroTaskQueue::singleton().runMicroTasks();
- }
InsertionPointRecord insertionPointRecord(m_host.inputStream());
NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);
diff --git a/Source/WebCore/html/parser/HTMLSourceTracker.cpp b/Source/WebCore/html/parser/HTMLSourceTracker.cpp
index 0c9a04632..bf1a8c466 100644
--- a/Source/WebCore/html/parser/HTMLSourceTracker.cpp
+++ b/Source/WebCore/html/parser/HTMLSourceTracker.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2010 Adam Barth. All Rights Reserved.
- * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,7 +25,6 @@
#include "config.h"
#include "HTMLSourceTracker.h"
-
#include "HTMLTokenizer.h"
#include <wtf/text/StringBuilder.h>
@@ -36,46 +34,42 @@ HTMLSourceTracker::HTMLSourceTracker()
{
}
-void HTMLSourceTracker::startToken(SegmentedString& currentInput, HTMLTokenizer& tokenizer)
+void HTMLSourceTracker::start(SegmentedString& currentInput, HTMLTokenizer* tokenizer, HTMLToken& token)
{
- if (!m_started) {
- if (tokenizer.numberOfBufferedCharacters())
- m_previousSource = tokenizer.bufferedCharacters();
- else
- m_previousSource.clear();
- m_started = true;
+ if (token.type() == HTMLToken::Uninitialized) {
+ m_previousSource.clear();
+ if (tokenizer->numberOfBufferedCharacters())
+ m_previousSource = tokenizer->bufferedCharacters();
} else
m_previousSource.append(m_currentSource);
m_currentSource = currentInput;
- m_tokenStart = m_currentSource.numberOfCharactersConsumed() - m_previousSource.length();
+ token.setBaseOffset(m_currentSource.numberOfCharactersConsumed() - m_previousSource.length());
}
-void HTMLSourceTracker::endToken(SegmentedString& currentInput, HTMLTokenizer& tokenizer)
+void HTMLSourceTracker::end(SegmentedString& currentInput, HTMLTokenizer* tokenizer, HTMLToken& token)
{
- ASSERT(m_started);
- m_started = false;
-
- m_tokenEnd = currentInput.numberOfCharactersConsumed() - tokenizer.numberOfBufferedCharacters();
m_cachedSourceForToken = String();
+
+ // FIXME: This work should really be done by the HTMLTokenizer.
+ token.end(currentInput.numberOfCharactersConsumed() - tokenizer->numberOfBufferedCharacters());
}
-String HTMLSourceTracker::source(const HTMLToken& token)
+String HTMLSourceTracker::sourceForToken(const HTMLToken& token)
{
- ASSERT(!m_started);
-
if (token.type() == HTMLToken::EndOfFile)
return String(); // Hides the null character we use to mark the end of file.
if (!m_cachedSourceForToken.isEmpty())
return m_cachedSourceForToken;
- unsigned length = m_tokenEnd - m_tokenStart;
+ ASSERT(!token.startIndex());
+ size_t length = static_cast<size_t>(token.endIndex() - token.startIndex());
StringBuilder source;
source.reserveCapacity(length);
- unsigned i = 0;
+ size_t i = 0;
for ( ; i < length && !m_previousSource.isEmpty(); ++i) {
source.append(m_previousSource.currentChar());
m_previousSource.advance();
@@ -90,9 +84,4 @@ String HTMLSourceTracker::source(const HTMLToken& token)
return m_cachedSourceForToken;
}
-String HTMLSourceTracker::source(const HTMLToken& token, unsigned attributeStart, unsigned attributeEnd)
-{
- return source(token).substring(attributeStart - m_tokenStart, attributeEnd - attributeStart);
-}
-
}
diff --git a/Source/WebCore/html/parser/HTMLSourceTracker.h b/Source/WebCore/html/parser/HTMLSourceTracker.h
index 3601e25db..7f0378b8f 100644
--- a/Source/WebCore/html/parser/HTMLSourceTracker.h
+++ b/Source/WebCore/html/parser/HTMLSourceTracker.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2010 Adam Barth. All Rights Reserved.
- * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,11 +26,11 @@
#ifndef HTMLSourceTracker_h
#define HTMLSourceTracker_h
+#include "HTMLToken.h"
#include "SegmentedString.h"
namespace WebCore {
-class HTMLToken;
class HTMLTokenizer;
class HTMLSourceTracker {
@@ -39,18 +38,15 @@ class HTMLSourceTracker {
public:
HTMLSourceTracker();
- void startToken(SegmentedString&, HTMLTokenizer&);
- void endToken(SegmentedString&, HTMLTokenizer&);
+ // FIXME: Once we move "end" into HTMLTokenizer, rename "start" to
+ // something that makes it obvious that this method can be called multiple
+ // times.
+ void start(SegmentedString&, HTMLTokenizer*, HTMLToken&);
+ void end(SegmentedString&, HTMLTokenizer*, HTMLToken&);
- String source(const HTMLToken&);
- String source(const HTMLToken&, unsigned attributeStart, unsigned attributeEnd);
+ String sourceForToken(const HTMLToken&);
private:
- bool m_started { false };
-
- unsigned m_tokenStart;
- unsigned m_tokenEnd;
-
SegmentedString m_previousSource;
SegmentedString m_currentSource;
diff --git a/Source/WebCore/html/parser/HTMLSrcsetParser.cpp b/Source/WebCore/html/parser/HTMLSrcsetParser.cpp
deleted file mode 100644
index cb0c8f9c3..000000000
--- a/Source/WebCore/html/parser/HTMLSrcsetParser.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "HTMLSrcsetParser.h"
-
-#include "HTMLParserIdioms.h"
-#include "ParsingUtilities.h"
-
-namespace WebCore {
-
-static inline bool compareByDensity(const ImageCandidate& first, const ImageCandidate& second)
-{
- return first.density < second.density;
-}
-
-enum DescriptorTokenizerState {
- Start,
- InParenthesis,
- AfterToken,
-};
-
-template<typename CharType>
-static void appendDescriptorAndReset(const CharType*& descriptorStart, const CharType* position, Vector<StringView>& descriptors)
-{
- if (position > descriptorStart)
- descriptors.append(StringView(descriptorStart, position - descriptorStart));
- descriptorStart = nullptr;
-}
-
-// The following is called appendCharacter to match the spec's terminology.
-template<typename CharType>
-static void appendCharacter(const CharType* descriptorStart, const CharType* position)
-{
- // Since we don't copy the tokens, this just set the point where the descriptor tokens start.
- if (!descriptorStart)
- descriptorStart = position;
-}
-
-template<typename CharType>
-static bool isEOF(const CharType* position, const CharType* end)
-{
- return position >= end;
-}
-
-template<typename CharType>
-static void tokenizeDescriptors(const CharType*& position, const CharType* attributeEnd, Vector<StringView>& descriptors)
-{
- DescriptorTokenizerState state = Start;
- const CharType* descriptorsStart = position;
- const CharType* currentDescriptorStart = descriptorsStart;
- for (; ; ++position) {
- switch (state) {
- case Start:
- if (isEOF(position, attributeEnd)) {
- appendDescriptorAndReset(currentDescriptorStart, attributeEnd, descriptors);
- return;
- }
- if (isComma(*position)) {
- appendDescriptorAndReset(currentDescriptorStart, position, descriptors);
- ++position;
- return;
- }
- if (isHTMLSpace(*position)) {
- appendDescriptorAndReset(currentDescriptorStart, position, descriptors);
- currentDescriptorStart = position + 1;
- state = AfterToken;
- } else if (*position == '(') {
- appendCharacter(currentDescriptorStart, position);
- state = InParenthesis;
- } else
- appendCharacter(currentDescriptorStart, position);
- break;
- case InParenthesis:
- if (isEOF(position, attributeEnd)) {
- appendDescriptorAndReset(currentDescriptorStart, attributeEnd, descriptors);
- return;
- }
- if (*position == ')') {
- appendCharacter(currentDescriptorStart, position);
- state = Start;
- } else
- appendCharacter(currentDescriptorStart, position);
- break;
- case AfterToken:
- if (isEOF(position, attributeEnd))
- return;
- if (!isHTMLSpace(*position)) {
- state = Start;
- currentDescriptorStart = position;
- --position;
- }
- break;
- }
- }
-}
-
-static bool parseDescriptors(Vector<StringView>& descriptors, DescriptorParsingResult& result)
-{
- for (auto& descriptor : descriptors) {
- if (descriptor.isEmpty())
- continue;
- unsigned descriptorCharPosition = descriptor.length() - 1;
- UChar descriptorChar = descriptor[descriptorCharPosition];
- descriptor = descriptor.substring(0, descriptorCharPosition);
- bool isValid = false;
- if (descriptorChar == 'x') {
- if (result.hasDensity() || result.hasHeight() || result.hasWidth())
- return false;
- float density = descriptor.toFloat(isValid);
- if (!isValid || density < 0)
- return false;
- result.setDensity(density);
- } else if (descriptorChar == 'w') {
- if (result.hasDensity() || result.hasWidth())
- return false;
- int resourceWidth = descriptor.toInt(isValid);
- if (!isValid || resourceWidth <= 0)
- return false;
- result.setResourceWidth(resourceWidth);
- } else if (descriptorChar == 'h') {
- // This is here only for future compat purposes.
- // The value of the 'h' descriptor is not used.
- if (result.hasDensity() || result.hasHeight())
- return false;
- int resourceHeight = descriptor.toInt(isValid);
- if (!isValid || resourceHeight <= 0)
- return false;
- result.setResourceHeight(resourceHeight);
- }
- }
- return true;
-}
-
-// http://picture.responsiveimages.org/#parse-srcset-attr
-template<typename CharType>
-static Vector<ImageCandidate> parseImageCandidatesFromSrcsetAttribute(const CharType* attributeStart, unsigned length)
-{
- Vector<ImageCandidate> imageCandidates;
-
- const CharType* attributeEnd = attributeStart + length;
-
- for (const CharType* position = attributeStart; position < attributeEnd;) {
- // 4. Splitting loop: Collect a sequence of characters that are space characters or U+002C COMMA characters.
- skipWhile<CharType, isHTMLSpaceOrComma<CharType> >(position, attributeEnd);
- if (position == attributeEnd) {
- // Contrary to spec language - descriptor parsing happens on each candidate, so when we reach the attributeEnd, we can exit.
- break;
- }
- const CharType* imageURLStart = position;
- // 6. Collect a sequence of characters that are not space characters, and let that be url.
-
- skipUntil<CharType, isHTMLSpace<CharType> >(position, attributeEnd);
- const CharType* imageURLEnd = position;
-
- DescriptorParsingResult result;
-
- // 8. If url ends with a U+002C COMMA character (,)
- if (isComma(*(position - 1))) {
- // Remove all trailing U+002C COMMA characters from url.
- imageURLEnd = position - 1;
- reverseSkipWhile<CharType, isComma>(imageURLEnd, imageURLStart);
- ++imageURLEnd;
- // If url is empty, then jump to the step labeled splitting loop.
- if (imageURLStart == imageURLEnd)
- continue;
- } else {
- // Advancing position here (contrary to spec) to avoid an useless extra state machine step.
- // Filed a spec bug: https://github.com/ResponsiveImagesCG/picture-element/issues/189
- ++position;
- Vector<StringView> descriptorTokens;
- tokenizeDescriptors(position, attributeEnd, descriptorTokens);
- // Contrary to spec language - descriptor parsing happens on each candidate.
- // This is a black-box equivalent, to avoid storing descriptor lists for each candidate.
- if (!parseDescriptors(descriptorTokens, result))
- continue;
- }
-
- ASSERT(imageURLEnd > imageURLStart);
- unsigned imageURLLength = imageURLEnd - imageURLStart;
- imageCandidates.append(ImageCandidate(StringView(imageURLStart, imageURLLength), result, ImageCandidate::SrcsetOrigin));
- // 11. Return to the step labeled splitting loop.
- }
- return imageCandidates;
-}
-
-Vector<ImageCandidate> parseImageCandidatesFromSrcsetAttribute(StringView attribute)
-{
- // FIXME: We should consider replacing the direct pointers in the parsing process with StringView and positions.
- if (attribute.is8Bit())
- return parseImageCandidatesFromSrcsetAttribute<LChar>(attribute.characters8(), attribute.length());
- else
- return parseImageCandidatesFromSrcsetAttribute<UChar>(attribute.characters16(), attribute.length());
-}
-
-static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, Vector<ImageCandidate>& imageCandidates, float sourceSize)
-{
- bool ignoreSrc = false;
- if (imageCandidates.isEmpty())
- return ImageCandidate();
-
- // http://picture.responsiveimages.org/#normalize-source-densities
- for (auto& candidate : imageCandidates) {
- if (candidate.resourceWidth > 0) {
- candidate.density = static_cast<float>(candidate.resourceWidth) / sourceSize;
- ignoreSrc = true;
- } else if (candidate.density < 0)
- candidate.density = DefaultDensityValue;
- }
-
- std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareByDensity);
-
- unsigned i;
- for (i = 0; i < imageCandidates.size() - 1; ++i) {
- if ((imageCandidates[i].density >= deviceScaleFactor) && (!ignoreSrc || !imageCandidates[i].srcOrigin()))
- break;
- }
-
- if (imageCandidates[i].srcOrigin() && ignoreSrc) {
- ASSERT(i > 0);
- --i;
- }
- float winningDensity = imageCandidates[i].density;
-
- unsigned winner = i;
- // 16. If an entry b in candidates has the same associated ... pixel density as an earlier entry a in candidates,
- // then remove entry b
- while ((i > 0) && (imageCandidates[--i].density == winningDensity))
- winner = i;
-
- return imageCandidates[winner];
-}
-
-ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, const AtomicString& srcAttribute, const AtomicString& srcsetAttribute, float sourceSize)
-{
- if (srcsetAttribute.isNull()) {
- if (srcAttribute.isNull())
- return ImageCandidate();
- return ImageCandidate(StringView(srcAttribute), DescriptorParsingResult(), ImageCandidate::SrcOrigin);
- }
-
- Vector<ImageCandidate> imageCandidates = parseImageCandidatesFromSrcsetAttribute(StringView(srcsetAttribute));
-
- if (!srcAttribute.isEmpty())
- imageCandidates.append(ImageCandidate(StringView(srcAttribute), DescriptorParsingResult(), ImageCandidate::SrcOrigin));
-
- return pickBestImageCandidate(deviceScaleFactor, imageCandidates, sourceSize);
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/html/parser/HTMLSrcsetParser.h b/Source/WebCore/html/parser/HTMLSrcsetParser.h
deleted file mode 100644
index f6d3900d4..000000000
--- a/Source/WebCore/html/parser/HTMLSrcsetParser.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLSrcsetParser_h
-#define HTMLSrcsetParser_h
-
-#include <wtf/text/StringView.h>
-
-namespace WebCore {
-
-const int UninitializedDescriptor = -1;
-const float DefaultDensityValue = 1.0;
-
-class DescriptorParsingResult {
-public:
- DescriptorParsingResult()
- : m_density(UninitializedDescriptor)
- , m_resourceWidth(UninitializedDescriptor)
- , m_resourceHeight(UninitializedDescriptor)
- {
- }
-
- bool hasDensity() const { return m_density >= 0; }
- bool hasWidth() const { return m_resourceWidth >= 0; }
- bool hasHeight() const { return m_resourceHeight >= 0; }
-
- float density() const { ASSERT(hasDensity()); return m_density; }
- unsigned resourceWidth() const { ASSERT(hasWidth()); return m_resourceWidth; }
- unsigned resourceHeight() const { ASSERT(hasHeight()); return m_resourceHeight; }
-
- void setResourceWidth(int width) { ASSERT(width >= 0); m_resourceWidth = (unsigned)width; }
- void setResourceHeight(int height) { ASSERT(height >= 0); m_resourceHeight = (unsigned)height; }
- void setDensity(float densityToSet) { ASSERT(densityToSet >= 0); m_density = densityToSet; }
-
-private:
- float m_density;
- int m_resourceWidth;
- int m_resourceHeight;
-};
-
-struct ImageCandidate {
- enum OriginAttribute {
- SrcsetOrigin,
- SrcOrigin
- };
-
- ImageCandidate()
- : density(DefaultDensityValue)
- , resourceWidth(UninitializedDescriptor)
- , originAttribute(SrcsetOrigin)
- {
- }
-
- ImageCandidate(const StringView& source, const DescriptorParsingResult& result, OriginAttribute originAttribute)
- : string(source)
- , density(result.hasDensity() ? result.density() : UninitializedDescriptor)
- , resourceWidth(result.hasWidth() ? result.resourceWidth() : UninitializedDescriptor)
- , originAttribute(originAttribute)
- {
- }
-
- bool srcOrigin() const
- {
- return (originAttribute == SrcOrigin);
- }
-
- StringView string;
- float density;
- int resourceWidth;
- OriginAttribute originAttribute;
-};
-
-ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, const AtomicString& srcAttribute, const AtomicString& srcsetAttribute, float sourceSize);
-
-Vector<ImageCandidate> parseImageCandidatesFromSrcsetAttribute(StringView attribute);
-
-}
-
-#endif
diff --git a/Source/WebCore/html/parser/HTMLStackItem.h b/Source/WebCore/html/parser/HTMLStackItem.h
index c02b3a9ce..953a67960 100644
--- a/Source/WebCore/html/parser/HTMLStackItem.h
+++ b/Source/WebCore/html/parser/HTMLStackItem.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2012 Company 100, Inc. All rights reserved.
- * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,166 +27,112 @@
#define HTMLStackItem_h
#include "AtomicHTMLToken.h"
-#include "DocumentFragment.h"
#include "Element.h"
#include "HTMLNames.h"
#include "MathMLNames.h"
#include "SVGNames.h"
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/AtomicString.h>
+
namespace WebCore {
+class ContainerNode;
+
class HTMLStackItem : public RefCounted<HTMLStackItem> {
public:
- // Normal HTMLElementStack and HTMLFormattingElementList items.
- static Ref<HTMLStackItem> create(Ref<Element>&&, AtomicHTMLToken&, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI);
-
- // Document fragment or element for parsing context.
- static Ref<HTMLStackItem> create(Element&);
- static Ref<HTMLStackItem> create(DocumentFragment&);
-
- bool isElement() const;
- bool isDocumentFragment() const;
-
- ContainerNode& node() const;
- Element& element() const;
-
- const AtomicString& namespaceURI() const;
- const AtomicString& localName() const;
-
- const Vector<Attribute>& attributes() const;
- const Attribute* findAttribute(const QualifiedName& attributeName) const;
-
- bool hasTagName(const QualifiedName&) const;
- bool matchesHTMLTag(const AtomicString&) const;
-
-private:
- HTMLStackItem(Ref<Element>&&, AtomicHTMLToken&, const AtomicString& namespaceURI);
- explicit HTMLStackItem(Element&);
- explicit HTMLStackItem(DocumentFragment&);
-
- const Ref<ContainerNode> m_node;
- const AtomicString m_namespaceURI;
- const AtomicString m_localName;
- const Vector<Attribute> m_attributes;
-};
-
-bool isInHTMLNamespace(const HTMLStackItem&);
-bool isNumberedHeaderElement(const HTMLStackItem&);
-bool isSpecialNode(const HTMLStackItem&);
-
-inline HTMLStackItem::HTMLStackItem(Ref<Element>&& element, AtomicHTMLToken& token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
- : m_node(WTF::move(element))
- , m_namespaceURI(namespaceURI)
- , m_localName(token.name())
- , m_attributes(token.attributes())
-{
- // FIXME: We should find a way to move the attributes vector in the normal code path instead of copying it.
-}
-
-inline Ref<HTMLStackItem> HTMLStackItem::create(Ref<Element>&& element, AtomicHTMLToken& token, const AtomicString& namespaceURI)
-{
- return adoptRef(*new HTMLStackItem(WTF::move(element), token, namespaceURI));
-}
-
-inline HTMLStackItem::HTMLStackItem(Element& element)
- : m_node(element)
- , m_namespaceURI(element.namespaceURI())
- , m_localName(element.localName())
-{
-}
-
-inline Ref<HTMLStackItem> HTMLStackItem::create(Element& element)
-{
- return adoptRef(*new HTMLStackItem(element));
-}
-
-inline HTMLStackItem::HTMLStackItem(DocumentFragment& fragment)
- : m_node(fragment)
-{
-}
-
-inline Ref<HTMLStackItem> HTMLStackItem::create(DocumentFragment& fragment)
-{
- return adoptRef(*new HTMLStackItem(fragment));
-}
-
-inline ContainerNode& HTMLStackItem::node() const
-{
- return const_cast<ContainerNode&>(m_node.get());
-}
+ enum ItemType {
+ ItemForContextElement,
+ ItemForDocumentFragmentNode
+ };
+
+ // Used by document fragment node and context element.
+ static PassRefPtr<HTMLStackItem> create(PassRefPtr<ContainerNode> node, ItemType type)
+ {
+ return adoptRef(new HTMLStackItem(node, type));
+ }
-inline Element& HTMLStackItem::element() const
-{
- return downcast<Element>(node());
-}
+ // Used by HTMLElementStack and HTMLFormattingElementList.
+ static PassRefPtr<HTMLStackItem> create(PassRefPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
+ {
+ return adoptRef(new HTMLStackItem(node, token, namespaceURI));
+ }
-inline bool HTMLStackItem::isDocumentFragment() const
-{
- return m_localName.isNull();
-}
+ Element* element() const { return toElement(m_node.get()); }
+ ContainerNode* node() const { return m_node.get(); }
-inline bool HTMLStackItem::isElement() const
-{
- return !isDocumentFragment();
-}
+ bool isDocumentFragmentNode() const { return m_isDocumentFragmentNode; }
+ bool isElementNode() const { return !m_isDocumentFragmentNode; }
-inline const AtomicString& HTMLStackItem::namespaceURI() const
-{
- return m_namespaceURI;
-}
+ const AtomicString& namespaceURI() const { return m_namespaceURI; }
+ const AtomicString& localName() const { return m_tokenLocalName; }
-inline const AtomicString& HTMLStackItem::localName() const
-{
- return m_localName;
-}
+ const Vector<Attribute>& attributes() const { ASSERT(m_tokenLocalName); return m_tokenAttributes; }
+ Attribute* getAttributeItem(const QualifiedName& attributeName)
+ {
+ ASSERT(m_tokenLocalName);
+ return findAttributeInVector(m_tokenAttributes, attributeName);
+ }
-inline const Vector<Attribute>& HTMLStackItem::attributes() const
-{
- ASSERT(isElement());
- return m_attributes;
-}
+ bool hasLocalName(const AtomicString& name) const { return m_tokenLocalName == name; }
+ bool hasTagName(const QualifiedName& name) const { return m_tokenLocalName == name.localName() && m_namespaceURI == name.namespaceURI(); }
-inline const Attribute* HTMLStackItem::findAttribute(const QualifiedName& attributeName) const
-{
- return WebCore::findAttribute(const_cast<Vector<Attribute>&>(attributes()), attributeName);
-}
+ bool matchesHTMLTag(const AtomicString& name) const { return m_tokenLocalName == name && m_namespaceURI == HTMLNames::xhtmlNamespaceURI; }
+ bool matchesHTMLTag(const QualifiedName& name) const { return m_tokenLocalName == name && m_namespaceURI == HTMLNames::xhtmlNamespaceURI; }
-inline bool HTMLStackItem::hasTagName(const QualifiedName& name) const
-{
- return m_localName == name.localName() && m_namespaceURI == name.namespaceURI();
-}
+ bool causesFosterParenting()
+ {
+ return hasTagName(HTMLNames::tableTag)
+ || hasTagName(HTMLNames::tbodyTag)
+ || hasTagName(HTMLNames::tfootTag)
+ || hasTagName(HTMLNames::theadTag)
+ || hasTagName(HTMLNames::trTag);
+ }
-inline bool HTMLStackItem::matchesHTMLTag(const AtomicString& name) const
-{
- return m_localName == name && m_namespaceURI == HTMLNames::xhtmlNamespaceURI;
-}
+ bool isInHTMLNamespace() const
+ {
+ // A DocumentFragment takes the place of the document element when parsing
+ // fragments and should be considered in the HTML namespace.
+ return namespaceURI() == HTMLNames::xhtmlNamespaceURI
+ || isDocumentFragmentNode(); // FIXME: Does this also apply to ShadowRoot?
+ }
-inline bool isInHTMLNamespace(const HTMLStackItem& item)
-{
- // A DocumentFragment takes the place of the document element when parsing
- // fragments and thus should be treated as if it was in the HTML namespace.
- // FIXME: Is this also needed for a ShadowRoot that might be a non-HTML element?
- return item.namespaceURI() == HTMLNames::xhtmlNamespaceURI || item.isDocumentFragment();
-}
+ bool isNumberedHeaderElement() const
+ {
+ return hasTagName(HTMLNames::h1Tag)
+ || hasTagName(HTMLNames::h2Tag)
+ || hasTagName(HTMLNames::h3Tag)
+ || hasTagName(HTMLNames::h4Tag)
+ || hasTagName(HTMLNames::h5Tag)
+ || hasTagName(HTMLNames::h6Tag);
+ }
-inline bool isNumberedHeaderElement(const HTMLStackItem& item)
-{
- return item.namespaceURI() == HTMLNames::xhtmlNamespaceURI
- && (item.localName() == HTMLNames::h1Tag
- || item.localName() == HTMLNames::h2Tag
- || item.localName() == HTMLNames::h3Tag
- || item.localName() == HTMLNames::h4Tag
- || item.localName() == HTMLNames::h5Tag
- || item.localName() == HTMLNames::h6Tag);
-}
+ bool isTableBodyContextElement() const
+ {
+ return hasTagName(HTMLNames::tbodyTag)
+ || hasTagName(HTMLNames::tfootTag)
+ || hasTagName(HTMLNames::theadTag);
+ }
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#special
-inline bool isSpecialNode(const HTMLStackItem& item)
-{
- if (item.isDocumentFragment())
- return true;
- const AtomicString& tagName = item.localName();
- if (item.namespaceURI() == HTMLNames::xhtmlNamespaceURI) {
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#special
+ bool isSpecialNode() const
+ {
+ if (hasTagName(MathMLNames::miTag)
+ || hasTagName(MathMLNames::moTag)
+ || hasTagName(MathMLNames::mnTag)
+ || hasTagName(MathMLNames::msTag)
+ || hasTagName(MathMLNames::mtextTag)
+ || hasTagName(MathMLNames::annotation_xmlTag)
+ || hasTagName(SVGNames::foreignObjectTag)
+ || hasTagName(SVGNames::descTag)
+ || hasTagName(SVGNames::titleTag))
+ return true;
+ if (isDocumentFragmentNode())
+ return true;
+ if (!isInHTMLNamespace())
+ return false;
+ const AtomicString& tagName = localName();
return tagName == HTMLNames::addressTag
|| tagName == HTMLNames::appletTag
|| tagName == HTMLNames::areaTag
@@ -219,12 +164,7 @@ inline bool isSpecialNode(const HTMLStackItem& item)
|| tagName == HTMLNames::formTag
|| tagName == HTMLNames::frameTag
|| tagName == HTMLNames::framesetTag
- || tagName == HTMLNames::h1Tag
- || tagName == HTMLNames::h2Tag
- || tagName == HTMLNames::h3Tag
- || tagName == HTMLNames::h4Tag
- || tagName == HTMLNames::h5Tag
- || tagName == HTMLNames::h6Tag
+ || isNumberedHeaderElement()
|| tagName == HTMLNames::headTag
|| tagName == HTMLNames::headerTag
|| tagName == HTMLNames::hgroupTag
@@ -257,36 +197,52 @@ inline bool isSpecialNode(const HTMLStackItem& item)
|| tagName == HTMLNames::styleTag
|| tagName == HTMLNames::summaryTag
|| tagName == HTMLNames::tableTag
- || tagName == HTMLNames::tbodyTag
+ || isTableBodyContextElement()
|| tagName == HTMLNames::tdTag
#if ENABLE(TEMPLATE_ELEMENT)
|| tagName == HTMLNames::templateTag
#endif
|| tagName == HTMLNames::textareaTag
- || tagName == HTMLNames::tfootTag
|| tagName == HTMLNames::thTag
- || tagName == HTMLNames::theadTag
|| tagName == HTMLNames::titleTag
|| tagName == HTMLNames::trTag
|| tagName == HTMLNames::ulTag
|| tagName == HTMLNames::wbrTag
|| tagName == HTMLNames::xmpTag;
}
- if (item.namespaceURI() == MathMLNames::mathmlNamespaceURI) {
- return tagName == MathMLNames::annotation_xmlTag
- || tagName == MathMLNames::miTag
- || tagName == MathMLNames::moTag
- || tagName == MathMLNames::mnTag
- || tagName == MathMLNames::msTag
- || tagName == MathMLNames::mtextTag;
+
+private:
+ HTMLStackItem(PassRefPtr<ContainerNode> node, ItemType type)
+ : m_node(node)
+ {
+ switch (type) {
+ case ItemForDocumentFragmentNode:
+ m_isDocumentFragmentNode = true;
+ break;
+ case ItemForContextElement:
+ m_tokenLocalName = m_node->localName();
+ m_namespaceURI = m_node->namespaceURI();
+ m_isDocumentFragmentNode = false;
+ break;
+ }
}
- if (item.namespaceURI() == SVGNames::svgNamespaceURI) {
- return tagName == SVGNames::descTag
- || tagName == SVGNames::foreignObjectTag
- || tagName == SVGNames::titleTag;
+
+ HTMLStackItem(PassRefPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
+ : m_node(node)
+ , m_tokenLocalName(token->name())
+ , m_tokenAttributes(token->attributes())
+ , m_namespaceURI(namespaceURI)
+ , m_isDocumentFragmentNode(false)
+ {
}
- return false;
-}
+
+ RefPtr<ContainerNode> m_node;
+
+ AtomicString m_tokenLocalName;
+ Vector<Attribute> m_tokenAttributes;
+ AtomicString m_namespaceURI;
+ bool m_isDocumentFragmentNode;
+};
} // namespace WebCore
diff --git a/Source/WebCore/html/parser/HTMLToken.h b/Source/WebCore/html/parser/HTMLToken.h
index 617172181..722ed9080 100644
--- a/Source/WebCore/html/parser/HTMLToken.h
+++ b/Source/WebCore/html/parser/HTMLToken.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2013 Google, Inc. All Rights Reserved.
- * Copyright (C) 2015 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,18 +27,43 @@
#define HTMLToken_h
#include "Attribute.h"
+#include "HTMLToken.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
namespace WebCore {
-struct DoctypeData {
- bool hasPublicIdentifier { false };
- bool hasSystemIdentifier { false };
- Vector<UChar> publicIdentifier;
- Vector<UChar> systemIdentifier;
- bool forceQuirks { false };
+class DoctypeData {
+ WTF_MAKE_NONCOPYABLE(DoctypeData);
+public:
+ DoctypeData()
+ : m_hasPublicIdentifier(false)
+ , m_hasSystemIdentifier(false)
+ , m_forceQuirks(false)
+ {
+ }
+
+ // FIXME: This should use String instead of Vector<UChar>.
+ bool m_hasPublicIdentifier;
+ bool m_hasSystemIdentifier;
+ WTF::Vector<UChar> m_publicIdentifier;
+ WTF::Vector<UChar> m_systemIdentifier;
+ bool m_forceQuirks;
};
+static inline Attribute* findAttributeInVector(Vector<Attribute>& attributes, const QualifiedName& name)
+{
+ for (unsigned i = 0; i < attributes.size(); ++i) {
+ if (attributes.at(i).name().matches(name))
+ return &attributes.at(i);
+ }
+ return 0;
+}
+
class HTMLToken {
+ WTF_MAKE_NONCOPYABLE(HTMLToken);
WTF_MAKE_FAST_ALLOCATED;
public:
enum Type {
@@ -52,398 +76,377 @@ public:
EndOfFile,
};
- struct Attribute {
+ class Attribute {
+ public:
+ class Range {
+ public:
+ int start;
+ int end;
+ };
+
+ Range nameRange;
+ Range valueRange;
Vector<UChar, 32> name;
Vector<UChar, 32> value;
-
- // Used by HTMLSourceTracker.
- unsigned startOffset;
- unsigned endOffset;
};
typedef Vector<Attribute, 10> AttributeList;
typedef Vector<UChar, 256> DataVector;
- HTMLToken();
-
- void clear();
-
- Type type() const;
-
- // EndOfFile
-
- void makeEndOfFile();
-
- // StartTag, EndTag, DOCTYPE.
-
- const DataVector& name() const;
-
- void appendToName(UChar);
-
- // DOCTYPE.
-
- void beginDOCTYPE();
- void beginDOCTYPE(UChar);
-
- void setForceQuirks();
-
- void setPublicIdentifierToEmptyString();
- void setSystemIdentifierToEmptyString();
-
- void appendToPublicIdentifier(UChar);
- void appendToSystemIdentifier(UChar);
-
- std::unique_ptr<DoctypeData> releaseDoctypeData();
-
- // StartTag, EndTag.
+ HTMLToken() { clear(); }
- bool selfClosing() const;
- const AttributeList& attributes() const;
-
- void beginStartTag(UChar);
-
- void beginEndTag(LChar);
- void beginEndTag(const Vector<LChar, 32>&);
-
- void beginAttribute(unsigned offset);
- void appendToAttributeName(UChar);
- void appendToAttributeValue(UChar);
- void endAttribute(unsigned offset);
+ void clear()
+ {
+ m_type = Uninitialized;
+ m_range.start = 0;
+ m_range.end = 0;
+ m_baseOffset = 0;
+ m_data.clear();
+ m_orAllData = 0;
+ }
- void setSelfClosing();
+ bool isUninitialized() { return m_type == Uninitialized; }
+ Type type() const { return m_type; }
-public:
- // Used by the XSSAuditor to nuke XSS-laden attributes.
- void eraseValueOfAttribute(unsigned index);
- void appendToAttributeValue(unsigned index, StringView value);
+ void makeEndOfFile()
+ {
+ ASSERT(m_type == Uninitialized);
+ m_type = EndOfFile;
+ }
- // Character.
+ /* Range and offset methods exposed for HTMLSourceTracker and HTMLViewSourceParser */
+ int startIndex() const { return m_range.start; }
+ int endIndex() const { return m_range.end; }
- // Starting a character token works slightly differently than starting
- // other types of tokens because we want to save a per-character branch.
- // There is no beginCharacters, and appending a character sets the type.
-
- const DataVector& characters() const;
- bool charactersIsAll8BitData() const;
+ void setBaseOffset(int offset)
+ {
+ m_baseOffset = offset;
+ }
- void appendToCharacter(LChar);
- void appendToCharacter(UChar);
- void appendToCharacter(const Vector<LChar, 32>&);
+ void end(int endOffset)
+ {
+ m_range.end = endOffset - m_baseOffset;
+ }
- // Comment.
+ const DataVector& data() const
+ {
+ ASSERT(m_type == Character || m_type == Comment || m_type == StartTag || m_type == EndTag);
+ return m_data;
+ }
- const DataVector& comment() const;
- bool commentIsAll8BitData() const;
+ bool isAll8BitData() const
+ {
+ return (m_orAllData <= 0xff);
+ }
- void beginComment();
- void appendToComment(UChar);
+ const DataVector& name() const
+ {
+ ASSERT(m_type == StartTag || m_type == EndTag || m_type == DOCTYPE);
+ return m_data;
+ }
-private:
- Type m_type;
+ void appendToName(UChar character)
+ {
+ ASSERT(m_type == StartTag || m_type == EndTag || m_type == DOCTYPE);
+ ASSERT(character);
+ m_data.append(character);
+ m_orAllData |= character;
+ }
- DataVector m_data;
- UChar m_data8BitCheck;
+ /* DOCTYPE Tokens */
- // For StartTag and EndTag
- bool m_selfClosing;
- AttributeList m_attributes;
- Attribute* m_currentAttribute;
+ bool forceQuirks() const
+ {
+ ASSERT(m_type == DOCTYPE);
+ return m_doctypeData->m_forceQuirks;
+ }
- // For DOCTYPE
- std::unique_ptr<DoctypeData> m_doctypeData;
-};
+ void setForceQuirks()
+ {
+ ASSERT(m_type == DOCTYPE);
+ m_doctypeData->m_forceQuirks = true;
+ }
-const HTMLToken::Attribute* findAttribute(const Vector<HTMLToken::Attribute>&, StringView name);
+ void beginDOCTYPE()
+ {
+ ASSERT(m_type == Uninitialized);
+ m_type = DOCTYPE;
+ m_doctypeData = std::make_unique<DoctypeData>();
+ }
-inline HTMLToken::HTMLToken()
- : m_type(Uninitialized)
- , m_data8BitCheck(0)
-{
-}
+ void beginDOCTYPE(UChar character)
+ {
+ ASSERT(character);
+ beginDOCTYPE();
+ m_data.append(character);
+ m_orAllData |= character;
+ }
-inline void HTMLToken::clear()
-{
- m_type = Uninitialized;
- m_data.clear();
- m_data8BitCheck = 0;
-}
+ // FIXME: Distinguish between a missing public identifer and an empty one.
+ const WTF::Vector<UChar>& publicIdentifier() const
+ {
+ ASSERT(m_type == DOCTYPE);
+ return m_doctypeData->m_publicIdentifier;
+ }
-inline HTMLToken::Type HTMLToken::type() const
-{
- return m_type;
-}
+ // FIXME: Distinguish between a missing system identifer and an empty one.
+ const WTF::Vector<UChar>& systemIdentifier() const
+ {
+ ASSERT(m_type == DOCTYPE);
+ return m_doctypeData->m_systemIdentifier;
+ }
-inline void HTMLToken::makeEndOfFile()
-{
- ASSERT(m_type == Uninitialized);
- m_type = EndOfFile;
-}
+ void setPublicIdentifierToEmptyString()
+ {
+ ASSERT(m_type == DOCTYPE);
+ m_doctypeData->m_hasPublicIdentifier = true;
+ m_doctypeData->m_publicIdentifier.clear();
+ }
-inline const HTMLToken::DataVector& HTMLToken::name() const
-{
- ASSERT(m_type == StartTag || m_type == EndTag || m_type == DOCTYPE);
- return m_data;
-}
+ void setSystemIdentifierToEmptyString()
+ {
+ ASSERT(m_type == DOCTYPE);
+ m_doctypeData->m_hasSystemIdentifier = true;
+ m_doctypeData->m_systemIdentifier.clear();
+ }
-inline void HTMLToken::appendToName(UChar character)
-{
- ASSERT(m_type == StartTag || m_type == EndTag || m_type == DOCTYPE);
- ASSERT(character);
- m_data.append(character);
- m_data8BitCheck |= character;
-}
+ void appendToPublicIdentifier(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == DOCTYPE);
+ ASSERT(m_doctypeData->m_hasPublicIdentifier);
+ m_doctypeData->m_publicIdentifier.append(character);
+ }
-inline void HTMLToken::setForceQuirks()
-{
- ASSERT(m_type == DOCTYPE);
- m_doctypeData->forceQuirks = true;
-}
+ void appendToSystemIdentifier(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == DOCTYPE);
+ ASSERT(m_doctypeData->m_hasSystemIdentifier);
+ m_doctypeData->m_systemIdentifier.append(character);
+ }
-inline void HTMLToken::beginDOCTYPE()
-{
- ASSERT(m_type == Uninitialized);
- m_type = DOCTYPE;
- m_doctypeData = std::make_unique<DoctypeData>();
-}
+ std::unique_ptr<DoctypeData> releaseDoctypeData()
+ {
+ return std::move(m_doctypeData);
+ }
-inline void HTMLToken::beginDOCTYPE(UChar character)
-{
- ASSERT(character);
- beginDOCTYPE();
- m_data.append(character);
- m_data8BitCheck |= character;
-}
+ /* Start/End Tag Tokens */
-inline void HTMLToken::setPublicIdentifierToEmptyString()
-{
- ASSERT(m_type == DOCTYPE);
- m_doctypeData->hasPublicIdentifier = true;
- m_doctypeData->publicIdentifier.clear();
-}
+ bool selfClosing() const
+ {
+ ASSERT(m_type == StartTag || m_type == EndTag);
+ return m_selfClosing;
+ }
-inline void HTMLToken::setSystemIdentifierToEmptyString()
-{
- ASSERT(m_type == DOCTYPE);
- m_doctypeData->hasSystemIdentifier = true;
- m_doctypeData->systemIdentifier.clear();
-}
+ void setSelfClosing()
+ {
+ ASSERT(m_type == StartTag || m_type == EndTag);
+ m_selfClosing = true;
+ }
-inline void HTMLToken::appendToPublicIdentifier(UChar character)
-{
- ASSERT(character);
- ASSERT(m_type == DOCTYPE);
- ASSERT(m_doctypeData->hasPublicIdentifier);
- m_doctypeData->publicIdentifier.append(character);
-}
+ void beginStartTag(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == Uninitialized);
+ m_type = StartTag;
+ m_selfClosing = false;
+ m_currentAttribute = 0;
+ m_attributes.clear();
+
+ m_data.append(character);
+ m_orAllData |= character;
+ }
-inline void HTMLToken::appendToSystemIdentifier(UChar character)
-{
- ASSERT(character);
- ASSERT(m_type == DOCTYPE);
- ASSERT(m_doctypeData->hasSystemIdentifier);
- m_doctypeData->systemIdentifier.append(character);
-}
+ void beginEndTag(LChar character)
+ {
+ ASSERT(m_type == Uninitialized);
+ m_type = EndTag;
+ m_selfClosing = false;
+ m_currentAttribute = 0;
+ m_attributes.clear();
-inline std::unique_ptr<DoctypeData> HTMLToken::releaseDoctypeData()
-{
- return WTF::move(m_doctypeData);
-}
+ m_data.append(character);
+ }
-inline bool HTMLToken::selfClosing() const
-{
- ASSERT(m_type == StartTag || m_type == EndTag);
- return m_selfClosing;
-}
+ void beginEndTag(const Vector<LChar, 32>& characters)
+ {
+ ASSERT(m_type == Uninitialized);
+ m_type = EndTag;
+ m_selfClosing = false;
+ m_currentAttribute = 0;
+ m_attributes.clear();
-inline void HTMLToken::setSelfClosing()
-{
- ASSERT(m_type == StartTag || m_type == EndTag);
- m_selfClosing = true;
-}
+ m_data.appendVector(characters);
+ }
-inline void HTMLToken::beginStartTag(UChar character)
-{
- ASSERT(character);
- ASSERT(m_type == Uninitialized);
- m_type = StartTag;
- m_selfClosing = false;
- m_attributes.clear();
-
-#if !ASSERT_DISABLED
- m_currentAttribute = nullptr;
+ void addNewAttribute()
+ {
+ ASSERT(m_type == StartTag || m_type == EndTag);
+ m_attributes.grow(m_attributes.size() + 1);
+ m_currentAttribute = &m_attributes.last();
+#ifndef NDEBUG
+ m_currentAttribute->nameRange.start = 0;
+ m_currentAttribute->nameRange.end = 0;
+ m_currentAttribute->valueRange.start = 0;
+ m_currentAttribute->valueRange.end = 0;
#endif
+ }
- m_data.append(character);
- m_data8BitCheck = character;
-}
+ void beginAttributeName(int offset)
+ {
+ m_currentAttribute->nameRange.start = offset - m_baseOffset;
+ }
-inline void HTMLToken::beginEndTag(LChar character)
-{
- ASSERT(m_type == Uninitialized);
- m_type = EndTag;
- m_selfClosing = false;
- m_attributes.clear();
+ void endAttributeName(int offset)
+ {
+ int index = offset - m_baseOffset;
+ m_currentAttribute->nameRange.end = index;
+ m_currentAttribute->valueRange.start = index;
+ m_currentAttribute->valueRange.end = index;
+ }
-#if !ASSERT_DISABLED
- m_currentAttribute = nullptr;
+ void beginAttributeValue(int offset)
+ {
+ m_currentAttribute->valueRange.start = offset - m_baseOffset;
+#ifndef NDEBUG
+ m_currentAttribute->valueRange.end = 0;
#endif
+ }
- m_data.append(character);
-}
-
-inline void HTMLToken::beginEndTag(const Vector<LChar, 32>& characters)
-{
- ASSERT(m_type == Uninitialized);
- m_type = EndTag;
- m_selfClosing = false;
- m_attributes.clear();
-
-#if !ASSERT_DISABLED
- m_currentAttribute = nullptr;
-#endif
+ void endAttributeValue(int offset)
+ {
+ m_currentAttribute->valueRange.end = offset - m_baseOffset;
+ }
- m_data.appendVector(characters);
-}
+ void appendToAttributeName(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == StartTag || m_type == EndTag);
+ // FIXME: We should be able to add the following ASSERT once we fix
+ // https://bugs.webkit.org/show_bug.cgi?id=62971
+ // ASSERT(m_currentAttribute->nameRange.start);
+ m_currentAttribute->name.append(character);
+ }
-inline void HTMLToken::beginAttribute(unsigned offset)
-{
- ASSERT(m_type == StartTag || m_type == EndTag);
- ASSERT(offset);
+ void appendToAttributeValue(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == StartTag || m_type == EndTag);
+ ASSERT(m_currentAttribute->valueRange.start);
+ m_currentAttribute->value.append(character);
+ }
- m_attributes.grow(m_attributes.size() + 1);
- m_currentAttribute = &m_attributes.last();
+ void appendToAttributeValue(size_t i, const String& value)
+ {
+ ASSERT(!value.isEmpty());
+ ASSERT(m_type == StartTag || m_type == EndTag);
+ append(m_attributes[i].value, value);
+ }
- m_currentAttribute->startOffset = offset;
-}
+ const AttributeList& attributes() const
+ {
+ ASSERT(m_type == StartTag || m_type == EndTag);
+ return m_attributes;
+ }
-inline void HTMLToken::endAttribute(unsigned offset)
-{
- ASSERT(offset);
- ASSERT(m_currentAttribute);
- m_currentAttribute->endOffset = offset;
-#if !ASSERT_DISABLED
- m_currentAttribute = nullptr;
-#endif
-}
+ const Attribute* getAttributeItem(const QualifiedName& name) const
+ {
+ for (unsigned i = 0; i < m_attributes.size(); ++i) {
+ if (AtomicString(m_attributes.at(i).name) == name.localName())
+ return &m_attributes.at(i);
+ }
+ return 0;
+ }
-inline void HTMLToken::appendToAttributeName(UChar character)
-{
- ASSERT(character);
- ASSERT(m_type == StartTag || m_type == EndTag);
- ASSERT(m_currentAttribute);
- m_currentAttribute->name.append(character);
-}
+ // Used by the XSSAuditor to nuke XSS-laden attributes.
+ void eraseValueOfAttribute(size_t i)
+ {
+ ASSERT(m_type == StartTag || m_type == EndTag);
+ m_attributes[i].value.clear();
+ }
-inline void HTMLToken::appendToAttributeValue(UChar character)
-{
- ASSERT(character);
- ASSERT(m_type == StartTag || m_type == EndTag);
- ASSERT(m_currentAttribute);
- m_currentAttribute->value.append(character);
-}
+ /* Character Tokens */
-inline void HTMLToken::appendToAttributeValue(unsigned i, StringView value)
-{
- ASSERT(!value.isEmpty());
- ASSERT(m_type == StartTag || m_type == EndTag);
- append(m_attributes[i].value, value);
-}
+ // Starting a character token works slightly differently than starting
+ // other types of tokens because we want to save a per-character branch.
+ void ensureIsCharacterToken()
+ {
+ ASSERT(m_type == Uninitialized || m_type == Character);
+ m_type = Character;
+ }
-inline const HTMLToken::AttributeList& HTMLToken::attributes() const
-{
- ASSERT(m_type == StartTag || m_type == EndTag);
- return m_attributes;
-}
+ const DataVector& characters() const
+ {
+ ASSERT(m_type == Character);
+ return m_data;
+ }
-// Used by the XSSAuditor to nuke XSS-laden attributes.
-inline void HTMLToken::eraseValueOfAttribute(unsigned i)
-{
- ASSERT(m_type == StartTag || m_type == EndTag);
- ASSERT(i < m_attributes.size());
- m_attributes[i].value.clear();
-}
+ void appendToCharacter(char character)
+ {
+ ASSERT(m_type == Character);
+ m_data.append(character);
+ }
-inline const HTMLToken::DataVector& HTMLToken::characters() const
-{
- ASSERT(m_type == Character);
- return m_data;
-}
+ void appendToCharacter(UChar character)
+ {
+ ASSERT(m_type == Character);
+ m_data.append(character);
+ m_orAllData |= character;
+ }
-inline bool HTMLToken::charactersIsAll8BitData() const
-{
- ASSERT(m_type == Character);
- return m_data8BitCheck <= 0xFF;
-}
+ void appendToCharacter(const Vector<LChar, 32>& characters)
+ {
+ ASSERT(m_type == Character);
+ m_data.appendVector(characters);
+ }
-inline void HTMLToken::appendToCharacter(LChar character)
-{
- ASSERT(m_type == Uninitialized || m_type == Character);
- m_type = Character;
- m_data.append(character);
-}
+ /* Comment Tokens */
-inline void HTMLToken::appendToCharacter(UChar character)
-{
- ASSERT(m_type == Uninitialized || m_type == Character);
- m_type = Character;
- m_data.append(character);
- m_data8BitCheck |= character;
-}
+ const DataVector& comment() const
+ {
+ ASSERT(m_type == Comment);
+ return m_data;
+ }
-inline void HTMLToken::appendToCharacter(const Vector<LChar, 32>& characters)
-{
- ASSERT(m_type == Uninitialized || m_type == Character);
- m_type = Character;
- m_data.appendVector(characters);
-}
+ void beginComment()
+ {
+ ASSERT(m_type == Uninitialized);
+ m_type = Comment;
+ }
-inline const HTMLToken::DataVector& HTMLToken::comment() const
-{
- ASSERT(m_type == Comment);
- return m_data;
-}
+ void appendToComment(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == Comment);
+ m_data.append(character);
+ m_orAllData |= character;
+ }
-inline bool HTMLToken::commentIsAll8BitData() const
-{
- ASSERT(m_type == Comment);
- return m_data8BitCheck <= 0xFF;
-}
+ void eraseCharacters()
+ {
+ ASSERT(m_type == Character);
+ m_data.clear();
+ m_orAllData = 0;
+ }
-inline void HTMLToken::beginComment()
-{
- ASSERT(m_type == Uninitialized);
- m_type = Comment;
-}
+private:
+ Type m_type;
+ Attribute::Range m_range; // Always starts at zero.
+ int m_baseOffset;
+ DataVector m_data;
+ UChar m_orAllData;
-inline void HTMLToken::appendToComment(UChar character)
-{
- ASSERT(character);
- ASSERT(m_type == Comment);
- m_data.append(character);
- m_data8BitCheck |= character;
-}
+ // For StartTag and EndTag
+ bool m_selfClosing;
+ AttributeList m_attributes;
-inline bool nameMatches(const HTMLToken::Attribute& attribute, StringView name)
-{
- unsigned size = name.length();
- if (attribute.name.size() != size)
- return false;
- for (unsigned i = 0; i < size; ++i) {
- // FIXME: The one caller that uses this probably wants to ignore letter case.
- if (attribute.name[i] != name[i])
- return false;
- }
- return true;
-}
+ // A pointer into m_attributes used during lexing.
+ Attribute* m_currentAttribute;
-inline const HTMLToken::Attribute* findAttribute(const HTMLToken::AttributeList& attributes, StringView name)
-{
- for (auto& attribute : attributes) {
- if (nameMatches(attribute, name))
- return &attribute;
- }
- return nullptr;
-}
+ // For DOCTYPE
+ std::unique_ptr<DoctypeData> m_doctypeData;
+};
}
diff --git a/Source/WebCore/html/parser/HTMLTokenizer.cpp b/Source/WebCore/html/parser/HTMLTokenizer.cpp
index 489e6c51a..2abefaf68 100644
--- a/Source/WebCore/html/parser/HTMLTokenizer.cpp
+++ b/Source/WebCore/html/parser/HTMLTokenizer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2015 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
* Copyright (C) 2009 Torch Mobile, Inc. http://www.torchmobile.com/
* Copyright (C) 2010 Google, Inc. All Rights Reserved.
*
@@ -29,9 +29,13 @@
#include "HTMLTokenizer.h"
#include "HTMLEntityParser.h"
-#include "HTMLNames.h"
+#include "HTMLTreeBuilder.h"
#include "MarkupTokenizerInlines.h"
+#include "NotImplemented.h"
#include <wtf/ASCIICType.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+#include <wtf/unicode/Unicode.h>
using namespace WTF;
@@ -39,95 +43,81 @@ namespace WebCore {
using namespace HTMLNames;
-static inline LChar convertASCIIAlphaToLower(UChar character)
+// This has to go in a .cpp file, as the linker doesn't like it being included more than once.
+// We don't have an HTMLToken.cpp though, so this is the next best place.
+QualifiedName AtomicHTMLToken::nameForAttribute(const HTMLToken::Attribute& attribute) const
{
- ASSERT(isASCIIAlpha(character));
- return toASCIILowerUnchecked(character);
+ return QualifiedName(nullAtom, AtomicString(attribute.name), nullAtom);
}
-static inline bool vectorEqualsString(const Vector<LChar, 32>& vector, const char* string)
+bool AtomicHTMLToken::usesName() const
{
- unsigned size = vector.size();
- for (unsigned i = 0; i < size; ++i) {
- if (!string[i] || vector[i] != string[i])
- return false;
- }
- return !string[size];
+ return m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag || m_type == HTMLToken::DOCTYPE;
}
-inline bool HTMLTokenizer::inEndTagBufferingState() const
+bool AtomicHTMLToken::usesAttributes() const
{
- switch (m_state) {
- case RCDATAEndTagOpenState:
- case RCDATAEndTagNameState:
- case RAWTEXTEndTagOpenState:
- case RAWTEXTEndTagNameState:
- case ScriptDataEndTagOpenState:
- case ScriptDataEndTagNameState:
- case ScriptDataEscapedEndTagOpenState:
- case ScriptDataEscapedEndTagNameState:
- return true;
- default:
- return false;
- }
+ return m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag;
}
-HTMLTokenizer::HTMLTokenizer(const HTMLParserOptions& options)
- : m_preprocessor(*this)
- , m_options(options)
+static inline UChar toLowerCase(UChar cc)
{
+ ASSERT(isASCIIUpper(cc));
+ const int lowerCaseOffset = 0x20;
+ return cc + lowerCaseOffset;
}
-inline void HTMLTokenizer::bufferASCIICharacter(UChar character)
+static inline bool vectorEqualsString(const Vector<LChar, 32>& vector, const String& string)
{
- ASSERT(character != kEndOfFileMarker);
- ASSERT(isASCII(character));
- LChar narrowedCharacter = character;
- m_token.appendToCharacter(narrowedCharacter);
-}
+ if (vector.size() != string.length())
+ return false;
-inline void HTMLTokenizer::bufferCharacter(UChar character)
-{
- ASSERT(character != kEndOfFileMarker);
- m_token.appendToCharacter(character);
-}
+ if (!string.length())
+ return true;
-inline bool HTMLTokenizer::emitAndResumeInDataState(SegmentedString& source)
-{
- saveEndTagNameIfNeeded();
- m_state = DataState;
- source.advanceAndUpdateLineNumber();
- return true;
+ return equal(string.impl(), vector.data(), vector.size());
}
-inline bool HTMLTokenizer::emitAndReconsumeInDataState()
+static inline bool isEndTagBufferingState(HTMLTokenizer::State state)
{
- saveEndTagNameIfNeeded();
- m_state = DataState;
- return true;
+ switch (state) {
+ case HTMLTokenizer::RCDATAEndTagOpenState:
+ case HTMLTokenizer::RCDATAEndTagNameState:
+ case HTMLTokenizer::RAWTEXTEndTagOpenState:
+ case HTMLTokenizer::RAWTEXTEndTagNameState:
+ case HTMLTokenizer::ScriptDataEndTagOpenState:
+ case HTMLTokenizer::ScriptDataEndTagNameState:
+ case HTMLTokenizer::ScriptDataEscapedEndTagOpenState:
+ case HTMLTokenizer::ScriptDataEscapedEndTagNameState:
+ return true;
+ default:
+ return false;
+ }
}
-inline bool HTMLTokenizer::emitEndOfFile(SegmentedString& source)
+#define HTML_BEGIN_STATE(stateName) BEGIN_STATE(HTMLTokenizer, stateName)
+#define HTML_RECONSUME_IN(stateName) RECONSUME_IN(HTMLTokenizer, stateName)
+#define HTML_ADVANCE_TO(stateName) ADVANCE_TO(HTMLTokenizer, stateName)
+#define HTML_SWITCH_TO(stateName) SWITCH_TO(HTMLTokenizer, stateName)
+
+HTMLTokenizer::HTMLTokenizer(const HTMLParserOptions& options)
+ : m_inputStreamPreprocessor(this)
+ , m_options(options)
{
- m_state = DataState;
- if (haveBufferedCharacterToken())
- return true;
- source.advance();
- m_token.clear();
- m_token.makeEndOfFile();
- return true;
+ reset();
}
-inline void HTMLTokenizer::saveEndTagNameIfNeeded()
+HTMLTokenizer::~HTMLTokenizer()
{
- ASSERT(m_token.type() != HTMLToken::Uninitialized);
- if (m_token.type() == HTMLToken::StartTag)
- m_appropriateEndTagName = m_token.name();
}
-inline bool HTMLTokenizer::haveBufferedCharacterToken() const
+void HTMLTokenizer::reset()
{
- return m_token.type() == HTMLToken::Character;
+ m_state = HTMLTokenizer::DataState;
+ m_token = 0;
+ m_forceNullCharacterReplacement = false;
+ m_shouldAllowCDATA = false;
+ m_additionalAllowedCharacter = '\0';
}
inline bool HTMLTokenizer::processEntity(SegmentedString& source)
@@ -139,7 +129,7 @@ inline bool HTMLTokenizer::processEntity(SegmentedString& source)
return false;
if (!success) {
ASSERT(decodedEntity.isEmpty());
- bufferASCIICharacter('&');
+ bufferCharacter('&');
} else {
for (unsigned i = 0; i < decodedEntity.length(); ++i)
bufferCharacter(decodedEntity[i]);
@@ -147,1246 +137,1426 @@ inline bool HTMLTokenizer::processEntity(SegmentedString& source)
return true;
}
-void HTMLTokenizer::flushBufferedEndTag()
+bool HTMLTokenizer::flushBufferedEndTag(SegmentedString& source)
{
- m_token.beginEndTag(m_bufferedEndTagName);
+ ASSERT(m_token->type() == HTMLToken::Character || m_token->type() == HTMLToken::Uninitialized);
+ source.advanceAndUpdateLineNumber();
+ if (m_token->type() == HTMLToken::Character)
+ return true;
+ m_token->beginEndTag(m_bufferedEndTagName);
m_bufferedEndTagName.clear();
m_appropriateEndTagName.clear();
m_temporaryBuffer.clear();
-}
-
-bool HTMLTokenizer::commitToPartialEndTag(SegmentedString& source, UChar character, State state)
-{
- ASSERT(source.currentChar() == character);
- appendToTemporaryBuffer(character);
- source.advanceAndUpdateLineNumber();
-
- if (haveBufferedCharacterToken()) {
- // Emit the buffered character token.
- // The next call to processToken will flush the buffered end tag and continue parsing it.
- m_state = state;
- return true;
- }
-
- flushBufferedEndTag();
return false;
}
-bool HTMLTokenizer::commitToCompleteEndTag(SegmentedString& source)
+#define FLUSH_AND_ADVANCE_TO(stateName) \
+ do { \
+ m_state = HTMLTokenizer::stateName; \
+ if (flushBufferedEndTag(source)) \
+ return true; \
+ if (source.isEmpty() \
+ || !m_inputStreamPreprocessor.peek(source)) \
+ return haveBufferedCharacterToken(); \
+ cc = m_inputStreamPreprocessor.nextInputCharacter(); \
+ goto stateName; \
+ } while (false)
+
+bool HTMLTokenizer::flushEmitAndResumeIn(SegmentedString& source, HTMLTokenizer::State state)
{
- ASSERT(source.currentChar() == '>');
- appendToTemporaryBuffer('>');
- source.advance();
-
- m_state = DataState;
-
- if (haveBufferedCharacterToken()) {
- // Emit the character token we already have.
- // The next call to processToken will flush the buffered end tag and emit it.
- return true;
- }
-
- flushBufferedEndTag();
+ m_state = state;
+ flushBufferedEndTag(source);
return true;
}
-bool HTMLTokenizer::processToken(SegmentedString& source)
+bool HTMLTokenizer::nextToken(SegmentedString& source, HTMLToken& token)
{
- if (!m_bufferedEndTagName.isEmpty() && !inEndTagBufferingState()) {
- // We are back here after emitting a character token that came just before an end tag.
- // To continue parsing the end tag we need to move the buffered tag name into the token.
- flushBufferedEndTag();
-
- // If we are in the data state, the end tag is already complete and we should emit it
- // now, otherwise, we want to resume parsing the partial end tag.
- if (m_state == DataState)
+ // If we have a token in progress, then we're supposed to be called back
+ // with the same token so we can finish it.
+ ASSERT(!m_token || m_token == &token || token.type() == HTMLToken::Uninitialized);
+ m_token = &token;
+
+ if (!m_bufferedEndTagName.isEmpty() && !isEndTagBufferingState(m_state)) {
+ // FIXME: This should call flushBufferedEndTag().
+ // We started an end tag during our last iteration.
+ m_token->beginEndTag(m_bufferedEndTagName);
+ m_bufferedEndTagName.clear();
+ m_appropriateEndTagName.clear();
+ m_temporaryBuffer.clear();
+ if (m_state == HTMLTokenizer::DataState) {
+ // We're back in the data state, so we must be done with the tag.
return true;
+ }
}
- if (!m_preprocessor.peek(source, isNullCharacterSkippingState(m_state)))
+ if (source.isEmpty() || !m_inputStreamPreprocessor.peek(source))
return haveBufferedCharacterToken();
- UChar character = m_preprocessor.nextInputCharacter();
+ UChar cc = m_inputStreamPreprocessor.nextInputCharacter();
- // https://html.spec.whatwg.org/#tokenization
+ // Source: http://www.whatwg.org/specs/web-apps/current-work/#tokenisation0
switch (m_state) {
-
- BEGIN_STATE(DataState)
- if (character == '&')
- ADVANCE_TO(CharacterReferenceInDataState);
- if (character == '<') {
- if (haveBufferedCharacterToken())
- RETURN_IN_CURRENT_STATE(true);
- ADVANCE_TO(TagOpenState);
- }
- if (character == kEndOfFileMarker)
+ HTML_BEGIN_STATE(DataState) {
+ if (cc == '&')
+ HTML_ADVANCE_TO(CharacterReferenceInDataState);
+ else if (cc == '<') {
+ if (m_token->type() == HTMLToken::Character) {
+ // We have a bunch of character tokens queued up that we
+ // are emitting lazily here.
+ return true;
+ }
+ HTML_ADVANCE_TO(TagOpenState);
+ } else if (cc == kEndOfFileMarker)
return emitEndOfFile(source);
- bufferCharacter(character);
- ADVANCE_TO(DataState);
+ else {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(DataState);
+ }
+ }
END_STATE()
- BEGIN_STATE(CharacterReferenceInDataState)
+ HTML_BEGIN_STATE(CharacterReferenceInDataState) {
if (!processEntity(source))
- RETURN_IN_CURRENT_STATE(haveBufferedCharacterToken());
- SWITCH_TO(DataState);
+ return haveBufferedCharacterToken();
+ HTML_SWITCH_TO(DataState);
+ }
END_STATE()
- BEGIN_STATE(RCDATAState)
- if (character == '&')
- ADVANCE_TO(CharacterReferenceInRCDATAState);
- if (character == '<')
- ADVANCE_TO(RCDATALessThanSignState);
- if (character == kEndOfFileMarker)
- RECONSUME_IN(DataState);
- bufferCharacter(character);
- ADVANCE_TO(RCDATAState);
+ HTML_BEGIN_STATE(RCDATAState) {
+ if (cc == '&')
+ HTML_ADVANCE_TO(CharacterReferenceInRCDATAState);
+ else if (cc == '<')
+ HTML_ADVANCE_TO(RCDATALessThanSignState);
+ else if (cc == kEndOfFileMarker)
+ return emitEndOfFile(source);
+ else {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(RCDATAState);
+ }
+ }
END_STATE()
- BEGIN_STATE(CharacterReferenceInRCDATAState)
+ HTML_BEGIN_STATE(CharacterReferenceInRCDATAState) {
if (!processEntity(source))
- RETURN_IN_CURRENT_STATE(haveBufferedCharacterToken());
- SWITCH_TO(RCDATAState);
- END_STATE()
-
- BEGIN_STATE(RAWTEXTState)
- if (character == '<')
- ADVANCE_TO(RAWTEXTLessThanSignState);
- if (character == kEndOfFileMarker)
- RECONSUME_IN(DataState);
- bufferCharacter(character);
- ADVANCE_TO(RAWTEXTState);
- END_STATE()
-
- BEGIN_STATE(ScriptDataState)
- if (character == '<')
- ADVANCE_TO(ScriptDataLessThanSignState);
- if (character == kEndOfFileMarker)
- RECONSUME_IN(DataState);
- bufferCharacter(character);
- ADVANCE_TO(ScriptDataState);
- END_STATE()
-
- BEGIN_STATE(PLAINTEXTState)
- if (character == kEndOfFileMarker)
- RECONSUME_IN(DataState);
- bufferCharacter(character);
- ADVANCE_TO(PLAINTEXTState);
- END_STATE()
-
- BEGIN_STATE(TagOpenState)
- if (character == '!')
- ADVANCE_TO(MarkupDeclarationOpenState);
- if (character == '/')
- ADVANCE_TO(EndTagOpenState);
- if (isASCIIAlpha(character)) {
- m_token.beginStartTag(convertASCIIAlphaToLower(character));
- ADVANCE_TO(TagNameState);
+ return haveBufferedCharacterToken();
+ HTML_SWITCH_TO(RCDATAState);
+ }
+ END_STATE()
+
+ HTML_BEGIN_STATE(RAWTEXTState) {
+ if (cc == '<')
+ HTML_ADVANCE_TO(RAWTEXTLessThanSignState);
+ else if (cc == kEndOfFileMarker)
+ return emitEndOfFile(source);
+ else {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(RAWTEXTState);
+ }
+ }
+ END_STATE()
+
+ HTML_BEGIN_STATE(ScriptDataState) {
+ if (cc == '<')
+ HTML_ADVANCE_TO(ScriptDataLessThanSignState);
+ else if (cc == kEndOfFileMarker)
+ return emitEndOfFile(source);
+ else {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataState);
}
- if (character == '?') {
+ }
+ END_STATE()
+
+ HTML_BEGIN_STATE(PLAINTEXTState) {
+ if (cc == kEndOfFileMarker)
+ return emitEndOfFile(source);
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(PLAINTEXTState);
+ }
+ END_STATE()
+
+ HTML_BEGIN_STATE(TagOpenState) {
+ if (cc == '!')
+ HTML_ADVANCE_TO(MarkupDeclarationOpenState);
+ else if (cc == '/')
+ HTML_ADVANCE_TO(EndTagOpenState);
+ else if (isASCIIUpper(cc)) {
+ m_token->beginStartTag(toLowerCase(cc));
+ HTML_ADVANCE_TO(TagNameState);
+ } else if (isASCIILower(cc)) {
+ m_token->beginStartTag(cc);
+ HTML_ADVANCE_TO(TagNameState);
+ } else if (cc == '?') {
parseError();
// The spec consumes the current character before switching
// to the bogus comment state, but it's easier to implement
// if we reconsume the current character.
- RECONSUME_IN(BogusCommentState);
+ HTML_RECONSUME_IN(BogusCommentState);
+ } else {
+ parseError();
+ bufferCharacter('<');
+ HTML_RECONSUME_IN(DataState);
}
- parseError();
- bufferASCIICharacter('<');
- RECONSUME_IN(DataState);
+ }
END_STATE()
- BEGIN_STATE(EndTagOpenState)
- if (isASCIIAlpha(character)) {
- m_token.beginEndTag(convertASCIIAlphaToLower(character));
+ HTML_BEGIN_STATE(EndTagOpenState) {
+ if (isASCIIUpper(cc)) {
+ m_token->beginEndTag(static_cast<LChar>(toLowerCase(cc)));
m_appropriateEndTagName.clear();
- ADVANCE_TO(TagNameState);
- }
- if (character == '>') {
+ HTML_ADVANCE_TO(TagNameState);
+ } else if (isASCIILower(cc)) {
+ m_token->beginEndTag(static_cast<LChar>(cc));
+ m_appropriateEndTagName.clear();
+ HTML_ADVANCE_TO(TagNameState);
+ } else if (cc == '>') {
parseError();
- ADVANCE_TO(DataState);
- }
- if (character == kEndOfFileMarker) {
+ HTML_ADVANCE_TO(DataState);
+ } else if (cc == kEndOfFileMarker) {
+ parseError();
+ bufferCharacter('<');
+ bufferCharacter('/');
+ HTML_RECONSUME_IN(DataState);
+ } else {
parseError();
- bufferASCIICharacter('<');
- bufferASCIICharacter('/');
- RECONSUME_IN(DataState);
+ HTML_RECONSUME_IN(BogusCommentState);
}
- parseError();
- RECONSUME_IN(BogusCommentState);
+ }
END_STATE()
- BEGIN_STATE(TagNameState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(BeforeAttributeNameState);
- if (character == '/')
- ADVANCE_TO(SelfClosingStartTagState);
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (m_options.usePreHTML5ParserQuirks && character == '<')
- return emitAndReconsumeInDataState();
- if (character == kEndOfFileMarker) {
- parseError();
- RECONSUME_IN(DataState);
+ HTML_BEGIN_STATE(TagNameState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(BeforeAttributeNameState);
+ else if (cc == '/')
+ HTML_ADVANCE_TO(SelfClosingStartTagState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (m_options.usePreHTML5ParserQuirks && cc == '<')
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ else if (isASCIIUpper(cc)) {
+ m_token->appendToName(toLowerCase(cc));
+ HTML_ADVANCE_TO(TagNameState);
+ } else if (cc == kEndOfFileMarker) {
+ parseError();
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ m_token->appendToName(cc);
+ HTML_ADVANCE_TO(TagNameState);
}
- m_token.appendToName(toASCIILower(character));
- ADVANCE_TO(TagNameState);
+ }
END_STATE()
- BEGIN_STATE(RCDATALessThanSignState)
- if (character == '/') {
+ HTML_BEGIN_STATE(RCDATALessThanSignState) {
+ if (cc == '/') {
m_temporaryBuffer.clear();
ASSERT(m_bufferedEndTagName.isEmpty());
- ADVANCE_TO(RCDATAEndTagOpenState);
+ HTML_ADVANCE_TO(RCDATAEndTagOpenState);
+ } else {
+ bufferCharacter('<');
+ HTML_RECONSUME_IN(RCDATAState);
}
- bufferASCIICharacter('<');
- RECONSUME_IN(RCDATAState);
+ }
END_STATE()
- BEGIN_STATE(RCDATAEndTagOpenState)
- if (isASCIIAlpha(character)) {
- appendToTemporaryBuffer(character);
- appendToPossibleEndTag(convertASCIIAlphaToLower(character));
- ADVANCE_TO(RCDATAEndTagNameState);
+ HTML_BEGIN_STATE(RCDATAEndTagOpenState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(toLowerCase(cc)));
+ HTML_ADVANCE_TO(RCDATAEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(cc));
+ HTML_ADVANCE_TO(RCDATAEndTagNameState);
+ } else {
+ bufferCharacter('<');
+ bufferCharacter('/');
+ HTML_RECONSUME_IN(RCDATAState);
}
- bufferASCIICharacter('<');
- bufferASCIICharacter('/');
- RECONSUME_IN(RCDATAState);
+ }
END_STATE()
- BEGIN_STATE(RCDATAEndTagNameState)
- if (isASCIIAlpha(character)) {
- appendToTemporaryBuffer(character);
- appendToPossibleEndTag(convertASCIIAlphaToLower(character));
- ADVANCE_TO(RCDATAEndTagNameState);
- }
- if (isTokenizerWhitespace(character)) {
- if (isAppropriateEndTag()) {
- if (commitToPartialEndTag(source, character, BeforeAttributeNameState))
- return true;
- SWITCH_TO(BeforeAttributeNameState);
- }
- } else if (character == '/') {
- if (isAppropriateEndTag()) {
- if (commitToPartialEndTag(source, '/', SelfClosingStartTagState))
- return true;
- SWITCH_TO(SelfClosingStartTagState);
+ HTML_BEGIN_STATE(RCDATAEndTagNameState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(toLowerCase(cc)));
+ HTML_ADVANCE_TO(RCDATAEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(cc));
+ HTML_ADVANCE_TO(RCDATAEndTagNameState);
+ } else {
+ if (isTokenizerWhitespace(cc)) {
+ if (isAppropriateEndTag()) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ FLUSH_AND_ADVANCE_TO(BeforeAttributeNameState);
+ }
+ } else if (cc == '/') {
+ if (isAppropriateEndTag()) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ FLUSH_AND_ADVANCE_TO(SelfClosingStartTagState);
+ }
+ } else if (cc == '>') {
+ if (isAppropriateEndTag()) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ return flushEmitAndResumeIn(source, HTMLTokenizer::DataState);
+ }
}
- } else if (character == '>') {
- if (isAppropriateEndTag())
- return commitToCompleteEndTag(source);
+ bufferCharacter('<');
+ bufferCharacter('/');
+ m_token->appendToCharacter(m_temporaryBuffer);
+ m_bufferedEndTagName.clear();
+ m_temporaryBuffer.clear();
+ HTML_RECONSUME_IN(RCDATAState);
}
- bufferASCIICharacter('<');
- bufferASCIICharacter('/');
- m_token.appendToCharacter(m_temporaryBuffer);
- m_bufferedEndTagName.clear();
- m_temporaryBuffer.clear();
- RECONSUME_IN(RCDATAState);
+ }
END_STATE()
- BEGIN_STATE(RAWTEXTLessThanSignState)
- if (character == '/') {
+ HTML_BEGIN_STATE(RAWTEXTLessThanSignState) {
+ if (cc == '/') {
m_temporaryBuffer.clear();
ASSERT(m_bufferedEndTagName.isEmpty());
- ADVANCE_TO(RAWTEXTEndTagOpenState);
+ HTML_ADVANCE_TO(RAWTEXTEndTagOpenState);
+ } else {
+ bufferCharacter('<');
+ HTML_RECONSUME_IN(RAWTEXTState);
}
- bufferASCIICharacter('<');
- RECONSUME_IN(RAWTEXTState);
+ }
END_STATE()
- BEGIN_STATE(RAWTEXTEndTagOpenState)
- if (isASCIIAlpha(character)) {
- appendToTemporaryBuffer(character);
- appendToPossibleEndTag(convertASCIIAlphaToLower(character));
- ADVANCE_TO(RAWTEXTEndTagNameState);
+ HTML_BEGIN_STATE(RAWTEXTEndTagOpenState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(toLowerCase(cc)));
+ HTML_ADVANCE_TO(RAWTEXTEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(cc));
+ HTML_ADVANCE_TO(RAWTEXTEndTagNameState);
+ } else {
+ bufferCharacter('<');
+ bufferCharacter('/');
+ HTML_RECONSUME_IN(RAWTEXTState);
}
- bufferASCIICharacter('<');
- bufferASCIICharacter('/');
- RECONSUME_IN(RAWTEXTState);
+ }
END_STATE()
- BEGIN_STATE(RAWTEXTEndTagNameState)
- if (isASCIIAlpha(character)) {
- appendToTemporaryBuffer(character);
- appendToPossibleEndTag(convertASCIIAlphaToLower(character));
- ADVANCE_TO(RAWTEXTEndTagNameState);
- }
- if (isTokenizerWhitespace(character)) {
- if (isAppropriateEndTag()) {
- if (commitToPartialEndTag(source, character, BeforeAttributeNameState))
- return true;
- SWITCH_TO(BeforeAttributeNameState);
- }
- } else if (character == '/') {
- if (isAppropriateEndTag()) {
- if (commitToPartialEndTag(source, '/', SelfClosingStartTagState))
- return true;
- SWITCH_TO(SelfClosingStartTagState);
+ HTML_BEGIN_STATE(RAWTEXTEndTagNameState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(toLowerCase(cc)));
+ HTML_ADVANCE_TO(RAWTEXTEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(cc));
+ HTML_ADVANCE_TO(RAWTEXTEndTagNameState);
+ } else {
+ if (isTokenizerWhitespace(cc)) {
+ if (isAppropriateEndTag()) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ FLUSH_AND_ADVANCE_TO(BeforeAttributeNameState);
+ }
+ } else if (cc == '/') {
+ if (isAppropriateEndTag()) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ FLUSH_AND_ADVANCE_TO(SelfClosingStartTagState);
+ }
+ } else if (cc == '>') {
+ if (isAppropriateEndTag()) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ return flushEmitAndResumeIn(source, HTMLTokenizer::DataState);
+ }
}
- } else if (character == '>') {
- if (isAppropriateEndTag())
- return commitToCompleteEndTag(source);
+ bufferCharacter('<');
+ bufferCharacter('/');
+ m_token->appendToCharacter(m_temporaryBuffer);
+ m_bufferedEndTagName.clear();
+ m_temporaryBuffer.clear();
+ HTML_RECONSUME_IN(RAWTEXTState);
}
- bufferASCIICharacter('<');
- bufferASCIICharacter('/');
- m_token.appendToCharacter(m_temporaryBuffer);
- m_bufferedEndTagName.clear();
- m_temporaryBuffer.clear();
- RECONSUME_IN(RAWTEXTState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataLessThanSignState)
- if (character == '/') {
+ HTML_BEGIN_STATE(ScriptDataLessThanSignState) {
+ if (cc == '/') {
m_temporaryBuffer.clear();
ASSERT(m_bufferedEndTagName.isEmpty());
- ADVANCE_TO(ScriptDataEndTagOpenState);
- }
- if (character == '!') {
- bufferASCIICharacter('<');
- bufferASCIICharacter('!');
- ADVANCE_TO(ScriptDataEscapeStartState);
+ HTML_ADVANCE_TO(ScriptDataEndTagOpenState);
+ } else if (cc == '!') {
+ bufferCharacter('<');
+ bufferCharacter('!');
+ HTML_ADVANCE_TO(ScriptDataEscapeStartState);
+ } else {
+ bufferCharacter('<');
+ HTML_RECONSUME_IN(ScriptDataState);
}
- bufferASCIICharacter('<');
- RECONSUME_IN(ScriptDataState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataEndTagOpenState)
- if (isASCIIAlpha(character)) {
- appendToTemporaryBuffer(character);
- appendToPossibleEndTag(convertASCIIAlphaToLower(character));
- ADVANCE_TO(ScriptDataEndTagNameState);
+ HTML_BEGIN_STATE(ScriptDataEndTagOpenState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(toLowerCase(cc)));
+ HTML_ADVANCE_TO(ScriptDataEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(cc));
+ HTML_ADVANCE_TO(ScriptDataEndTagNameState);
+ } else {
+ bufferCharacter('<');
+ bufferCharacter('/');
+ HTML_RECONSUME_IN(ScriptDataState);
}
- bufferASCIICharacter('<');
- bufferASCIICharacter('/');
- RECONSUME_IN(ScriptDataState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataEndTagNameState)
- if (isASCIIAlpha(character)) {
- appendToTemporaryBuffer(character);
- appendToPossibleEndTag(convertASCIIAlphaToLower(character));
- ADVANCE_TO(ScriptDataEndTagNameState);
- }
- if (isTokenizerWhitespace(character)) {
- if (isAppropriateEndTag()) {
- if (commitToPartialEndTag(source, character, BeforeAttributeNameState))
- return true;
- SWITCH_TO(BeforeAttributeNameState);
- }
- } else if (character == '/') {
- if (isAppropriateEndTag()) {
- if (commitToPartialEndTag(source, '/', SelfClosingStartTagState))
- return true;
- SWITCH_TO(SelfClosingStartTagState);
+ HTML_BEGIN_STATE(ScriptDataEndTagNameState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(toLowerCase(cc)));
+ HTML_ADVANCE_TO(ScriptDataEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(cc));
+ HTML_ADVANCE_TO(ScriptDataEndTagNameState);
+ } else {
+ if (isTokenizerWhitespace(cc)) {
+ if (isAppropriateEndTag()) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ FLUSH_AND_ADVANCE_TO(BeforeAttributeNameState);
+ }
+ } else if (cc == '/') {
+ if (isAppropriateEndTag()) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ FLUSH_AND_ADVANCE_TO(SelfClosingStartTagState);
+ }
+ } else if (cc == '>') {
+ if (isAppropriateEndTag()) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ return flushEmitAndResumeIn(source, HTMLTokenizer::DataState);
+ }
}
- } else if (character == '>') {
- if (isAppropriateEndTag())
- return commitToCompleteEndTag(source);
+ bufferCharacter('<');
+ bufferCharacter('/');
+ m_token->appendToCharacter(m_temporaryBuffer);
+ m_bufferedEndTagName.clear();
+ m_temporaryBuffer.clear();
+ HTML_RECONSUME_IN(ScriptDataState);
}
- bufferASCIICharacter('<');
- bufferASCIICharacter('/');
- m_token.appendToCharacter(m_temporaryBuffer);
- m_bufferedEndTagName.clear();
- m_temporaryBuffer.clear();
- RECONSUME_IN(ScriptDataState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataEscapeStartState)
- if (character == '-') {
- bufferASCIICharacter('-');
- ADVANCE_TO(ScriptDataEscapeStartDashState);
+ HTML_BEGIN_STATE(ScriptDataEscapeStartState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataEscapeStartDashState);
} else
- RECONSUME_IN(ScriptDataState);
+ HTML_RECONSUME_IN(ScriptDataState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataEscapeStartDashState)
- if (character == '-') {
- bufferASCIICharacter('-');
- ADVANCE_TO(ScriptDataEscapedDashDashState);
+ HTML_BEGIN_STATE(ScriptDataEscapeStartDashState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataEscapedDashDashState);
} else
- RECONSUME_IN(ScriptDataState);
+ HTML_RECONSUME_IN(ScriptDataState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataEscapedState)
- if (character == '-') {
- bufferASCIICharacter('-');
- ADVANCE_TO(ScriptDataEscapedDashState);
- }
- if (character == '<')
- ADVANCE_TO(ScriptDataEscapedLessThanSignState);
- if (character == kEndOfFileMarker) {
+ HTML_BEGIN_STATE(ScriptDataEscapedState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataEscapedDashState);
+ } else if (cc == '<')
+ HTML_ADVANCE_TO(ScriptDataEscapedLessThanSignState);
+ else if (cc == kEndOfFileMarker) {
parseError();
- RECONSUME_IN(DataState);
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataEscapedState);
}
- bufferCharacter(character);
- ADVANCE_TO(ScriptDataEscapedState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataEscapedDashState)
- if (character == '-') {
- bufferASCIICharacter('-');
- ADVANCE_TO(ScriptDataEscapedDashDashState);
- }
- if (character == '<')
- ADVANCE_TO(ScriptDataEscapedLessThanSignState);
- if (character == kEndOfFileMarker) {
+ HTML_BEGIN_STATE(ScriptDataEscapedDashState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataEscapedDashDashState);
+ } else if (cc == '<')
+ HTML_ADVANCE_TO(ScriptDataEscapedLessThanSignState);
+ else if (cc == kEndOfFileMarker) {
parseError();
- RECONSUME_IN(DataState);
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataEscapedState);
}
- bufferCharacter(character);
- ADVANCE_TO(ScriptDataEscapedState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataEscapedDashDashState)
- if (character == '-') {
- bufferASCIICharacter('-');
- ADVANCE_TO(ScriptDataEscapedDashDashState);
- }
- if (character == '<')
- ADVANCE_TO(ScriptDataEscapedLessThanSignState);
- if (character == '>') {
- bufferASCIICharacter('>');
- ADVANCE_TO(ScriptDataState);
- }
- if (character == kEndOfFileMarker) {
+ HTML_BEGIN_STATE(ScriptDataEscapedDashDashState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataEscapedDashDashState);
+ } else if (cc == '<')
+ HTML_ADVANCE_TO(ScriptDataEscapedLessThanSignState);
+ else if (cc == '>') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- RECONSUME_IN(DataState);
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataEscapedState);
}
- bufferCharacter(character);
- ADVANCE_TO(ScriptDataEscapedState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataEscapedLessThanSignState)
- if (character == '/') {
+ HTML_BEGIN_STATE(ScriptDataEscapedLessThanSignState) {
+ if (cc == '/') {
m_temporaryBuffer.clear();
ASSERT(m_bufferedEndTagName.isEmpty());
- ADVANCE_TO(ScriptDataEscapedEndTagOpenState);
- }
- if (isASCIIAlpha(character)) {
- bufferASCIICharacter('<');
- bufferASCIICharacter(character);
+ HTML_ADVANCE_TO(ScriptDataEscapedEndTagOpenState);
+ } else if (isASCIIUpper(cc)) {
+ bufferCharacter('<');
+ bufferCharacter(cc);
+ m_temporaryBuffer.clear();
+ m_temporaryBuffer.append(toLowerCase(cc));
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapeStartState);
+ } else if (isASCIILower(cc)) {
+ bufferCharacter('<');
+ bufferCharacter(cc);
m_temporaryBuffer.clear();
- appendToTemporaryBuffer(convertASCIIAlphaToLower(character));
- ADVANCE_TO(ScriptDataDoubleEscapeStartState);
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapeStartState);
+ } else {
+ bufferCharacter('<');
+ HTML_RECONSUME_IN(ScriptDataEscapedState);
}
- bufferASCIICharacter('<');
- RECONSUME_IN(ScriptDataEscapedState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataEscapedEndTagOpenState)
- if (isASCIIAlpha(character)) {
- appendToTemporaryBuffer(character);
- appendToPossibleEndTag(convertASCIIAlphaToLower(character));
- ADVANCE_TO(ScriptDataEscapedEndTagNameState);
+ HTML_BEGIN_STATE(ScriptDataEscapedEndTagOpenState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(toLowerCase(cc)));
+ HTML_ADVANCE_TO(ScriptDataEscapedEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(cc));
+ HTML_ADVANCE_TO(ScriptDataEscapedEndTagNameState);
+ } else {
+ bufferCharacter('<');
+ bufferCharacter('/');
+ HTML_RECONSUME_IN(ScriptDataEscapedState);
}
- bufferASCIICharacter('<');
- bufferASCIICharacter('/');
- RECONSUME_IN(ScriptDataEscapedState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataEscapedEndTagNameState)
- if (isASCIIAlpha(character)) {
- appendToTemporaryBuffer(character);
- appendToPossibleEndTag(convertASCIIAlphaToLower(character));
- ADVANCE_TO(ScriptDataEscapedEndTagNameState);
- }
- if (isTokenizerWhitespace(character)) {
- if (isAppropriateEndTag()) {
- if (commitToPartialEndTag(source, character, BeforeAttributeNameState))
- return true;
- SWITCH_TO(BeforeAttributeNameState);
- }
- } else if (character == '/') {
- if (isAppropriateEndTag()) {
- if (commitToPartialEndTag(source, '/', SelfClosingStartTagState))
- return true;
- SWITCH_TO(SelfClosingStartTagState);
+ HTML_BEGIN_STATE(ScriptDataEscapedEndTagNameState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(toLowerCase(cc)));
+ HTML_ADVANCE_TO(ScriptDataEscapedEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ addToPossibleEndTag(static_cast<LChar>(cc));
+ HTML_ADVANCE_TO(ScriptDataEscapedEndTagNameState);
+ } else {
+ if (isTokenizerWhitespace(cc)) {
+ if (isAppropriateEndTag()) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ FLUSH_AND_ADVANCE_TO(BeforeAttributeNameState);
+ }
+ } else if (cc == '/') {
+ if (isAppropriateEndTag()) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ FLUSH_AND_ADVANCE_TO(SelfClosingStartTagState);
+ }
+ } else if (cc == '>') {
+ if (isAppropriateEndTag()) {
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ return flushEmitAndResumeIn(source, HTMLTokenizer::DataState);
+ }
}
- } else if (character == '>') {
- if (isAppropriateEndTag())
- return commitToCompleteEndTag(source);
+ bufferCharacter('<');
+ bufferCharacter('/');
+ m_token->appendToCharacter(m_temporaryBuffer);
+ m_bufferedEndTagName.clear();
+ m_temporaryBuffer.clear();
+ HTML_RECONSUME_IN(ScriptDataEscapedState);
}
- bufferASCIICharacter('<');
- bufferASCIICharacter('/');
- m_token.appendToCharacter(m_temporaryBuffer);
- m_bufferedEndTagName.clear();
- m_temporaryBuffer.clear();
- RECONSUME_IN(ScriptDataEscapedState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataDoubleEscapeStartState)
- if (isTokenizerWhitespace(character) || character == '/' || character == '>') {
- bufferASCIICharacter(character);
- if (temporaryBufferIs("script"))
- ADVANCE_TO(ScriptDataDoubleEscapedState);
+ HTML_BEGIN_STATE(ScriptDataDoubleEscapeStartState) {
+ if (isTokenizerWhitespace(cc) || cc == '/' || cc == '>') {
+ bufferCharacter(cc);
+ if (temporaryBufferIs(scriptTag.localName()))
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapedState);
else
- ADVANCE_TO(ScriptDataEscapedState);
- }
- if (isASCIIAlpha(character)) {
- bufferASCIICharacter(character);
- appendToTemporaryBuffer(convertASCIIAlphaToLower(character));
- ADVANCE_TO(ScriptDataDoubleEscapeStartState);
- }
- RECONSUME_IN(ScriptDataEscapedState);
+ HTML_ADVANCE_TO(ScriptDataEscapedState);
+ } else if (isASCIIUpper(cc)) {
+ bufferCharacter(cc);
+ m_temporaryBuffer.append(toLowerCase(cc));
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapeStartState);
+ } else if (isASCIILower(cc)) {
+ bufferCharacter(cc);
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapeStartState);
+ } else
+ HTML_RECONSUME_IN(ScriptDataEscapedState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataDoubleEscapedState)
- if (character == '-') {
- bufferASCIICharacter('-');
- ADVANCE_TO(ScriptDataDoubleEscapedDashState);
- }
- if (character == '<') {
- bufferASCIICharacter('<');
- ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
- }
- if (character == kEndOfFileMarker) {
+ HTML_BEGIN_STATE(ScriptDataDoubleEscapedState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapedDashState);
+ } else if (cc == '<') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- RECONSUME_IN(DataState);
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapedState);
}
- bufferCharacter(character);
- ADVANCE_TO(ScriptDataDoubleEscapedState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataDoubleEscapedDashState)
- if (character == '-') {
- bufferASCIICharacter('-');
- ADVANCE_TO(ScriptDataDoubleEscapedDashDashState);
- }
- if (character == '<') {
- bufferASCIICharacter('<');
- ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
- }
- if (character == kEndOfFileMarker) {
+ HTML_BEGIN_STATE(ScriptDataDoubleEscapedDashState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapedDashDashState);
+ } else if (cc == '<') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- RECONSUME_IN(DataState);
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapedState);
}
- bufferCharacter(character);
- ADVANCE_TO(ScriptDataDoubleEscapedState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataDoubleEscapedDashDashState)
- if (character == '-') {
- bufferASCIICharacter('-');
- ADVANCE_TO(ScriptDataDoubleEscapedDashDashState);
- }
- if (character == '<') {
- bufferASCIICharacter('<');
- ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
- }
- if (character == '>') {
- bufferASCIICharacter('>');
- ADVANCE_TO(ScriptDataState);
- }
- if (character == kEndOfFileMarker) {
+ HTML_BEGIN_STATE(ScriptDataDoubleEscapedDashDashState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapedDashDashState);
+ } else if (cc == '<') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
+ } else if (cc == '>') {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- RECONSUME_IN(DataState);
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapedState);
}
- bufferCharacter(character);
- ADVANCE_TO(ScriptDataDoubleEscapedState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataDoubleEscapedLessThanSignState)
- if (character == '/') {
- bufferASCIICharacter('/');
+ HTML_BEGIN_STATE(ScriptDataDoubleEscapedLessThanSignState) {
+ if (cc == '/') {
+ bufferCharacter(cc);
m_temporaryBuffer.clear();
- ADVANCE_TO(ScriptDataDoubleEscapeEndState);
- }
- RECONSUME_IN(ScriptDataDoubleEscapedState);
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapeEndState);
+ } else
+ HTML_RECONSUME_IN(ScriptDataDoubleEscapedState);
+ }
END_STATE()
- BEGIN_STATE(ScriptDataDoubleEscapeEndState)
- if (isTokenizerWhitespace(character) || character == '/' || character == '>') {
- bufferASCIICharacter(character);
- if (temporaryBufferIs("script"))
- ADVANCE_TO(ScriptDataEscapedState);
+ HTML_BEGIN_STATE(ScriptDataDoubleEscapeEndState) {
+ if (isTokenizerWhitespace(cc) || cc == '/' || cc == '>') {
+ bufferCharacter(cc);
+ if (temporaryBufferIs(scriptTag.localName()))
+ HTML_ADVANCE_TO(ScriptDataEscapedState);
else
- ADVANCE_TO(ScriptDataDoubleEscapedState);
- }
- if (isASCIIAlpha(character)) {
- bufferASCIICharacter(character);
- appendToTemporaryBuffer(convertASCIIAlphaToLower(character));
- ADVANCE_TO(ScriptDataDoubleEscapeEndState);
- }
- RECONSUME_IN(ScriptDataDoubleEscapedState);
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapedState);
+ } else if (isASCIIUpper(cc)) {
+ bufferCharacter(cc);
+ m_temporaryBuffer.append(toLowerCase(cc));
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapeEndState);
+ } else if (isASCIILower(cc)) {
+ bufferCharacter(cc);
+ m_temporaryBuffer.append(static_cast<LChar>(cc));
+ HTML_ADVANCE_TO(ScriptDataDoubleEscapeEndState);
+ } else
+ HTML_RECONSUME_IN(ScriptDataDoubleEscapedState);
+ }
END_STATE()
- BEGIN_STATE(BeforeAttributeNameState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(BeforeAttributeNameState);
- if (character == '/')
- ADVANCE_TO(SelfClosingStartTagState);
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (m_options.usePreHTML5ParserQuirks && character == '<')
- return emitAndReconsumeInDataState();
- if (character == kEndOfFileMarker) {
- parseError();
- RECONSUME_IN(DataState);
- }
- if (character == '"' || character == '\'' || character == '<' || character == '=')
- parseError();
- m_token.beginAttribute(source.numberOfCharactersConsumed());
- m_token.appendToAttributeName(toASCIILower(character));
- ADVANCE_TO(AttributeNameState);
- END_STATE()
-
- BEGIN_STATE(AttributeNameState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(AfterAttributeNameState);
- if (character == '/')
- ADVANCE_TO(SelfClosingStartTagState);
- if (character == '=')
- ADVANCE_TO(BeforeAttributeValueState);
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (m_options.usePreHTML5ParserQuirks && character == '<')
- return emitAndReconsumeInDataState();
- if (character == kEndOfFileMarker) {
- parseError();
- RECONSUME_IN(DataState);
- }
- if (character == '"' || character == '\'' || character == '<' || character == '=')
- parseError();
- m_token.appendToAttributeName(toASCIILower(character));
- ADVANCE_TO(AttributeNameState);
- END_STATE()
-
- BEGIN_STATE(AfterAttributeNameState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(AfterAttributeNameState);
- if (character == '/')
- ADVANCE_TO(SelfClosingStartTagState);
- if (character == '=')
- ADVANCE_TO(BeforeAttributeValueState);
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (m_options.usePreHTML5ParserQuirks && character == '<')
- return emitAndReconsumeInDataState();
- if (character == kEndOfFileMarker) {
- parseError();
- RECONSUME_IN(DataState);
+ HTML_BEGIN_STATE(BeforeAttributeNameState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(BeforeAttributeNameState);
+ else if (cc == '/')
+ HTML_ADVANCE_TO(SelfClosingStartTagState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (m_options.usePreHTML5ParserQuirks && cc == '<')
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ else if (isASCIIUpper(cc)) {
+ m_token->addNewAttribute();
+ m_token->beginAttributeName(source.numberOfCharactersConsumed());
+ m_token->appendToAttributeName(toLowerCase(cc));
+ HTML_ADVANCE_TO(AttributeNameState);
+ } else if (cc == kEndOfFileMarker) {
+ parseError();
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ if (cc == '"' || cc == '\'' || cc == '<' || cc == '=')
+ parseError();
+ m_token->addNewAttribute();
+ m_token->beginAttributeName(source.numberOfCharactersConsumed());
+ m_token->appendToAttributeName(cc);
+ HTML_ADVANCE_TO(AttributeNameState);
}
- if (character == '"' || character == '\'' || character == '<')
- parseError();
- m_token.beginAttribute(source.numberOfCharactersConsumed());
- m_token.appendToAttributeName(toASCIILower(character));
- ADVANCE_TO(AttributeNameState);
+ }
END_STATE()
- BEGIN_STATE(BeforeAttributeValueState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(BeforeAttributeValueState);
- if (character == '"')
- ADVANCE_TO(AttributeValueDoubleQuotedState);
- if (character == '&')
- RECONSUME_IN(AttributeValueUnquotedState);
- if (character == '\'')
- ADVANCE_TO(AttributeValueSingleQuotedState);
- if (character == '>') {
- parseError();
- return emitAndResumeInDataState(source);
+ HTML_BEGIN_STATE(AttributeNameState) {
+ if (isTokenizerWhitespace(cc)) {
+ m_token->endAttributeName(source.numberOfCharactersConsumed());
+ HTML_ADVANCE_TO(AfterAttributeNameState);
+ } else if (cc == '/') {
+ m_token->endAttributeName(source.numberOfCharactersConsumed());
+ HTML_ADVANCE_TO(SelfClosingStartTagState);
+ } else if (cc == '=') {
+ m_token->endAttributeName(source.numberOfCharactersConsumed());
+ HTML_ADVANCE_TO(BeforeAttributeValueState);
+ } else if (cc == '>') {
+ m_token->endAttributeName(source.numberOfCharactersConsumed());
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (m_options.usePreHTML5ParserQuirks && cc == '<') {
+ m_token->endAttributeName(source.numberOfCharactersConsumed());
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else if (isASCIIUpper(cc)) {
+ m_token->appendToAttributeName(toLowerCase(cc));
+ HTML_ADVANCE_TO(AttributeNameState);
+ } else if (cc == kEndOfFileMarker) {
+ parseError();
+ m_token->endAttributeName(source.numberOfCharactersConsumed());
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ if (cc == '"' || cc == '\'' || cc == '<' || cc == '=')
+ parseError();
+ m_token->appendToAttributeName(cc);
+ HTML_ADVANCE_TO(AttributeNameState);
}
- if (character == kEndOfFileMarker) {
- parseError();
- RECONSUME_IN(DataState);
+ }
+ END_STATE()
+
+ HTML_BEGIN_STATE(AfterAttributeNameState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(AfterAttributeNameState);
+ else if (cc == '/')
+ HTML_ADVANCE_TO(SelfClosingStartTagState);
+ else if (cc == '=')
+ HTML_ADVANCE_TO(BeforeAttributeValueState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (m_options.usePreHTML5ParserQuirks && cc == '<')
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ else if (isASCIIUpper(cc)) {
+ m_token->addNewAttribute();
+ m_token->beginAttributeName(source.numberOfCharactersConsumed());
+ m_token->appendToAttributeName(toLowerCase(cc));
+ HTML_ADVANCE_TO(AttributeNameState);
+ } else if (cc == kEndOfFileMarker) {
+ parseError();
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ if (cc == '"' || cc == '\'' || cc == '<')
+ parseError();
+ m_token->addNewAttribute();
+ m_token->beginAttributeName(source.numberOfCharactersConsumed());
+ m_token->appendToAttributeName(cc);
+ HTML_ADVANCE_TO(AttributeNameState);
}
- if (character == '<' || character == '=' || character == '`')
- parseError();
- m_token.appendToAttributeValue(character);
- ADVANCE_TO(AttributeValueUnquotedState);
+ }
END_STATE()
- BEGIN_STATE(AttributeValueDoubleQuotedState)
- if (character == '"') {
- m_token.endAttribute(source.numberOfCharactersConsumed());
- ADVANCE_TO(AfterAttributeValueQuotedState);
+ HTML_BEGIN_STATE(BeforeAttributeValueState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(BeforeAttributeValueState);
+ else if (cc == '"') {
+ m_token->beginAttributeValue(source.numberOfCharactersConsumed() + 1);
+ HTML_ADVANCE_TO(AttributeValueDoubleQuotedState);
+ } else if (cc == '&') {
+ m_token->beginAttributeValue(source.numberOfCharactersConsumed());
+ HTML_RECONSUME_IN(AttributeValueUnquotedState);
+ } else if (cc == '\'') {
+ m_token->beginAttributeValue(source.numberOfCharactersConsumed() + 1);
+ HTML_ADVANCE_TO(AttributeValueSingleQuotedState);
+ } else if (cc == '>') {
+ parseError();
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
+ parseError();
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ if (cc == '<' || cc == '=' || cc == '`')
+ parseError();
+ m_token->beginAttributeValue(source.numberOfCharactersConsumed());
+ m_token->appendToAttributeValue(cc);
+ HTML_ADVANCE_TO(AttributeValueUnquotedState);
}
- if (character == '&') {
+ }
+ END_STATE()
+
+ HTML_BEGIN_STATE(AttributeValueDoubleQuotedState) {
+ if (cc == '"') {
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ HTML_ADVANCE_TO(AfterAttributeValueQuotedState);
+ } else if (cc == '&') {
m_additionalAllowedCharacter = '"';
- ADVANCE_TO(CharacterReferenceInAttributeValueState);
- }
- if (character == kEndOfFileMarker) {
+ HTML_ADVANCE_TO(CharacterReferenceInAttributeValueState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- m_token.endAttribute(source.numberOfCharactersConsumed());
- RECONSUME_IN(DataState);
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ m_token->appendToAttributeValue(cc);
+ HTML_ADVANCE_TO(AttributeValueDoubleQuotedState);
}
- m_token.appendToAttributeValue(character);
- ADVANCE_TO(AttributeValueDoubleQuotedState);
+ }
END_STATE()
- BEGIN_STATE(AttributeValueSingleQuotedState)
- if (character == '\'') {
- m_token.endAttribute(source.numberOfCharactersConsumed());
- ADVANCE_TO(AfterAttributeValueQuotedState);
- }
- if (character == '&') {
+ HTML_BEGIN_STATE(AttributeValueSingleQuotedState) {
+ if (cc == '\'') {
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ HTML_ADVANCE_TO(AfterAttributeValueQuotedState);
+ } else if (cc == '&') {
m_additionalAllowedCharacter = '\'';
- ADVANCE_TO(CharacterReferenceInAttributeValueState);
- }
- if (character == kEndOfFileMarker) {
+ HTML_ADVANCE_TO(CharacterReferenceInAttributeValueState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- m_token.endAttribute(source.numberOfCharactersConsumed());
- RECONSUME_IN(DataState);
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ m_token->appendToAttributeValue(cc);
+ HTML_ADVANCE_TO(AttributeValueSingleQuotedState);
}
- m_token.appendToAttributeValue(character);
- ADVANCE_TO(AttributeValueSingleQuotedState);
+ }
END_STATE()
- BEGIN_STATE(AttributeValueUnquotedState)
- if (isTokenizerWhitespace(character)) {
- m_token.endAttribute(source.numberOfCharactersConsumed());
- ADVANCE_TO(BeforeAttributeNameState);
- }
- if (character == '&') {
+ HTML_BEGIN_STATE(AttributeValueUnquotedState) {
+ if (isTokenizerWhitespace(cc)) {
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ HTML_ADVANCE_TO(BeforeAttributeNameState);
+ } else if (cc == '&') {
m_additionalAllowedCharacter = '>';
- ADVANCE_TO(CharacterReferenceInAttributeValueState);
- }
- if (character == '>') {
- m_token.endAttribute(source.numberOfCharactersConsumed());
- return emitAndResumeInDataState(source);
- }
- if (character == kEndOfFileMarker) {
- parseError();
- m_token.endAttribute(source.numberOfCharactersConsumed());
- RECONSUME_IN(DataState);
+ HTML_ADVANCE_TO(CharacterReferenceInAttributeValueState);
+ } else if (cc == '>') {
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
+ parseError();
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ if (cc == '"' || cc == '\'' || cc == '<' || cc == '=' || cc == '`')
+ parseError();
+ m_token->appendToAttributeValue(cc);
+ HTML_ADVANCE_TO(AttributeValueUnquotedState);
}
- if (character == '"' || character == '\'' || character == '<' || character == '=' || character == '`')
- parseError();
- m_token.appendToAttributeValue(character);
- ADVANCE_TO(AttributeValueUnquotedState);
+ }
END_STATE()
- BEGIN_STATE(CharacterReferenceInAttributeValueState)
+ HTML_BEGIN_STATE(CharacterReferenceInAttributeValueState) {
bool notEnoughCharacters = false;
StringBuilder decodedEntity;
bool success = consumeHTMLEntity(source, decodedEntity, notEnoughCharacters, m_additionalAllowedCharacter);
if (notEnoughCharacters)
- RETURN_IN_CURRENT_STATE(haveBufferedCharacterToken());
+ return haveBufferedCharacterToken();
if (!success) {
ASSERT(decodedEntity.isEmpty());
- m_token.appendToAttributeValue('&');
+ m_token->appendToAttributeValue('&');
} else {
for (unsigned i = 0; i < decodedEntity.length(); ++i)
- m_token.appendToAttributeValue(decodedEntity[i]);
+ m_token->appendToAttributeValue(decodedEntity[i]);
}
// We're supposed to switch back to the attribute value state that
// we were in when we were switched into this state. Rather than
// keeping track of this explictly, we observe that the previous
// state can be determined by m_additionalAllowedCharacter.
if (m_additionalAllowedCharacter == '"')
- SWITCH_TO(AttributeValueDoubleQuotedState);
- if (m_additionalAllowedCharacter == '\'')
- SWITCH_TO(AttributeValueSingleQuotedState);
- ASSERT(m_additionalAllowedCharacter == '>');
- SWITCH_TO(AttributeValueUnquotedState);
- END_STATE()
-
- BEGIN_STATE(AfterAttributeValueQuotedState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(BeforeAttributeNameState);
- if (character == '/')
- ADVANCE_TO(SelfClosingStartTagState);
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (m_options.usePreHTML5ParserQuirks && character == '<')
- return emitAndReconsumeInDataState();
- if (character == kEndOfFileMarker) {
- parseError();
- RECONSUME_IN(DataState);
- }
- parseError();
- RECONSUME_IN(BeforeAttributeNameState);
+ HTML_SWITCH_TO(AttributeValueDoubleQuotedState);
+ else if (m_additionalAllowedCharacter == '\'')
+ HTML_SWITCH_TO(AttributeValueSingleQuotedState);
+ else if (m_additionalAllowedCharacter == '>')
+ HTML_SWITCH_TO(AttributeValueUnquotedState);
+ else
+ ASSERT_NOT_REACHED();
+ }
END_STATE()
- BEGIN_STATE(SelfClosingStartTagState)
- if (character == '>') {
- m_token.setSelfClosing();
- return emitAndResumeInDataState(source);
+ HTML_BEGIN_STATE(AfterAttributeValueQuotedState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(BeforeAttributeNameState);
+ else if (cc == '/')
+ HTML_ADVANCE_TO(SelfClosingStartTagState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (m_options.usePreHTML5ParserQuirks && cc == '<')
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ else if (cc == kEndOfFileMarker) {
+ parseError();
+ HTML_RECONSUME_IN(DataState);
+ } else {
+ parseError();
+ HTML_RECONSUME_IN(BeforeAttributeNameState);
}
- if (character == kEndOfFileMarker) {
+ }
+ END_STATE()
+
+ HTML_BEGIN_STATE(SelfClosingStartTagState) {
+ if (cc == '>') {
+ m_token->setSelfClosing();
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
+ parseError();
+ HTML_RECONSUME_IN(DataState);
+ } else {
parseError();
- RECONSUME_IN(DataState);
+ HTML_RECONSUME_IN(BeforeAttributeNameState);
}
- parseError();
- RECONSUME_IN(BeforeAttributeNameState);
+ }
END_STATE()
- BEGIN_STATE(BogusCommentState)
- m_token.beginComment();
- RECONSUME_IN(ContinueBogusCommentState);
+ HTML_BEGIN_STATE(BogusCommentState) {
+ m_token->beginComment();
+ HTML_RECONSUME_IN(ContinueBogusCommentState);
+ }
END_STATE()
- BEGIN_STATE(ContinueBogusCommentState)
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (character == kEndOfFileMarker)
- return emitAndReconsumeInDataState();
- m_token.appendToComment(character);
- ADVANCE_TO(ContinueBogusCommentState);
+ HTML_BEGIN_STATE(ContinueBogusCommentState) {
+ if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (cc == kEndOfFileMarker)
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ else {
+ m_token->appendToComment(cc);
+ HTML_ADVANCE_TO(ContinueBogusCommentState);
+ }
+ }
END_STATE()
- BEGIN_STATE(MarkupDeclarationOpenState)
- if (character == '-') {
- auto result = source.advancePast("--");
+ HTML_BEGIN_STATE(MarkupDeclarationOpenState) {
+ DEFINE_STATIC_LOCAL(String, dashDashString, (ASCIILiteral("--")));
+ DEFINE_STATIC_LOCAL(String, doctypeString, (ASCIILiteral("doctype")));
+ DEFINE_STATIC_LOCAL(String, cdataString, (ASCIILiteral("[CDATA[")));
+ if (cc == '-') {
+ SegmentedString::LookAheadResult result = source.lookAhead(dashDashString);
if (result == SegmentedString::DidMatch) {
- m_token.beginComment();
- SWITCH_TO(CommentStartState);
- }
- if (result == SegmentedString::NotEnoughCharacters)
- RETURN_IN_CURRENT_STATE(haveBufferedCharacterToken());
- } else if (isASCIIAlphaCaselessEqual(character, 'd')) {
- auto result = source.advancePastIgnoringCase("doctype");
- if (result == SegmentedString::DidMatch)
- SWITCH_TO(DOCTYPEState);
- if (result == SegmentedString::NotEnoughCharacters)
- RETURN_IN_CURRENT_STATE(haveBufferedCharacterToken());
- } else if (character == '[' && shouldAllowCDATA()) {
- auto result = source.advancePast("[CDATA[");
- if (result == SegmentedString::DidMatch)
- SWITCH_TO(CDATASectionState);
- if (result == SegmentedString::NotEnoughCharacters)
- RETURN_IN_CURRENT_STATE(haveBufferedCharacterToken());
+ source.advanceAndASSERT('-');
+ source.advanceAndASSERT('-');
+ m_token->beginComment();
+ HTML_SWITCH_TO(CommentStartState);
+ } else if (result == SegmentedString::NotEnoughCharacters)
+ return haveBufferedCharacterToken();
+ } else if (cc == 'D' || cc == 'd') {
+ SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(doctypeString);
+ if (result == SegmentedString::DidMatch) {
+ advanceStringAndASSERTIgnoringCase(source, "doctype");
+ HTML_SWITCH_TO(DOCTYPEState);
+ } else if (result == SegmentedString::NotEnoughCharacters)
+ return haveBufferedCharacterToken();
+ } else if (cc == '[' && shouldAllowCDATA()) {
+ SegmentedString::LookAheadResult result = source.lookAhead(cdataString);
+ if (result == SegmentedString::DidMatch) {
+ advanceStringAndASSERT(source, "[CDATA[");
+ HTML_SWITCH_TO(CDATASectionState);
+ } else if (result == SegmentedString::NotEnoughCharacters)
+ return haveBufferedCharacterToken();
}
parseError();
- RECONSUME_IN(BogusCommentState);
+ HTML_RECONSUME_IN(BogusCommentState);
+ }
END_STATE()
- BEGIN_STATE(CommentStartState)
- if (character == '-')
- ADVANCE_TO(CommentStartDashState);
- if (character == '>') {
+ HTML_BEGIN_STATE(CommentStartState) {
+ if (cc == '-')
+ HTML_ADVANCE_TO(CommentStartDashState);
+ else if (cc == '>') {
parseError();
- return emitAndResumeInDataState(source);
- }
- if (character == kEndOfFileMarker) {
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- return emitAndReconsumeInDataState();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ m_token->appendToComment(cc);
+ HTML_ADVANCE_TO(CommentState);
}
- m_token.appendToComment(character);
- ADVANCE_TO(CommentState);
+ }
END_STATE()
- BEGIN_STATE(CommentStartDashState)
- if (character == '-')
- ADVANCE_TO(CommentEndState);
- if (character == '>') {
+ HTML_BEGIN_STATE(CommentStartDashState) {
+ if (cc == '-')
+ HTML_ADVANCE_TO(CommentEndState);
+ else if (cc == '>') {
parseError();
- return emitAndResumeInDataState(source);
- }
- if (character == kEndOfFileMarker) {
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- return emitAndReconsumeInDataState();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ m_token->appendToComment('-');
+ m_token->appendToComment(cc);
+ HTML_ADVANCE_TO(CommentState);
}
- m_token.appendToComment('-');
- m_token.appendToComment(character);
- ADVANCE_TO(CommentState);
+ }
END_STATE()
- BEGIN_STATE(CommentState)
- if (character == '-')
- ADVANCE_TO(CommentEndDashState);
- if (character == kEndOfFileMarker) {
+ HTML_BEGIN_STATE(CommentState) {
+ if (cc == '-')
+ HTML_ADVANCE_TO(CommentEndDashState);
+ else if (cc == kEndOfFileMarker) {
parseError();
- return emitAndReconsumeInDataState();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ m_token->appendToComment(cc);
+ HTML_ADVANCE_TO(CommentState);
}
- m_token.appendToComment(character);
- ADVANCE_TO(CommentState);
+ }
END_STATE()
- BEGIN_STATE(CommentEndDashState)
- if (character == '-')
- ADVANCE_TO(CommentEndState);
- if (character == kEndOfFileMarker) {
+ HTML_BEGIN_STATE(CommentEndDashState) {
+ if (cc == '-')
+ HTML_ADVANCE_TO(CommentEndState);
+ else if (cc == kEndOfFileMarker) {
parseError();
- return emitAndReconsumeInDataState();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ m_token->appendToComment('-');
+ m_token->appendToComment(cc);
+ HTML_ADVANCE_TO(CommentState);
}
- m_token.appendToComment('-');
- m_token.appendToComment(character);
- ADVANCE_TO(CommentState);
+ }
END_STATE()
- BEGIN_STATE(CommentEndState)
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (character == '!') {
+ HTML_BEGIN_STATE(CommentEndState) {
+ if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (cc == '!') {
parseError();
- ADVANCE_TO(CommentEndBangState);
- }
- if (character == '-') {
+ HTML_ADVANCE_TO(CommentEndBangState);
+ } else if (cc == '-') {
parseError();
- m_token.appendToComment('-');
- ADVANCE_TO(CommentEndState);
- }
- if (character == kEndOfFileMarker) {
+ m_token->appendToComment('-');
+ HTML_ADVANCE_TO(CommentEndState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- return emitAndReconsumeInDataState();
- }
- parseError();
- m_token.appendToComment('-');
- m_token.appendToComment('-');
- m_token.appendToComment(character);
- ADVANCE_TO(CommentState);
- END_STATE()
-
- BEGIN_STATE(CommentEndBangState)
- if (character == '-') {
- m_token.appendToComment('-');
- m_token.appendToComment('-');
- m_token.appendToComment('!');
- ADVANCE_TO(CommentEndDashState);
- }
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (character == kEndOfFileMarker) {
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
parseError();
- return emitAndReconsumeInDataState();
+ m_token->appendToComment('-');
+ m_token->appendToComment('-');
+ m_token->appendToComment(cc);
+ HTML_ADVANCE_TO(CommentState);
}
- m_token.appendToComment('-');
- m_token.appendToComment('-');
- m_token.appendToComment('!');
- m_token.appendToComment(character);
- ADVANCE_TO(CommentState);
+ }
END_STATE()
- BEGIN_STATE(DOCTYPEState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(BeforeDOCTYPENameState);
- if (character == kEndOfFileMarker) {
+ HTML_BEGIN_STATE(CommentEndBangState) {
+ if (cc == '-') {
+ m_token->appendToComment('-');
+ m_token->appendToComment('-');
+ m_token->appendToComment('!');
+ HTML_ADVANCE_TO(CommentEndDashState);
+ } else if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (cc == kEndOfFileMarker) {
parseError();
- m_token.beginDOCTYPE();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ m_token->appendToComment('-');
+ m_token->appendToComment('-');
+ m_token->appendToComment('!');
+ m_token->appendToComment(cc);
+ HTML_ADVANCE_TO(CommentState);
}
- parseError();
- RECONSUME_IN(BeforeDOCTYPENameState);
+ }
END_STATE()
- BEGIN_STATE(BeforeDOCTYPENameState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(BeforeDOCTYPENameState);
- if (character == '>') {
+ HTML_BEGIN_STATE(DOCTYPEState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(BeforeDOCTYPENameState);
+ else if (cc == kEndOfFileMarker) {
parseError();
- m_token.beginDOCTYPE();
- m_token.setForceQuirks();
- return emitAndResumeInDataState(source);
- }
- if (character == kEndOfFileMarker) {
+ m_token->beginDOCTYPE();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
parseError();
- m_token.beginDOCTYPE();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ HTML_RECONSUME_IN(BeforeDOCTYPENameState);
}
- m_token.beginDOCTYPE(toASCIILower(character));
- ADVANCE_TO(DOCTYPENameState);
+ }
END_STATE()
- BEGIN_STATE(DOCTYPENameState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(AfterDOCTYPENameState);
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (character == kEndOfFileMarker) {
+ HTML_BEGIN_STATE(BeforeDOCTYPENameState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(BeforeDOCTYPENameState);
+ else if (isASCIIUpper(cc)) {
+ m_token->beginDOCTYPE(toLowerCase(cc));
+ HTML_ADVANCE_TO(DOCTYPENameState);
+ } else if (cc == '>') {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ m_token->beginDOCTYPE();
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
+ parseError();
+ m_token->beginDOCTYPE();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ m_token->beginDOCTYPE(cc);
+ HTML_ADVANCE_TO(DOCTYPENameState);
}
- m_token.appendToName(toASCIILower(character));
- ADVANCE_TO(DOCTYPENameState);
+ }
END_STATE()
- BEGIN_STATE(AfterDOCTYPENameState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(AfterDOCTYPENameState);
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (character == kEndOfFileMarker) {
+ HTML_BEGIN_STATE(DOCTYPENameState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(AfterDOCTYPENameState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (isASCIIUpper(cc)) {
+ m_token->appendToName(toLowerCase(cc));
+ HTML_ADVANCE_TO(DOCTYPENameState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
- }
- if (isASCIIAlphaCaselessEqual(character, 'p')) {
- auto result = source.advancePastIgnoringCase("public");
- if (result == SegmentedString::DidMatch)
- SWITCH_TO(AfterDOCTYPEPublicKeywordState);
- if (result == SegmentedString::NotEnoughCharacters)
- RETURN_IN_CURRENT_STATE(haveBufferedCharacterToken());
- } else if (isASCIIAlphaCaselessEqual(character, 's')) {
- auto result = source.advancePastIgnoringCase("system");
- if (result == SegmentedString::DidMatch)
- SWITCH_TO(AfterDOCTYPESystemKeywordState);
- if (result == SegmentedString::NotEnoughCharacters)
- RETURN_IN_CURRENT_STATE(haveBufferedCharacterToken());
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ m_token->appendToName(cc);
+ HTML_ADVANCE_TO(DOCTYPENameState);
}
- parseError();
- m_token.setForceQuirks();
- ADVANCE_TO(BogusDOCTYPEState);
+ }
END_STATE()
- BEGIN_STATE(AfterDOCTYPEPublicKeywordState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(BeforeDOCTYPEPublicIdentifierState);
- if (character == '"') {
+ HTML_BEGIN_STATE(AfterDOCTYPENameState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(AfterDOCTYPENameState);
+ if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (cc == kEndOfFileMarker) {
parseError();
- m_token.setPublicIdentifierToEmptyString();
- ADVANCE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
- }
- if (character == '\'') {
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ DEFINE_STATIC_LOCAL(String, publicString, (ASCIILiteral("public")));
+ DEFINE_STATIC_LOCAL(String, systemString, (ASCIILiteral("system")));
+ if (cc == 'P' || cc == 'p') {
+ SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(publicString);
+ if (result == SegmentedString::DidMatch) {
+ advanceStringAndASSERTIgnoringCase(source, "public");
+ HTML_SWITCH_TO(AfterDOCTYPEPublicKeywordState);
+ } else if (result == SegmentedString::NotEnoughCharacters)
+ return haveBufferedCharacterToken();
+ } else if (cc == 'S' || cc == 's') {
+ SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(systemString);
+ if (result == SegmentedString::DidMatch) {
+ advanceStringAndASSERTIgnoringCase(source, "system");
+ HTML_SWITCH_TO(AfterDOCTYPESystemKeywordState);
+ } else if (result == SegmentedString::NotEnoughCharacters)
+ return haveBufferedCharacterToken();
+ }
parseError();
- m_token.setPublicIdentifierToEmptyString();
- ADVANCE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
+ m_token->setForceQuirks();
+ HTML_ADVANCE_TO(BogusDOCTYPEState);
}
- if (character == '>') {
+ }
+ END_STATE()
+
+ HTML_BEGIN_STATE(AfterDOCTYPEPublicKeywordState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(BeforeDOCTYPEPublicIdentifierState);
+ else if (cc == '"') {
parseError();
- m_token.setForceQuirks();
- return emitAndResumeInDataState(source);
- }
- if (character == kEndOfFileMarker) {
+ m_token->setPublicIdentifierToEmptyString();
+ HTML_ADVANCE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
+ } else if (cc == '\'') {
+ parseError();
+ m_token->setPublicIdentifierToEmptyString();
+ HTML_ADVANCE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
+ } else if (cc == '>') {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ parseError();
+ m_token->setForceQuirks();
+ HTML_ADVANCE_TO(BogusDOCTYPEState);
}
- parseError();
- m_token.setForceQuirks();
- ADVANCE_TO(BogusDOCTYPEState);
+ }
END_STATE()
- BEGIN_STATE(BeforeDOCTYPEPublicIdentifierState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(BeforeDOCTYPEPublicIdentifierState);
- if (character == '"') {
- m_token.setPublicIdentifierToEmptyString();
- ADVANCE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
- }
- if (character == '\'') {
- m_token.setPublicIdentifierToEmptyString();
- ADVANCE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
- }
- if (character == '>') {
+ HTML_BEGIN_STATE(BeforeDOCTYPEPublicIdentifierState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(BeforeDOCTYPEPublicIdentifierState);
+ else if (cc == '"') {
+ m_token->setPublicIdentifierToEmptyString();
+ HTML_ADVANCE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
+ } else if (cc == '\'') {
+ m_token->setPublicIdentifierToEmptyString();
+ HTML_ADVANCE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
+ } else if (cc == '>') {
parseError();
- m_token.setForceQuirks();
- return emitAndResumeInDataState(source);
- }
- if (character == kEndOfFileMarker) {
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ parseError();
+ m_token->setForceQuirks();
+ HTML_ADVANCE_TO(BogusDOCTYPEState);
}
- parseError();
- m_token.setForceQuirks();
- ADVANCE_TO(BogusDOCTYPEState);
+ }
END_STATE()
- BEGIN_STATE(DOCTYPEPublicIdentifierDoubleQuotedState)
- if (character == '"')
- ADVANCE_TO(AfterDOCTYPEPublicIdentifierState);
- if (character == '>') {
+ HTML_BEGIN_STATE(DOCTYPEPublicIdentifierDoubleQuotedState) {
+ if (cc == '"')
+ HTML_ADVANCE_TO(AfterDOCTYPEPublicIdentifierState);
+ else if (cc == '>') {
parseError();
- m_token.setForceQuirks();
- return emitAndResumeInDataState(source);
- }
- if (character == kEndOfFileMarker) {
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ m_token->appendToPublicIdentifier(cc);
+ HTML_ADVANCE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
}
- m_token.appendToPublicIdentifier(character);
- ADVANCE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
+ }
END_STATE()
- BEGIN_STATE(DOCTYPEPublicIdentifierSingleQuotedState)
- if (character == '\'')
- ADVANCE_TO(AfterDOCTYPEPublicIdentifierState);
- if (character == '>') {
+ HTML_BEGIN_STATE(DOCTYPEPublicIdentifierSingleQuotedState) {
+ if (cc == '\'')
+ HTML_ADVANCE_TO(AfterDOCTYPEPublicIdentifierState);
+ else if (cc == '>') {
parseError();
- m_token.setForceQuirks();
- return emitAndResumeInDataState(source);
- }
- if (character == kEndOfFileMarker) {
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ m_token->appendToPublicIdentifier(cc);
+ HTML_ADVANCE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
}
- m_token.appendToPublicIdentifier(character);
- ADVANCE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
+ }
END_STATE()
- BEGIN_STATE(AfterDOCTYPEPublicIdentifierState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(BetweenDOCTYPEPublicAndSystemIdentifiersState);
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (character == '"') {
+ HTML_BEGIN_STATE(AfterDOCTYPEPublicIdentifierState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(BetweenDOCTYPEPublicAndSystemIdentifiersState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (cc == '"') {
parseError();
- m_token.setSystemIdentifierToEmptyString();
- ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
- }
- if (character == '\'') {
+ m_token->setSystemIdentifierToEmptyString();
+ HTML_ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
+ } else if (cc == '\'') {
parseError();
- m_token.setSystemIdentifierToEmptyString();
- ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
- }
- if (character == kEndOfFileMarker) {
+ m_token->setSystemIdentifierToEmptyString();
+ HTML_ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
- }
- parseError();
- m_token.setForceQuirks();
- ADVANCE_TO(BogusDOCTYPEState);
- END_STATE()
-
- BEGIN_STATE(BetweenDOCTYPEPublicAndSystemIdentifiersState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(BetweenDOCTYPEPublicAndSystemIdentifiersState);
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (character == '"') {
- m_token.setSystemIdentifierToEmptyString();
- ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
- }
- if (character == '\'') {
- m_token.setSystemIdentifierToEmptyString();
- ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
- }
- if (character == kEndOfFileMarker) {
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ m_token->setForceQuirks();
+ HTML_ADVANCE_TO(BogusDOCTYPEState);
}
- parseError();
- m_token.setForceQuirks();
- ADVANCE_TO(BogusDOCTYPEState);
+ }
END_STATE()
- BEGIN_STATE(AfterDOCTYPESystemKeywordState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(BeforeDOCTYPESystemIdentifierState);
- if (character == '"') {
+ HTML_BEGIN_STATE(BetweenDOCTYPEPublicAndSystemIdentifiersState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(BetweenDOCTYPEPublicAndSystemIdentifiersState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (cc == '"') {
+ m_token->setSystemIdentifierToEmptyString();
+ HTML_ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
+ } else if (cc == '\'') {
+ m_token->setSystemIdentifierToEmptyString();
+ HTML_ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
+ } else if (cc == kEndOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
parseError();
- m_token.setSystemIdentifierToEmptyString();
- ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
+ m_token->setForceQuirks();
+ HTML_ADVANCE_TO(BogusDOCTYPEState);
}
- if (character == '\'') {
+ }
+ END_STATE()
+
+ HTML_BEGIN_STATE(AfterDOCTYPESystemKeywordState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(BeforeDOCTYPESystemIdentifierState);
+ else if (cc == '"') {
parseError();
- m_token.setSystemIdentifierToEmptyString();
- ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
- }
- if (character == '>') {
+ m_token->setSystemIdentifierToEmptyString();
+ HTML_ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
+ } else if (cc == '\'') {
parseError();
- m_token.setForceQuirks();
- return emitAndResumeInDataState(source);
- }
- if (character == kEndOfFileMarker) {
+ m_token->setSystemIdentifierToEmptyString();
+ HTML_ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
+ } else if (cc == '>') {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ m_token->setForceQuirks();
+ HTML_ADVANCE_TO(BogusDOCTYPEState);
}
- parseError();
- m_token.setForceQuirks();
- ADVANCE_TO(BogusDOCTYPEState);
+ }
END_STATE()
- BEGIN_STATE(BeforeDOCTYPESystemIdentifierState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(BeforeDOCTYPESystemIdentifierState);
- if (character == '"') {
- m_token.setSystemIdentifierToEmptyString();
- ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
- }
- if (character == '\'') {
- m_token.setSystemIdentifierToEmptyString();
- ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
- }
- if (character == '>') {
+ HTML_BEGIN_STATE(BeforeDOCTYPESystemIdentifierState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(BeforeDOCTYPESystemIdentifierState);
+ if (cc == '"') {
+ m_token->setSystemIdentifierToEmptyString();
+ HTML_ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
+ } else if (cc == '\'') {
+ m_token->setSystemIdentifierToEmptyString();
+ HTML_ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
+ } else if (cc == '>') {
parseError();
- m_token.setForceQuirks();
- return emitAndResumeInDataState(source);
- }
- if (character == kEndOfFileMarker) {
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ parseError();
+ m_token->setForceQuirks();
+ HTML_ADVANCE_TO(BogusDOCTYPEState);
}
- parseError();
- m_token.setForceQuirks();
- ADVANCE_TO(BogusDOCTYPEState);
+ }
END_STATE()
- BEGIN_STATE(DOCTYPESystemIdentifierDoubleQuotedState)
- if (character == '"')
- ADVANCE_TO(AfterDOCTYPESystemIdentifierState);
- if (character == '>') {
+ HTML_BEGIN_STATE(DOCTYPESystemIdentifierDoubleQuotedState) {
+ if (cc == '"')
+ HTML_ADVANCE_TO(AfterDOCTYPESystemIdentifierState);
+ else if (cc == '>') {
parseError();
- m_token.setForceQuirks();
- return emitAndResumeInDataState(source);
- }
- if (character == kEndOfFileMarker) {
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ m_token->appendToSystemIdentifier(cc);
+ HTML_ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
}
- m_token.appendToSystemIdentifier(character);
- ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
+ }
END_STATE()
- BEGIN_STATE(DOCTYPESystemIdentifierSingleQuotedState)
- if (character == '\'')
- ADVANCE_TO(AfterDOCTYPESystemIdentifierState);
- if (character == '>') {
+ HTML_BEGIN_STATE(DOCTYPESystemIdentifierSingleQuotedState) {
+ if (cc == '\'')
+ HTML_ADVANCE_TO(AfterDOCTYPESystemIdentifierState);
+ else if (cc == '>') {
parseError();
- m_token.setForceQuirks();
- return emitAndResumeInDataState(source);
- }
- if (character == kEndOfFileMarker) {
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ } else if (cc == kEndOfFileMarker) {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ m_token->appendToSystemIdentifier(cc);
+ HTML_ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
}
- m_token.appendToSystemIdentifier(character);
- ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
+ }
END_STATE()
- BEGIN_STATE(AfterDOCTYPESystemIdentifierState)
- if (isTokenizerWhitespace(character))
- ADVANCE_TO(AfterDOCTYPESystemIdentifierState);
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (character == kEndOfFileMarker) {
+ HTML_BEGIN_STATE(AfterDOCTYPESystemIdentifierState) {
+ if (isTokenizerWhitespace(cc))
+ HTML_ADVANCE_TO(AfterDOCTYPESystemIdentifierState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (cc == kEndOfFileMarker) {
parseError();
- m_token.setForceQuirks();
- return emitAndReconsumeInDataState();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ } else {
+ parseError();
+ HTML_ADVANCE_TO(BogusDOCTYPEState);
}
- parseError();
- ADVANCE_TO(BogusDOCTYPEState);
+ }
END_STATE()
- BEGIN_STATE(BogusDOCTYPEState)
- if (character == '>')
- return emitAndResumeInDataState(source);
- if (character == kEndOfFileMarker)
- return emitAndReconsumeInDataState();
- ADVANCE_TO(BogusDOCTYPEState);
+ HTML_BEGIN_STATE(BogusDOCTYPEState) {
+ if (cc == '>')
+ return emitAndResumeIn(source, HTMLTokenizer::DataState);
+ else if (cc == kEndOfFileMarker)
+ return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
+ HTML_ADVANCE_TO(BogusDOCTYPEState);
+ }
END_STATE()
- BEGIN_STATE(CDATASectionState)
- if (character == ']')
- ADVANCE_TO(CDATASectionRightSquareBracketState);
- if (character == kEndOfFileMarker)
- RECONSUME_IN(DataState);
- bufferCharacter(character);
- ADVANCE_TO(CDATASectionState);
+ HTML_BEGIN_STATE(CDATASectionState) {
+ if (cc == ']')
+ HTML_ADVANCE_TO(CDATASectionRightSquareBracketState);
+ else if (cc == kEndOfFileMarker)
+ HTML_RECONSUME_IN(DataState);
+ else {
+ bufferCharacter(cc);
+ HTML_ADVANCE_TO(CDATASectionState);
+ }
+ }
END_STATE()
- BEGIN_STATE(CDATASectionRightSquareBracketState)
- if (character == ']')
- ADVANCE_TO(CDATASectionDoubleRightSquareBracketState);
- bufferASCIICharacter(']');
- RECONSUME_IN(CDATASectionState);
- END_STATE()
+ HTML_BEGIN_STATE(CDATASectionRightSquareBracketState) {
+ if (cc == ']')
+ HTML_ADVANCE_TO(CDATASectionDoubleRightSquareBracketState);
+ else {
+ bufferCharacter(']');
+ HTML_RECONSUME_IN(CDATASectionState);
+ }
+ }
- BEGIN_STATE(CDATASectionDoubleRightSquareBracketState)
- if (character == '>')
- ADVANCE_TO(DataState);
- bufferASCIICharacter(']');
- bufferASCIICharacter(']');
- RECONSUME_IN(CDATASectionState);
+ HTML_BEGIN_STATE(CDATASectionDoubleRightSquareBracketState) {
+ if (cc == '>')
+ HTML_ADVANCE_TO(DataState);
+ else {
+ bufferCharacter(']');
+ bufferCharacter(']');
+ HTML_RECONSUME_IN(CDATASectionState);
+ }
+ }
END_STATE()
}
@@ -1409,45 +1579,39 @@ String HTMLTokenizer::bufferedCharacters() const
void HTMLTokenizer::updateStateFor(const AtomicString& tagName)
{
if (tagName == textareaTag || tagName == titleTag)
- m_state = RCDATAState;
+ setState(HTMLTokenizer::RCDATAState);
else if (tagName == plaintextTag)
- m_state = PLAINTEXTState;
+ setState(HTMLTokenizer::PLAINTEXTState);
else if (tagName == scriptTag)
- m_state = ScriptDataState;
+ setState(HTMLTokenizer::ScriptDataState);
else if (tagName == styleTag
|| tagName == iframeTag
|| tagName == xmpTag
|| (tagName == noembedTag && m_options.pluginsEnabled)
|| tagName == noframesTag
|| (tagName == noscriptTag && m_options.scriptEnabled))
- m_state = RAWTEXTState;
-}
-
-inline void HTMLTokenizer::appendToTemporaryBuffer(UChar character)
-{
- ASSERT(isASCII(character));
- m_temporaryBuffer.append(character);
+ setState(HTMLTokenizer::RAWTEXTState);
}
-inline bool HTMLTokenizer::temporaryBufferIs(const char* expectedString)
+inline bool HTMLTokenizer::temporaryBufferIs(const String& expectedString)
{
return vectorEqualsString(m_temporaryBuffer, expectedString);
}
-inline void HTMLTokenizer::appendToPossibleEndTag(UChar character)
+inline void HTMLTokenizer::addToPossibleEndTag(LChar cc)
{
- ASSERT(isASCII(character));
- m_bufferedEndTagName.append(character);
+ ASSERT(isEndTagBufferingState(m_state));
+ m_bufferedEndTagName.append(cc);
}
-inline bool HTMLTokenizer::isAppropriateEndTag() const
+inline bool HTMLTokenizer::isAppropriateEndTag()
{
if (m_bufferedEndTagName.size() != m_appropriateEndTagName.size())
return false;
- unsigned size = m_bufferedEndTagName.size();
+ size_t numCharacters = m_bufferedEndTagName.size();
- for (unsigned i = 0; i < size; i++) {
+ for (size_t i = 0; i < numCharacters; i++) {
if (m_bufferedEndTagName[i] != m_appropriateEndTagName[i])
return false;
}
@@ -1457,6 +1621,7 @@ inline bool HTMLTokenizer::isAppropriateEndTag() const
inline void HTMLTokenizer::parseError()
{
+ notImplemented();
}
}
diff --git a/Source/WebCore/html/parser/HTMLTokenizer.h b/Source/WebCore/html/parser/HTMLTokenizer.h
index fed21188d..38021e87d 100644
--- a/Source/WebCore/html/parser/HTMLTokenizer.h
+++ b/Source/WebCore/html/parser/HTMLTokenizer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2015 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
* Copyright (C) 2010 Google, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,54 +30,19 @@
#include "HTMLParserOptions.h"
#include "HTMLToken.h"
#include "InputStreamPreprocessor.h"
+#include "SegmentedString.h"
namespace WebCore {
-class SegmentedString;
-
class HTMLTokenizer {
+ WTF_MAKE_NONCOPYABLE(HTMLTokenizer);
+ WTF_MAKE_FAST_ALLOCATED;
public:
- explicit HTMLTokenizer(const HTMLParserOptions& = HTMLParserOptions());
-
- // If we can't parse a whole token, this returns null.
- class TokenPtr;
- TokenPtr nextToken(SegmentedString&);
-
- // Returns a copy of any characters buffered internally by the tokenizer.
- // The tokenizer buffers characters when searching for the </script> token that terminates a script element.
- String bufferedCharacters() const;
- size_t numberOfBufferedCharacters() const;
-
- // Updates the tokenizer's state according to the given tag name. This is an approximation of how the tree
- // builder would update the tokenizer's state. This method is useful for approximating HTML tokenization.
- // To get exactly the correct tokenization, you need the real tree builder.
- //
- // The main failures in the approximation are as follows:
- //
- // * The first set of character tokens emitted for a <pre> element might contain an extra leading newline.
- // * The replacement of U+0000 with U+FFFD will not be sensitive to the tree builder's insertion mode.
- // * CDATA sections in foreign content will be tokenized as bogus comments instead of as character tokens.
- //
- // This approximation is also the algorithm called for when parsing an HTML fragment.
- // https://html.spec.whatwg.org/multipage/syntax.html#parsing-html-fragments
- void updateStateFor(const AtomicString& tagName);
+ explicit HTMLTokenizer(const HTMLParserOptions&);
+ ~HTMLTokenizer();
- void setForceNullCharacterReplacement(bool);
+ void reset();
- bool shouldAllowCDATA() const;
- void setShouldAllowCDATA(bool);
-
- bool isInDataState() const;
-
- void setDataState();
- void setPLAINTEXTState();
- void setRAWTEXTState();
- void setRCDATAState();
- void setScriptDataState();
-
- bool neverSkipNullCharacters() const;
-
-private:
enum State {
DataState,
CharacterReferenceInDataState,
@@ -123,7 +88,10 @@ private:
AfterAttributeValueQuotedState,
SelfClosingStartTagState,
BogusCommentState,
- ContinueBogusCommentState, // Not in the HTML spec, used internally to track whether we started the bogus comment token.
+ // The ContinueBogusCommentState is not in the HTML5 spec, but we use
+ // it internally to keep track of whether we've started the bogus
+ // comment token yet.
+ ContinueBogusCommentState,
MarkupDeclarationOpenState,
CommentStartState,
CommentStartDashState,
@@ -153,197 +121,147 @@ private:
CDATASectionDoubleRightSquareBracketState,
};
- bool processToken(SegmentedString&);
- bool processEntity(SegmentedString&);
-
- void parseError();
-
- void bufferASCIICharacter(UChar);
- void bufferCharacter(UChar);
-
- bool emitAndResumeInDataState(SegmentedString&);
- bool emitAndReconsumeInDataState();
- bool emitEndOfFile(SegmentedString&);
-
- // Return true if we wil emit a character token before dealing with the buffered end tag.
- void flushBufferedEndTag();
- bool commitToPartialEndTag(SegmentedString&, UChar, State);
- bool commitToCompleteEndTag(SegmentedString&);
-
- void appendToTemporaryBuffer(UChar);
- bool temporaryBufferIs(const char*);
+ // This function returns true if it emits a token. Otherwise, callers
+ // must provide the same (in progress) token on the next call (unless
+ // they call reset() first).
+ bool nextToken(SegmentedString&, HTMLToken&);
- // Sometimes we speculatively consume input characters and we don't know whether they represent
- // end tags or RCDATA, etc. These functions help manage these state.
- bool inEndTagBufferingState() const;
- void appendToPossibleEndTag(UChar);
- void saveEndTagNameIfNeeded();
- bool isAppropriateEndTag() const;
-
- bool haveBufferedCharacterToken() const;
-
- static bool isNullCharacterSkippingState(State);
-
- State m_state { DataState };
- bool m_forceNullCharacterReplacement { false };
- bool m_shouldAllowCDATA { false };
-
- mutable HTMLToken m_token;
-
- // https://html.spec.whatwg.org/#additional-allowed-character
- UChar m_additionalAllowedCharacter { 0 };
-
- // https://html.spec.whatwg.org/#preprocessing-the-input-stream
- InputStreamPreprocessor<HTMLTokenizer> m_preprocessor;
-
- Vector<UChar, 32> m_appropriateEndTagName;
-
- // https://html.spec.whatwg.org/#temporary-buffer
- Vector<LChar, 32> m_temporaryBuffer;
-
- // We occasionally want to emit both a character token and an end tag
- // token (e.g., when lexing script). We buffer the name of the end tag
- // token here so we remember it next time we re-enter the tokenizer.
- Vector<LChar, 32> m_bufferedEndTagName;
+ // Returns a copy of any characters buffered internally by the tokenizer.
+ // The tokenizer buffers characters when searching for the </script> token
+ // that terminates a script element.
+ String bufferedCharacters() const;
- const HTMLParserOptions m_options;
-};
+ size_t numberOfBufferedCharacters() const
+ {
+ // Notice that we add 2 to the length of the m_temporaryBuffer to
+ // account for the "</" characters, which are effecitvely buffered in
+ // the tokenizer's state machine.
+ return m_temporaryBuffer.size() ? m_temporaryBuffer.size() + 2 : 0;
+ }
-class HTMLTokenizer::TokenPtr {
-public:
- TokenPtr();
- ~TokenPtr();
+ // Updates the tokenizer's state according to the given tag name. This is
+ // an approximation of how the tree builder would update the tokenizer's
+ // state. This method is useful for approximating HTML tokenization. To
+ // get exactly the correct tokenization, you need the real tree builder.
+ //
+ // The main failures in the approximation are as follows:
+ //
+ // * The first set of character tokens emitted for a <pre> element might
+ // contain an extra leading newline.
+ // * The replacement of U+0000 with U+FFFD will not be sensitive to the
+ // tree builder's insertion mode.
+ // * CDATA sections in foreign content will be tokenized as bogus comments
+ // instead of as character tokens.
+ //
+ void updateStateFor(const AtomicString& tagName);
- TokenPtr(TokenPtr&&);
- TokenPtr& operator=(TokenPtr&&) = delete;
+ bool forceNullCharacterReplacement() const { return m_forceNullCharacterReplacement; }
+ void setForceNullCharacterReplacement(bool value) { m_forceNullCharacterReplacement = value; }
- void clear();
+ bool shouldAllowCDATA() const { return m_shouldAllowCDATA; }
+ void setShouldAllowCDATA(bool value) { m_shouldAllowCDATA = value; }
- operator bool() const;
+ State state() const { return m_state; }
+ void setState(State state) { m_state = state; }
- HTMLToken& operator*() const;
- HTMLToken* operator->() const;
+ inline bool shouldSkipNullCharacters() const
+ {
+ return !m_forceNullCharacterReplacement
+ && (m_state == HTMLTokenizer::DataState
+ || m_state == HTMLTokenizer::RCDATAState
+ || m_state == HTMLTokenizer::RAWTEXTState);
+ }
private:
- friend class HTMLTokenizer;
- explicit TokenPtr(HTMLToken*);
+ inline bool processEntity(SegmentedString&);
- HTMLToken* m_token { nullptr };
-};
+ inline void parseError();
-inline HTMLTokenizer::TokenPtr::TokenPtr()
-{
-}
-
-inline HTMLTokenizer::TokenPtr::TokenPtr(HTMLToken* token)
- : m_token(token)
-{
-}
-
-inline HTMLTokenizer::TokenPtr::~TokenPtr()
-{
- if (m_token)
- m_token->clear();
-}
+ inline void bufferCharacter(UChar character)
+ {
+ ASSERT(character != kEndOfFileMarker);
+ m_token->ensureIsCharacterToken();
+ m_token->appendToCharacter(character);
+ }
-inline HTMLTokenizer::TokenPtr::TokenPtr(TokenPtr&& other)
- : m_token(other.m_token)
-{
- other.m_token = nullptr;
-}
+ inline bool emitAndResumeIn(SegmentedString& source, State state)
+ {
+ saveEndTagNameIfNeeded();
+ m_state = state;
+ source.advanceAndUpdateLineNumber();
+ return true;
+ }
+
+ inline bool emitAndReconsumeIn(SegmentedString&, State state)
+ {
+ saveEndTagNameIfNeeded();
+ m_state = state;
+ return true;
+ }
-inline void HTMLTokenizer::TokenPtr::clear()
-{
- if (m_token) {
+ inline bool emitEndOfFile(SegmentedString& source)
+ {
+ if (haveBufferedCharacterToken())
+ return true;
+ m_state = HTMLTokenizer::DataState;
+ source.advanceAndUpdateLineNumber();
m_token->clear();
- m_token = nullptr;
+ m_token->makeEndOfFile();
+ return true;
}
-}
-inline HTMLTokenizer::TokenPtr::operator bool() const
-{
- return m_token;
-}
-
-inline HTMLToken& HTMLTokenizer::TokenPtr::operator*() const
-{
- ASSERT(m_token);
- return *m_token;
-}
-
-inline HTMLToken* HTMLTokenizer::TokenPtr::operator->() const
-{
- ASSERT(m_token);
- return m_token;
-}
+ inline bool flushEmitAndResumeIn(SegmentedString&, State);
-inline HTMLTokenizer::TokenPtr HTMLTokenizer::nextToken(SegmentedString& source)
-{
- return TokenPtr(processToken(source) ? &m_token : nullptr);
-}
+ // Return whether we need to emit a character token before dealing with
+ // the buffered end tag.
+ inline bool flushBufferedEndTag(SegmentedString&);
+ inline bool temporaryBufferIs(const String&);
-inline size_t HTMLTokenizer::numberOfBufferedCharacters() const
-{
- // Notice that we add 2 to the length of the m_temporaryBuffer to
- // account for the "</" characters, which are effecitvely buffered in
- // the tokenizer's state machine.
- return m_temporaryBuffer.size() ? m_temporaryBuffer.size() + 2 : 0;
-}
+ // Sometimes we speculatively consume input characters and we don't
+ // know whether they represent end tags or RCDATA, etc. These
+ // functions help manage these state.
+ inline void addToPossibleEndTag(LChar cc);
-inline void HTMLTokenizer::setForceNullCharacterReplacement(bool value)
-{
- m_forceNullCharacterReplacement = value;
-}
+ inline void saveEndTagNameIfNeeded()
+ {
+ ASSERT(m_token->type() != HTMLToken::Uninitialized);
+ if (m_token->type() == HTMLToken::StartTag)
+ m_appropriateEndTagName = m_token->name();
+ }
+ inline bool isAppropriateEndTag();
-inline bool HTMLTokenizer::shouldAllowCDATA() const
-{
- return m_shouldAllowCDATA;
-}
-inline void HTMLTokenizer::setShouldAllowCDATA(bool value)
-{
- m_shouldAllowCDATA = value;
-}
+ inline bool haveBufferedCharacterToken()
+ {
+ return m_token->type() == HTMLToken::Character;
+ }
-inline bool HTMLTokenizer::isInDataState() const
-{
- return m_state == DataState;
-}
+ State m_state;
+ bool m_forceNullCharacterReplacement;
+ bool m_shouldAllowCDATA;
-inline void HTMLTokenizer::setDataState()
-{
- m_state = DataState;
-}
+ // m_token is owned by the caller. If nextToken is not on the stack,
+ // this member might be pointing to unallocated memory.
+ HTMLToken* m_token;
-inline void HTMLTokenizer::setPLAINTEXTState()
-{
- m_state = PLAINTEXTState;
-}
+ // http://www.whatwg.org/specs/web-apps/current-work/#additional-allowed-character
+ UChar m_additionalAllowedCharacter;
-inline void HTMLTokenizer::setRAWTEXTState()
-{
- m_state = RAWTEXTState;
-}
+ // http://www.whatwg.org/specs/web-apps/current-work/#preprocessing-the-input-stream
+ InputStreamPreprocessor<HTMLTokenizer> m_inputStreamPreprocessor;
-inline void HTMLTokenizer::setRCDATAState()
-{
- m_state = RCDATAState;
-}
+ Vector<UChar, 32> m_appropriateEndTagName;
-inline void HTMLTokenizer::setScriptDataState()
-{
- m_state = ScriptDataState;
-}
+ // http://www.whatwg.org/specs/web-apps/current-work/#temporary-buffer
+ Vector<LChar, 32> m_temporaryBuffer;
-inline bool HTMLTokenizer::isNullCharacterSkippingState(State state)
-{
- return state == DataState || state == RCDATAState || state == RAWTEXTState;
-}
+ // We occationally want to emit both a character token and an end tag
+ // token (e.g., when lexing script). We buffer the name of the end tag
+ // token here so we remember it next time we re-enter the tokenizer.
+ Vector<LChar, 32> m_bufferedEndTagName;
-inline bool HTMLTokenizer::neverSkipNullCharacters() const
-{
- return m_forceNullCharacterReplacement;
-}
+ HTMLParserOptions m_options;
+};
}
diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp
index 64b2678b0..46b3baf47 100644
--- a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp
+++ b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Google, Inc. All Rights Reserved.
- * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,20 +30,42 @@
#include "DocumentFragment.h"
#include "HTMLDocument.h"
#include "HTMLDocumentParser.h"
-#include "HTMLFormControlElement.h"
#include "HTMLFormElement.h"
#include "HTMLOptGroupElement.h"
+#include "HTMLOptionElement.h"
#include "HTMLParserIdioms.h"
+#include "HTMLTableElement.h"
+#include "HTMLTemplateElement.h"
#include "LocalizedStrings.h"
#include "NotImplemented.h"
#include "XLinkNames.h"
#include "XMLNSNames.h"
#include "XMLNames.h"
-#include <wtf/NeverDestroyed.h>
+#include <wtf/MainThread.h>
#include <wtf/unicode/CharacterNames.h>
-#if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(IOS)
-#include "TelephoneNumberDetector.h"
+// FIXME: Extract the following iOS-specific code into a separate file.
+#if PLATFORM(IOS)
+#include "SoftLinking.h"
+
+#ifdef __has_include
+#if __has_include(<DataDetectorsCore/DDDFACache.h>)
+#include <DataDetectorsCore/DDDFACache.h>
+#else
+typedef void* DDDFACacheRef;
+#endif
+
+#if __has_include(<DataDetectorsCore/DDDFAScanner.h>)
+#include <DataDetectorsCore/DDDFAScanner.h>
+#else
+typedef void* DDDFAScannerRef;
+#endif
+#endif
+
+SOFT_LINK_PRIVATE_FRAMEWORK_OPTIONAL(DataDetectorsCore)
+SOFT_LINK(DataDetectorsCore, DDDFACacheCreateFromFramework, DDDFACacheRef, (), ())
+SOFT_LINK(DataDetectorsCore, DDDFAScannerCreateFromCache, DDDFAScannerRef, (DDDFACacheRef cache), (cache))
+SOFT_LINK(DataDetectorsCore, DDDFAScannerFirstResultInUnicharArray, Boolean, (DDDFAScannerRef scanner, const UniChar* str, unsigned length, int* startPos, int* endPos), (scanner, str, length, startPos, endPos))
#endif
namespace WebCore {
@@ -59,7 +81,7 @@ inline bool isHTMLSpaceOrReplacementCharacter(UChar character)
}
-static inline TextPosition uninitializedPositionValue1()
+static TextPosition uninitializedPositionValue1()
{
return TextPosition(OrdinalNumber::fromOneBasedInt(-1), OrdinalNumber::first());
}
@@ -86,7 +108,9 @@ static bool isNumberedHeaderTag(const AtomicString& tagName)
static bool isCaptionColOrColgroupTag(const AtomicString& tagName)
{
- return tagName == captionTag || tagName == colTag || tagName == colgroupTag;
+ return tagName == captionTag
+ || tagName == colTag
+ || tagName == colgroupTag;
}
static bool isTableCellContextTag(const AtomicString& tagName)
@@ -96,7 +120,9 @@ static bool isTableCellContextTag(const AtomicString& tagName)
static bool isTableBodyContextTag(const AtomicString& tagName)
{
- return tagName == tbodyTag || tagName == tfootTag || tagName == theadTag;
+ return tagName == tbodyTag
+ || tagName == tfootTag
+ || tagName == theadTag;
}
static bool isNonAnchorNonNobrFormattingTag(const AtomicString& tagName)
@@ -117,27 +143,31 @@ static bool isNonAnchorNonNobrFormattingTag(const AtomicString& tagName)
static bool isNonAnchorFormattingTag(const AtomicString& tagName)
{
- return tagName == nobrTag || isNonAnchorNonNobrFormattingTag(tagName);
+ return tagName == nobrTag
+ || isNonAnchorNonNobrFormattingTag(tagName);
}
-// https://html.spec.whatwg.org/multipage/syntax.html#formatting
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#formatting
static bool isFormattingTag(const AtomicString& tagName)
{
return tagName == aTag || isNonAnchorFormattingTag(tagName);
}
class HTMLTreeBuilder::ExternalCharacterTokenBuffer {
+ WTF_MAKE_NONCOPYABLE(ExternalCharacterTokenBuffer);
public:
- explicit ExternalCharacterTokenBuffer(AtomicHTMLToken& token)
- : m_text(token.characters(), token.charactersLength())
- , m_isAll8BitData(token.charactersIsAll8BitData())
+ explicit ExternalCharacterTokenBuffer(AtomicHTMLToken* token)
+ : m_current(token->characters())
+ , m_end(m_current + token->charactersLength())
+ , m_isAll8BitData(token->isAll8BitData())
{
ASSERT(!isEmpty());
}
explicit ExternalCharacterTokenBuffer(const String& string)
- : m_text(string)
- , m_isAll8BitData(m_text.is8Bit())
+ : m_current(string.deprecatedCharacters())
+ , m_end(m_current + string.length())
+ , m_isAll8BitData(string.length() && string.is8Bit())
{
ASSERT(!isEmpty());
}
@@ -147,15 +177,15 @@ public:
ASSERT(isEmpty());
}
- bool isEmpty() const { return m_text.isEmpty(); }
+ bool isEmpty() const { return m_current == m_end; }
bool isAll8BitData() const { return m_isAll8BitData; }
void skipAtMostOneLeadingNewline()
{
ASSERT(!isEmpty());
- if (m_text[0] == '\n')
- m_text = m_text.substring(1);
+ if (*m_current == '\n')
+ ++m_current;
}
void skipLeadingWhitespace()
@@ -175,190 +205,190 @@ public:
String takeRemaining()
{
- String result = makeString(m_text);
- m_text = StringView();
- return result;
+ ASSERT(!isEmpty());
+ const UChar* start = m_current;
+ m_current = m_end;
+ size_t length = m_current - start;
+
+ if (isAll8BitData())
+ return String::make8BitFrom16BitSource(start, length);
+
+ return String(start, length);
}
void giveRemainingTo(StringBuilder& recipient)
{
- recipient.append(m_text);
- m_text = StringView();
+ recipient.append(m_current, m_end - m_current);
+ m_current = m_end;
}
String takeRemainingWhitespace()
{
ASSERT(!isEmpty());
- Vector<LChar, 8> whitespace;
+ Vector<UChar> whitespace;
do {
- UChar character = m_text[0];
- if (isHTMLSpace(character))
- whitespace.append(character);
- m_text = m_text.substring(1);
- } while (!m_text.isEmpty());
-
+ UChar cc = *m_current++;
+ if (isHTMLSpace(cc))
+ whitespace.append(cc);
+ } while (m_current < m_end);
// Returning the null string when there aren't any whitespace
// characters is slightly cleaner semantically because we don't want
// to insert a text node (as opposed to inserting an empty text node).
if (whitespace.isEmpty())
return String();
-
return String::adopt(whitespace);
}
private:
- template<bool characterPredicate(UChar)> void skipLeading()
+ template<bool characterPredicate(UChar)>
+ void skipLeading()
{
ASSERT(!isEmpty());
- while (characterPredicate(m_text[0])) {
- m_text = m_text.substring(1);
- if (m_text.isEmpty())
+ while (characterPredicate(*m_current)) {
+ if (++m_current == m_end)
return;
}
}
- template<bool characterPredicate(UChar)> String takeLeading()
+ template<bool characterPredicate(UChar)>
+ String takeLeading()
{
ASSERT(!isEmpty());
- StringView start = m_text;
+ const UChar* start = m_current;
skipLeading<characterPredicate>();
- if (start.length() == m_text.length())
+ if (start == m_current)
return String();
- return makeString(start.substring(0, start.length() - m_text.length()));
- }
-
- String makeString(StringView stringView) const
- {
- if (stringView.is8Bit() || !isAll8BitData())
- return stringView.toString();
- return String::make8BitFrom16BitSource(stringView.characters16(), stringView.length());
+ if (isAll8BitData())
+ return String::make8BitFrom16BitSource(start, m_current - start);
+ return String(start, m_current - start);
}
- StringView m_text;
+ const UChar* m_current;
+ const UChar* m_end;
bool m_isAll8BitData;
};
-inline bool HTMLTreeBuilder::isParsingTemplateContents() const
-{
-#if ENABLE(TEMPLATE_ELEMENT)
- return m_tree.openElements().hasTemplateInHTMLScope();
-#else
- return false;
-#endif
-}
-
-inline bool HTMLTreeBuilder::isParsingFragmentOrTemplateContents() const
-{
- return isParsingFragment() || isParsingTemplateContents();
-}
HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser& parser, HTMLDocument& document, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
- : m_parser(parser)
- , m_options(options)
+ : m_framesetOk(true)
+#ifndef NDEBUG
+ , m_isAttached(true)
+#endif
, m_tree(document, parserContentPolicy, options.maximumDOMTreeDepth)
+ , m_insertionMode(InsertionMode::Initial)
+ , m_originalInsertionMode(InsertionMode::Initial)
+ , m_shouldSkipLeadingNewline(false)
+ , m_parser(parser)
, m_scriptToProcessStartPosition(uninitializedPositionValue1())
+ , m_options(options)
{
-#if !ASSERT_DISABLED
- m_destructionProhibited = false;
-#endif
}
-HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser& parser, DocumentFragment& fragment, Element& contextElement, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
- : m_parser(parser)
- , m_options(options)
+// FIXME: Member variables should be grouped into self-initializing structs to
+// minimize code duplication between these constructors.
+HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser& parser, DocumentFragment& fragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
+ : m_framesetOk(true)
+#ifndef NDEBUG
+ , m_isAttached(true)
+#endif
, m_fragmentContext(fragment, contextElement)
, m_tree(fragment, parserContentPolicy, options.maximumDOMTreeDepth)
+ , m_insertionMode(InsertionMode::Initial)
+ , m_originalInsertionMode(InsertionMode::Initial)
+ , m_shouldSkipLeadingNewline(false)
+ , m_parser(parser)
, m_scriptToProcessStartPosition(uninitializedPositionValue1())
+ , m_options(options)
{
ASSERT(isMainThread());
-
- // https://html.spec.whatwg.org/multipage/syntax.html#parsing-html-fragments
- // For efficiency, we skip step 5 ("Let root be a new html element with no attributes") and instead use the DocumentFragment as a root node.
- m_tree.openElements().pushRootNode(HTMLStackItem::create(fragment));
+ // FIXME: This assertion will become invalid if <http://webkit.org/b/60316> is fixed.
+ ASSERT(contextElement);
+ if (contextElement) {
+ // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm:
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
+ // For efficiency, we skip step 4.2 ("Let root be a new html element with no attributes")
+ // and instead use the DocumentFragment as a root node.
+ m_tree.openElements()->pushRootNode(HTMLStackItem::create(&fragment, HTMLStackItem::ItemForDocumentFragmentNode));
#if ENABLE(TEMPLATE_ELEMENT)
- if (contextElement.hasTagName(templateTag))
- m_templateInsertionModes.append(InsertionMode::TemplateContents);
+ if (contextElement->hasTagName(templateTag))
+ m_templateInsertionModes.append(InsertionMode::TemplateContents);
#endif
- resetInsertionModeAppropriately();
+ resetInsertionModeAppropriately();
+ m_tree.setForm(!contextElement || isHTMLFormElement(contextElement) ? toHTMLFormElement(contextElement) : HTMLFormElement::findClosestFormAncestor(*contextElement));
+ }
+}
- m_tree.setForm(is<HTMLFormElement>(contextElement) ? &downcast<HTMLFormElement>(contextElement) : HTMLFormElement::findClosestFormAncestor(contextElement));
+HTMLTreeBuilder::~HTMLTreeBuilder()
+{
+}
-#if !ASSERT_DISABLED
- m_destructionProhibited = false;
+void HTMLTreeBuilder::detach()
+{
+#ifndef NDEBUG
+ // This call makes little sense in fragment mode, but for consistency
+ // DocumentParser expects detach() to always be called before it's destroyed.
+ m_isAttached = false;
#endif
+ // HTMLConstructionSite might be on the callstack when detach() is called
+ // otherwise we'd just call m_tree.clear() here instead.
+ m_tree.detach();
}
HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext()
+ : m_fragment(0)
+ , m_contextElement(0)
{
}
-HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment& fragment, Element& contextElement)
+HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment& fragment, Element* contextElement)
: m_fragment(&fragment)
+ , m_contextElement(contextElement)
{
ASSERT(!fragment.hasChildNodes());
- m_contextElementStackItem = HTMLStackItem::create(contextElement);
}
-inline Element& HTMLTreeBuilder::FragmentParsingContext::contextElement() const
+HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext()
{
- return contextElementStackItem().element();
}
-inline HTMLStackItem& HTMLTreeBuilder::FragmentParsingContext::contextElementStackItem() const
+PassRefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptStartPosition)
{
- ASSERT(m_fragment);
- return *m_contextElementStackItem;
-}
-
-RefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptStartPosition)
-{
- ASSERT(!m_destroyed);
-
- if (!m_scriptToProcess)
- return nullptr;
-
+ ASSERT(m_scriptToProcess);
// Unpause ourselves, callers may pause us again when processing the script.
- // The HTML5 spec is written as though scripts are executed inside the tree builder.
- // We pause the parser to exit the tree builder, and then resume before running scripts.
+ // The HTML5 spec is written as though scripts are executed inside the tree
+ // builder. We pause the parser to exit the tree builder, and then resume
+ // before running scripts.
scriptStartPosition = m_scriptToProcessStartPosition;
m_scriptToProcessStartPosition = uninitializedPositionValue1();
- return WTF::move(m_scriptToProcess);
+ return m_scriptToProcess.release();
}
-void HTMLTreeBuilder::constructTree(AtomicHTMLToken& token)
+void HTMLTreeBuilder::constructTree(AtomicHTMLToken* token)
{
-#if !ASSERT_DISABLED
- ASSERT(!m_destroyed);
- ASSERT(!m_destructionProhibited);
- m_destructionProhibited = true;
-#endif
-
if (shouldProcessTokenInForeignContent(token))
processTokenInForeignContent(token);
else
processToken(token);
- bool inForeignContent = !m_tree.isEmpty()
- && !isInHTMLNamespace(adjustedCurrentStackItem())
- && !HTMLElementStack::isHTMLIntegrationPoint(m_tree.currentStackItem())
- && !HTMLElementStack::isMathMLTextIntegrationPoint(m_tree.currentStackItem());
-
- m_parser.tokenizer().setForceNullCharacterReplacement(m_insertionMode == InsertionMode::Text || inForeignContent);
- m_parser.tokenizer().setShouldAllowCDATA(inForeignContent);
+ if (m_parser.tokenizer()) {
+ bool inForeignContent = !m_tree.isEmpty()
+ && !m_tree.currentStackItem()->isInHTMLNamespace()
+ && !HTMLElementStack::isHTMLIntegrationPoint(m_tree.currentStackItem())
+ && !HTMLElementStack::isMathMLTextIntegrationPoint(m_tree.currentStackItem());
-#if !ASSERT_DISABLED
- m_destructionProhibited = false;
-#endif
+ m_parser.tokenizer()->setForceNullCharacterReplacement(m_insertionMode == InsertionMode::Text || inForeignContent);
+ m_parser.tokenizer()->setShouldAllowCDATA(inForeignContent);
+ }
m_tree.executeQueuedTasks();
- // The tree builder might have been destroyed as an indirect result of executing the queued tasks.
+ // We might be detached now.
}
-void HTMLTreeBuilder::processToken(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processToken(AtomicHTMLToken* token)
{
- switch (token.type()) {
+ switch (token->type()) {
case HTMLToken::Uninitialized:
ASSERT_NOT_REACHED();
break;
@@ -388,12 +418,12 @@ void HTMLTreeBuilder::processToken(AtomicHTMLToken& token)
}
}
-void HTMLTreeBuilder::processDoctypeToken(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processDoctypeToken(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::DOCTYPE);
+ ASSERT(token->type() == HTMLToken::DOCTYPE);
if (m_insertionMode == InsertionMode::Initial) {
- m_tree.insertDoctype(&token);
- m_insertionMode = InsertionMode::BeforeHTML;
+ m_tree.insertDoctype(token);
+ setInsertionMode(InsertionMode::BeforeHTML);
return;
}
if (m_insertionMode == InsertionMode::InTableText) {
@@ -404,17 +434,17 @@ void HTMLTreeBuilder::processDoctypeToken(AtomicHTMLToken& token)
parseError(token);
}
-void HTMLTreeBuilder::processFakeStartTag(const QualifiedName& tagName, Vector<Attribute>&& attributes)
+void HTMLTreeBuilder::processFakeStartTag(const QualifiedName& tagName, const Vector<Attribute>& attributes)
{
// FIXME: We'll need a fancier conversion than just "localName" for SVG/MathML tags.
- AtomicHTMLToken fakeToken(HTMLToken::StartTag, tagName.localName(), WTF::move(attributes));
- processStartTag(fakeToken);
+ AtomicHTMLToken fakeToken(HTMLToken::StartTag, tagName.localName(), attributes);
+ processStartTag(&fakeToken);
}
void HTMLTreeBuilder::processFakeEndTag(const AtomicString& tagName)
{
AtomicHTMLToken fakeToken(HTMLToken::EndTag, tagName);
- processEndTag(fakeToken);
+ processEndTag(&fakeToken);
}
void HTMLTreeBuilder::processFakeEndTag(const QualifiedName& tagName)
@@ -432,38 +462,41 @@ void HTMLTreeBuilder::processFakeCharacters(const String& characters)
void HTMLTreeBuilder::processFakePEndTagIfPInButtonScope()
{
- if (!m_tree.openElements().inButtonScope(pTag.localName()))
+ if (!m_tree.openElements()->inButtonScope(pTag.localName()))
return;
AtomicHTMLToken endP(HTMLToken::EndTag, pTag.localName());
- processEndTag(endP);
+ processEndTag(&endP);
}
-Vector<Attribute> HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken& token)
+Vector<Attribute> HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken* token)
{
- Vector<Attribute> attributes = token.attributes();
- attributes.removeAllMatching([] (const Attribute& attribute) {
- const QualifiedName& name = attribute.name();
- return name.matches(nameAttr) || name.matches(actionAttr) || name.matches(promptAttr);
- });
+ Vector<Attribute> attributes = token->attributes();
+ for (int i = attributes.size() - 1; i >= 0; --i) {
+ const QualifiedName& name = attributes.at(i).name();
+ if (name.matches(nameAttr) || name.matches(actionAttr) || name.matches(promptAttr))
+ attributes.remove(i);
+ }
attributes.append(Attribute(nameAttr, isindexTag.localName()));
return attributes;
}
-void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::StartTag);
- ASSERT(token.name() == isindexTag);
+ ASSERT(token->type() == HTMLToken::StartTag);
+ ASSERT(token->name() == isindexTag);
parseError(token);
if (m_tree.form() && !isParsingTemplateContents())
return;
notImplemented(); // Acknowledge self-closing flag
processFakeStartTag(formTag);
- if (Attribute* actionAttribute = findAttribute(token.attributes(), actionAttr))
+ Attribute* actionAttribute = token->getAttributeItem(actionAttr);
+ if (actionAttribute)
m_tree.form()->setAttribute(actionAttr, actionAttribute->value());
processFakeStartTag(hrTag);
processFakeStartTag(labelTag);
- if (Attribute* promptAttribute = findAttribute(token.attributes(), promptAttr))
+ Attribute* promptAttribute = token->getAttributeItem(promptAttr);
+ if (promptAttribute)
processFakeCharacters(promptAttribute->value());
else
processFakeCharacters(searchableIndexIntroduction());
@@ -476,357 +509,381 @@ void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken& token)
namespace {
-bool isLi(const HTMLStackItem& item)
+bool isLi(const HTMLStackItem* item)
{
- return item.hasTagName(liTag);
+ return item->hasTagName(liTag);
}
-bool isDdOrDt(const HTMLStackItem& item)
+bool isDdOrDt(const HTMLStackItem* item)
{
- return item.hasTagName(ddTag) || item.hasTagName(dtTag);
+ return item->hasTagName(ddTag)
+ || item->hasTagName(dtTag);
}
}
-template <bool shouldClose(const HTMLStackItem&)> void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken& token)
+template <bool shouldClose(const HTMLStackItem*)>
+void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken* token)
{
m_framesetOk = false;
- for (auto* nodeRecord = &m_tree.openElements().topRecord(); ; nodeRecord = nodeRecord->next()) {
- HTMLStackItem& item = nodeRecord->stackItem();
- if (shouldClose(item)) {
- ASSERT(item.isElement());
- processFakeEndTag(item.localName());
+ HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
+ while (1) {
+ RefPtr<HTMLStackItem> item = nodeRecord->stackItem();
+ if (shouldClose(item.get())) {
+ ASSERT(item->isElementNode());
+ processFakeEndTag(item->localName());
break;
}
- if (isSpecialNode(item) && !item.hasTagName(addressTag) && !item.hasTagName(divTag) && !item.hasTagName(pTag))
+ if (item->isSpecialNode() && !item->hasTagName(addressTag) && !item->hasTagName(divTag) && !item->hasTagName(pTag))
break;
+ nodeRecord = nodeRecord->next();
}
processFakePEndTagIfPInButtonScope();
- m_tree.insertHTMLElement(&token);
+ m_tree.insertHTMLElement(token);
}
-template <typename TableQualifiedName> static HashMap<AtomicString, QualifiedName> createCaseMap(const TableQualifiedName* const names[], unsigned length)
+typedef HashMap<AtomicString, QualifiedName> PrefixedNameToQualifiedNameMap;
+
+static void mapLoweredLocalNameToName(PrefixedNameToQualifiedNameMap* map, const QualifiedName* const names[], size_t length)
{
- HashMap<AtomicString, QualifiedName> map;
- for (unsigned i = 0; i < length; ++i) {
+ for (size_t i = 0; i < length; ++i) {
const QualifiedName& name = *names[i];
const AtomicString& localName = name.localName();
AtomicString loweredLocalName = localName.lower();
if (loweredLocalName != localName)
- map.add(loweredLocalName, name);
+ map->add(loweredLocalName, name);
}
- return map;
}
-static void adjustSVGTagNameCase(AtomicHTMLToken& token)
+static void adjustSVGTagNameCase(AtomicHTMLToken* token)
{
- static NeverDestroyed<HashMap<AtomicString, QualifiedName>> map = createCaseMap(SVGNames::getSVGTags(), SVGNames::SVGTagsCount);
- const QualifiedName& casedName = map.get().get(token.name());
+ static PrefixedNameToQualifiedNameMap* caseMap = 0;
+ if (!caseMap) {
+ caseMap = new PrefixedNameToQualifiedNameMap;
+ mapLoweredLocalNameToName(caseMap, SVGNames::getSVGTags(), SVGNames::SVGTagsCount);
+ }
+
+ const QualifiedName& casedName = caseMap->get(token->name());
if (casedName.localName().isNull())
return;
- token.setName(casedName.localName());
+ token->setName(casedName.localName());
}
-static inline void adjustAttributes(HashMap<AtomicString, QualifiedName>& map, AtomicHTMLToken& token)
+template<const QualifiedName* const * getAttrs(), unsigned length>
+static void adjustAttributes(AtomicHTMLToken* token)
{
- for (auto& attribute : token.attributes()) {
- const QualifiedName& casedName = map.get(attribute.localName());
- if (!casedName.localName().isNull())
- attribute.parserSetName(casedName);
+ static PrefixedNameToQualifiedNameMap* caseMap = 0;
+ if (!caseMap) {
+ caseMap = new PrefixedNameToQualifiedNameMap;
+ mapLoweredLocalNameToName(caseMap, getAttrs(), length);
}
-}
-template<const QualifiedName* const* attributesTable(), unsigned attributesTableLength> static void adjustAttributes(AtomicHTMLToken& token)
-{
- static NeverDestroyed<HashMap<AtomicString, QualifiedName>> map = createCaseMap(attributesTable(), attributesTableLength);
- adjustAttributes(map, token);
+ for (unsigned i = 0; i < token->attributes().size(); ++i) {
+ Attribute& tokenAttribute = token->attributes().at(i);
+ const QualifiedName& casedName = caseMap->get(tokenAttribute.localName());
+ if (!casedName.localName().isNull())
+ tokenAttribute.parserSetName(casedName);
+ }
}
-static inline void adjustSVGAttributes(AtomicHTMLToken& token)
+static void adjustSVGAttributes(AtomicHTMLToken* token)
{
adjustAttributes<SVGNames::getSVGAttrs, SVGNames::SVGAttrsCount>(token);
}
-static inline void adjustMathMLAttributes(AtomicHTMLToken& token)
+static void adjustMathMLAttributes(AtomicHTMLToken* token)
{
adjustAttributes<MathMLNames::getMathMLAttrs, MathMLNames::MathMLAttrsCount>(token);
}
-static void addNamesWithPrefix(HashMap<AtomicString, QualifiedName>& map, const AtomicString& prefix, const QualifiedName* const names[], unsigned length)
+static void addNamesWithPrefix(PrefixedNameToQualifiedNameMap* map, const AtomicString& prefix, const QualifiedName* const names[], size_t length)
{
- for (unsigned i = 0; i < length; ++i) {
+ for (size_t i = 0; i < length; ++i) {
const QualifiedName& name = *names[i];
const AtomicString& localName = name.localName();
- map.add(prefix + ':' + localName, QualifiedName(prefix, localName, name.namespaceURI()));
+ AtomicString prefixColonLocalName = prefix + ':' + localName;
+ QualifiedName nameWithPrefix(prefix, localName, name.namespaceURI());
+ map->add(prefixColonLocalName, nameWithPrefix);
}
}
-static HashMap<AtomicString, QualifiedName> createForeignAttributesMap()
+static void adjustForeignAttributes(AtomicHTMLToken* token)
{
- HashMap<AtomicString, QualifiedName> map;
+ static PrefixedNameToQualifiedNameMap* map = 0;
+ if (!map) {
+ map = new PrefixedNameToQualifiedNameMap;
- addNamesWithPrefix(map, xlinkAtom, XLinkNames::getXLinkAttrs(), XLinkNames::XLinkAttrsCount);
- addNamesWithPrefix(map, xmlAtom, XMLNames::getXMLAttrs(), XMLNames::XMLAttrsCount);
+ addNamesWithPrefix(map, xlinkAtom, XLinkNames::getXLinkAttrs(), XLinkNames::XLinkAttrsCount);
- map.add(WTF::xmlnsAtom, XMLNSNames::xmlnsAttr);
- map.add("xmlns:xlink", QualifiedName(xmlnsAtom, xlinkAtom, XMLNSNames::xmlnsNamespaceURI));
+ addNamesWithPrefix(map, xmlAtom, XMLNames::getXMLAttrs(), XMLNames::XMLAttrsCount);
- return map;
-}
+ map->add(WTF::xmlnsAtom, XMLNSNames::xmlnsAttr);
+ map->add("xmlns:xlink", QualifiedName(xmlnsAtom, xlinkAtom, XMLNSNames::xmlnsNamespaceURI));
+ }
-static void adjustForeignAttributes(AtomicHTMLToken& token)
-{
- static NeverDestroyed<HashMap<AtomicString, QualifiedName>> map = createForeignAttributesMap();
- adjustAttributes(map, token);
+ for (unsigned i = 0; i < token->attributes().size(); ++i) {
+ Attribute& tokenAttribute = token->attributes().at(i);
+ const QualifiedName& name = map->get(tokenAttribute.localName());
+ if (!name.localName().isNull())
+ tokenAttribute.parserSetName(name);
+ }
}
-void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::StartTag);
- if (token.name() == htmlTag) {
+ ASSERT(token->type() == HTMLToken::StartTag);
+ if (token->name() == htmlTag) {
processHtmlStartTagForInBody(token);
return;
}
- if (token.name() == baseTag
- || token.name() == basefontTag
- || token.name() == bgsoundTag
- || token.name() == commandTag
- || token.name() == linkTag
- || token.name() == metaTag
- || token.name() == noframesTag
- || token.name() == scriptTag
- || token.name() == styleTag
- || token.name() == titleTag) {
+ if (token->name() == baseTag
+ || token->name() == basefontTag
+ || token->name() == bgsoundTag
+ || token->name() == commandTag
+ || token->name() == linkTag
+ || token->name() == metaTag
+ || token->name() == noframesTag
+ || token->name() == scriptTag
+ || token->name() == styleTag
+ || token->name() == titleTag) {
bool didProcess = processStartTagForInHead(token);
ASSERT_UNUSED(didProcess, didProcess);
return;
}
- if (token.name() == bodyTag) {
+ if (token->name() == bodyTag) {
parseError(token);
- bool fragmentOrTemplateCase = !m_tree.openElements().secondElementIsHTMLBodyElement() || m_tree.openElements().hasOnlyOneElement();
+ bool fragmentOrTemplateCase = !m_tree.openElements()->secondElementIsHTMLBodyElement() || m_tree.openElements()->hasOnlyOneElement();
#if ENABLE(TEMPLATE_ELEMENT)
- fragmentOrTemplateCase = fragmentOrTemplateCase || m_tree.openElements().hasTemplateInHTMLScope();
+ fragmentOrTemplateCase = fragmentOrTemplateCase || m_tree.openElements()->hasTemplateInHTMLScope();
#endif
if (fragmentOrTemplateCase) {
ASSERT(isParsingFragmentOrTemplateContents());
return;
}
m_framesetOk = false;
- m_tree.insertHTMLBodyStartTagInBody(&token);
+ m_tree.insertHTMLBodyStartTagInBody(token);
return;
}
- if (token.name() == framesetTag) {
+ if (token->name() == framesetTag) {
parseError(token);
- if (!m_tree.openElements().secondElementIsHTMLBodyElement() || m_tree.openElements().hasOnlyOneElement()) {
+ if (!m_tree.openElements()->secondElementIsHTMLBodyElement() || m_tree.openElements()->hasOnlyOneElement()) {
ASSERT(isParsingFragmentOrTemplateContents());
return;
}
if (!m_framesetOk)
return;
- m_tree.openElements().bodyElement().remove(ASSERT_NO_EXCEPTION);
- m_tree.openElements().popUntil(&m_tree.openElements().bodyElement());
- m_tree.openElements().popHTMLBodyElement();
- ASSERT(&m_tree.openElements().top() == &m_tree.openElements().htmlElement());
- m_tree.insertHTMLElement(&token);
- m_insertionMode = InsertionMode::InFrameset;
- return;
- }
- if (token.name() == addressTag
- || token.name() == articleTag
- || token.name() == asideTag
- || token.name() == blockquoteTag
- || token.name() == centerTag
- || token.name() == detailsTag
- || token.name() == dirTag
- || token.name() == divTag
- || token.name() == dlTag
- || token.name() == fieldsetTag
- || token.name() == figcaptionTag
- || token.name() == figureTag
- || token.name() == footerTag
- || token.name() == headerTag
- || token.name() == hgroupTag
- || token.name() == mainTag
- || token.name() == menuTag
- || token.name() == navTag
- || token.name() == olTag
- || token.name() == pTag
- || token.name() == sectionTag
- || token.name() == summaryTag
- || token.name() == ulTag) {
+ m_tree.openElements()->bodyElement()->remove(ASSERT_NO_EXCEPTION);
+ m_tree.openElements()->popUntil(m_tree.openElements()->bodyElement());
+ m_tree.openElements()->popHTMLBodyElement();
+ ASSERT(m_tree.openElements()->top() == m_tree.openElements()->htmlElement());
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InsertionMode::InFrameset);
+ return;
+ }
+ if (token->name() == addressTag
+ || token->name() == articleTag
+ || token->name() == asideTag
+ || token->name() == blockquoteTag
+ || token->name() == centerTag
+ || token->name() == detailsTag
+ || token->name() == dirTag
+ || token->name() == divTag
+ || token->name() == dlTag
+ || token->name() == fieldsetTag
+ || token->name() == figcaptionTag
+ || token->name() == figureTag
+ || token->name() == footerTag
+ || token->name() == headerTag
+ || token->name() == hgroupTag
+ || token->name() == mainTag
+ || token->name() == menuTag
+ || token->name() == navTag
+ || token->name() == olTag
+ || token->name() == pTag
+ || token->name() == sectionTag
+ || token->name() == summaryTag
+ || token->name() == ulTag) {
processFakePEndTagIfPInButtonScope();
- m_tree.insertHTMLElement(&token);
+ m_tree.insertHTMLElement(token);
return;
}
- if (isNumberedHeaderTag(token.name())) {
+ if (isNumberedHeaderTag(token->name())) {
processFakePEndTagIfPInButtonScope();
- if (isNumberedHeaderElement(m_tree.currentStackItem())) {
+ if (m_tree.currentStackItem()->isNumberedHeaderElement()) {
parseError(token);
- m_tree.openElements().pop();
+ m_tree.openElements()->pop();
}
- m_tree.insertHTMLElement(&token);
+ m_tree.insertHTMLElement(token);
return;
}
- if (token.name() == preTag || token.name() == listingTag) {
+ if (token->name() == preTag || token->name() == listingTag) {
processFakePEndTagIfPInButtonScope();
- m_tree.insertHTMLElement(&token);
+ m_tree.insertHTMLElement(token);
m_shouldSkipLeadingNewline = true;
m_framesetOk = false;
return;
}
- if (token.name() == formTag) {
+ if (token->name() == formTag) {
if (m_tree.form() && !isParsingTemplateContents()) {
parseError(token);
return;
}
processFakePEndTagIfPInButtonScope();
- m_tree.insertHTMLFormElement(&token);
+ m_tree.insertHTMLFormElement(token);
return;
}
- if (token.name() == liTag) {
+ if (token->name() == liTag) {
processCloseWhenNestedTag<isLi>(token);
return;
}
- if (token.name() == ddTag || token.name() == dtTag) {
+ if (token->name() == ddTag || token->name() == dtTag) {
processCloseWhenNestedTag<isDdOrDt>(token);
return;
}
- if (token.name() == plaintextTag) {
+ if (token->name() == plaintextTag) {
processFakePEndTagIfPInButtonScope();
- m_tree.insertHTMLElement(&token);
- m_parser.tokenizer().setPLAINTEXTState();
+ m_tree.insertHTMLElement(token);
+ if (m_parser.tokenizer())
+ m_parser.tokenizer()->setState(HTMLTokenizer::PLAINTEXTState);
return;
}
- if (token.name() == buttonTag) {
- if (m_tree.openElements().inScope(buttonTag)) {
+ if (token->name() == buttonTag) {
+ if (m_tree.openElements()->inScope(buttonTag)) {
parseError(token);
processFakeEndTag(buttonTag);
processStartTag(token); // FIXME: Could we just fall through here?
return;
}
m_tree.reconstructTheActiveFormattingElements();
- m_tree.insertHTMLElement(&token);
+ m_tree.insertHTMLElement(token);
m_framesetOk = false;
return;
}
- if (token.name() == aTag) {
- Element* activeATag = m_tree.activeFormattingElements().closestElementInScopeWithName(aTag.localName());
+ if (token->name() == aTag) {
+ Element* activeATag = m_tree.activeFormattingElements()->closestElementInScopeWithName(aTag.localName());
if (activeATag) {
parseError(token);
processFakeEndTag(aTag);
- m_tree.activeFormattingElements().remove(activeATag);
- if (m_tree.openElements().contains(activeATag))
- m_tree.openElements().remove(activeATag);
+ m_tree.activeFormattingElements()->remove(activeATag);
+ if (m_tree.openElements()->contains(activeATag))
+ m_tree.openElements()->remove(activeATag);
}
m_tree.reconstructTheActiveFormattingElements();
- m_tree.insertFormattingElement(&token);
+ m_tree.insertFormattingElement(token);
return;
}
- if (isNonAnchorNonNobrFormattingTag(token.name())) {
+ if (isNonAnchorNonNobrFormattingTag(token->name())) {
m_tree.reconstructTheActiveFormattingElements();
- m_tree.insertFormattingElement(&token);
+ m_tree.insertFormattingElement(token);
return;
}
- if (token.name() == nobrTag) {
+ if (token->name() == nobrTag) {
m_tree.reconstructTheActiveFormattingElements();
- if (m_tree.openElements().inScope(nobrTag)) {
+ if (m_tree.openElements()->inScope(nobrTag)) {
parseError(token);
processFakeEndTag(nobrTag);
m_tree.reconstructTheActiveFormattingElements();
}
- m_tree.insertFormattingElement(&token);
+ m_tree.insertFormattingElement(token);
return;
}
- if (token.name() == appletTag || token.name() == embedTag || token.name() == objectTag) {
+ if (token->name() == appletTag
+ || token->name() == embedTag
+ || token->name() == objectTag) {
if (!pluginContentIsAllowed(m_tree.parserContentPolicy()))
return;
}
- if (token.name() == appletTag || token.name() == marqueeTag || token.name() == objectTag) {
+ if (token->name() == appletTag
+ || token->name() == marqueeTag
+ || token->name() == objectTag) {
m_tree.reconstructTheActiveFormattingElements();
- m_tree.insertHTMLElement(&token);
- m_tree.activeFormattingElements().appendMarker();
+ m_tree.insertHTMLElement(token);
+ m_tree.activeFormattingElements()->appendMarker();
m_framesetOk = false;
return;
}
- if (token.name() == tableTag) {
- if (!m_tree.inQuirksMode() && m_tree.openElements().inButtonScope(pTag))
+ if (token->name() == tableTag) {
+ if (!m_tree.inQuirksMode() && m_tree.openElements()->inButtonScope(pTag))
processFakeEndTag(pTag);
- m_tree.insertHTMLElement(&token);
+ m_tree.insertHTMLElement(token);
m_framesetOk = false;
- m_insertionMode = InsertionMode::InTable;
+ setInsertionMode(InsertionMode::InTable);
return;
}
- if (token.name() == imageTag) {
+ if (token->name() == imageTag) {
parseError(token);
// Apparently we're not supposed to ask.
- token.setName(imgTag.localName());
+ token->setName(imgTag.localName());
// Note the fall through to the imgTag handling below!
}
- if (token.name() == areaTag
- || token.name() == brTag
- || token.name() == embedTag
- || token.name() == imgTag
- || token.name() == keygenTag
- || token.name() == wbrTag) {
+ if (token->name() == areaTag
+ || token->name() == brTag
+ || token->name() == embedTag
+ || token->name() == imgTag
+ || token->name() == keygenTag
+ || token->name() == wbrTag) {
m_tree.reconstructTheActiveFormattingElements();
- m_tree.insertSelfClosingHTMLElement(&token);
+ m_tree.insertSelfClosingHTMLElement(token);
m_framesetOk = false;
return;
}
- if (token.name() == inputTag) {
- Attribute* typeAttribute = findAttribute(token.attributes(), typeAttr);
+ if (token->name() == inputTag) {
+ Attribute* typeAttribute = token->getAttributeItem(typeAttr);
m_tree.reconstructTheActiveFormattingElements();
- m_tree.insertSelfClosingHTMLElement(&token);
+ m_tree.insertSelfClosingHTMLElement(token);
if (!typeAttribute || !equalIgnoringCase(typeAttribute->value(), "hidden"))
m_framesetOk = false;
return;
}
- if (token.name() == paramTag || token.name() == sourceTag || token.name() == trackTag) {
- m_tree.insertSelfClosingHTMLElement(&token);
+ if (token->name() == paramTag
+ || token->name() == sourceTag
+ || token->name() == trackTag) {
+ m_tree.insertSelfClosingHTMLElement(token);
return;
}
- if (token.name() == hrTag) {
+ if (token->name() == hrTag) {
processFakePEndTagIfPInButtonScope();
- m_tree.insertSelfClosingHTMLElement(&token);
+ m_tree.insertSelfClosingHTMLElement(token);
m_framesetOk = false;
return;
}
- if (token.name() == isindexTag) {
+ if (token->name() == isindexTag) {
processIsindexStartTagForInBody(token);
return;
}
- if (token.name() == textareaTag) {
- m_tree.insertHTMLElement(&token);
+ if (token->name() == textareaTag) {
+ m_tree.insertHTMLElement(token);
m_shouldSkipLeadingNewline = true;
- m_parser.tokenizer().setRCDATAState();
+ if (m_parser.tokenizer())
+ m_parser.tokenizer()->setState(HTMLTokenizer::RCDATAState);
m_originalInsertionMode = m_insertionMode;
m_framesetOk = false;
- m_insertionMode = InsertionMode::Text;
+ setInsertionMode(InsertionMode::Text);
return;
}
- if (token.name() == xmpTag) {
+ if (token->name() == xmpTag) {
processFakePEndTagIfPInButtonScope();
m_tree.reconstructTheActiveFormattingElements();
m_framesetOk = false;
processGenericRawTextStartTag(token);
return;
}
- if (token.name() == iframeTag) {
+ if (token->name() == iframeTag) {
m_framesetOk = false;
processGenericRawTextStartTag(token);
return;
}
- if (token.name() == noembedTag && m_options.pluginsEnabled) {
+ if (token->name() == noembedTag && m_options.pluginsEnabled) {
processGenericRawTextStartTag(token);
return;
}
- if (token.name() == noscriptTag && m_options.scriptEnabled) {
+ if (token->name() == noscriptTag && m_options.scriptEnabled) {
processGenericRawTextStartTag(token);
return;
}
- if (token.name() == selectTag) {
+ if (token->name() == selectTag) {
m_tree.reconstructTheActiveFormattingElements();
- m_tree.insertHTMLElement(&token);
+ m_tree.insertHTMLElement(token);
m_framesetOk = false;
if (m_insertionMode == InsertionMode::InTable
|| m_insertionMode == InsertionMode::InCaption
@@ -834,116 +891,105 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
|| m_insertionMode == InsertionMode::InTableBody
|| m_insertionMode == InsertionMode::InRow
|| m_insertionMode == InsertionMode::InCell)
- m_insertionMode = InsertionMode::InSelectInTable;
+ setInsertionMode(InsertionMode::InSelectInTable);
else
- m_insertionMode = InsertionMode::InSelect;
+ setInsertionMode(InsertionMode::InSelect);
return;
}
- if (token.name() == optgroupTag || token.name() == optionTag) {
- if (is<HTMLOptionElement>(m_tree.currentStackItem().node())) {
+ if (token->name() == optgroupTag || token->name() == optionTag) {
+ if (isHTMLOptionElement(m_tree.currentStackItem()->node())) {
AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
- processEndTag(endOption);
+ processEndTag(&endOption);
}
m_tree.reconstructTheActiveFormattingElements();
- m_tree.insertHTMLElement(&token);
+ m_tree.insertHTMLElement(token);
return;
}
- if (token.name() == rbTag || token.name() == rtcTag) {
- if (m_tree.openElements().inScope(rubyTag.localName())) {
+ if (token->name() == rpTag || token->name() == rtTag) {
+ if (m_tree.openElements()->inScope(rubyTag.localName())) {
m_tree.generateImpliedEndTags();
- if (!m_tree.currentStackItem().hasTagName(rubyTag))
- parseError(token);
- }
- m_tree.insertHTMLElement(&token);
- return;
- }
- if (token.name() == rtTag || token.name() == rpTag) {
- if (m_tree.openElements().inScope(rubyTag.localName())) {
- m_tree.generateImpliedEndTagsWithExclusion(rtcTag.localName());
- if (!m_tree.currentStackItem().hasTagName(rubyTag) && !m_tree.currentStackItem().hasTagName(rtcTag))
+ if (!m_tree.currentStackItem()->hasTagName(rubyTag))
parseError(token);
}
- m_tree.insertHTMLElement(&token);
+ m_tree.insertHTMLElement(token);
return;
}
- if (token.name() == MathMLNames::mathTag.localName()) {
+ if (token->name() == MathMLNames::mathTag.localName()) {
m_tree.reconstructTheActiveFormattingElements();
adjustMathMLAttributes(token);
adjustForeignAttributes(token);
- m_tree.insertForeignElement(&token, MathMLNames::mathmlNamespaceURI);
+ m_tree.insertForeignElement(token, MathMLNames::mathmlNamespaceURI);
return;
}
- if (token.name() == SVGNames::svgTag.localName()) {
+ if (token->name() == SVGNames::svgTag.localName()) {
m_tree.reconstructTheActiveFormattingElements();
adjustSVGAttributes(token);
adjustForeignAttributes(token);
- m_tree.insertForeignElement(&token, SVGNames::svgNamespaceURI);
+ m_tree.insertForeignElement(token, SVGNames::svgNamespaceURI);
return;
}
- if (isCaptionColOrColgroupTag(token.name())
- || token.name() == frameTag
- || token.name() == headTag
- || isTableBodyContextTag(token.name())
- || isTableCellContextTag(token.name())
- || token.name() == trTag) {
+ if (isCaptionColOrColgroupTag(token->name())
+ || token->name() == frameTag
+ || token->name() == headTag
+ || isTableBodyContextTag(token->name())
+ || isTableCellContextTag(token->name())
+ || token->name() == trTag) {
parseError(token);
return;
}
#if ENABLE(TEMPLATE_ELEMENT)
- if (token.name() == templateTag) {
+ if (token->name() == templateTag) {
processTemplateStartTag(token);
return;
}
#endif
m_tree.reconstructTheActiveFormattingElements();
- m_tree.insertHTMLElement(&token);
+ m_tree.insertHTMLElement(token);
}
#if ENABLE(TEMPLATE_ELEMENT)
-
-void HTMLTreeBuilder::processTemplateStartTag(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processTemplateStartTag(AtomicHTMLToken* token)
{
- m_tree.activeFormattingElements().appendMarker();
- m_tree.insertHTMLElement(&token);
+ m_tree.activeFormattingElements()->appendMarker();
+ m_tree.insertHTMLElement(token);
m_templateInsertionModes.append(InsertionMode::TemplateContents);
- m_insertionMode = InsertionMode::TemplateContents;
+ setInsertionMode(InsertionMode::TemplateContents);
}
-bool HTMLTreeBuilder::processTemplateEndTag(AtomicHTMLToken& token)
+bool HTMLTreeBuilder::processTemplateEndTag(AtomicHTMLToken* token)
{
- ASSERT(token.name() == templateTag.localName());
- if (!m_tree.openElements().hasTemplateInHTMLScope()) {
- ASSERT(m_templateInsertionModes.isEmpty() || (m_templateInsertionModes.size() == 1 && m_fragmentContext.contextElement().hasTagName(templateTag)));
+ ASSERT(token->name() == templateTag.localName());
+ if (!m_tree.openElements()->hasTemplateInHTMLScope()) {
+ ASSERT(m_templateInsertionModes.isEmpty() || (m_templateInsertionModes.size() == 1 && m_fragmentContext.contextElement()->hasTagName(templateTag)));
parseError(token);
return false;
}
m_tree.generateImpliedEndTags();
- if (!m_tree.currentStackItem().hasTagName(templateTag))
+ if (!m_tree.currentStackItem()->hasTagName(templateTag))
parseError(token);
- m_tree.openElements().popUntilPopped(templateTag);
- m_tree.activeFormattingElements().clearToLastMarker();
+ m_tree.openElements()->popUntilPopped(templateTag);
+ m_tree.activeFormattingElements()->clearToLastMarker();
m_templateInsertionModes.removeLast();
resetInsertionModeAppropriately();
return true;
}
-bool HTMLTreeBuilder::processEndOfFileForInTemplateContents(AtomicHTMLToken& token)
+bool HTMLTreeBuilder::processEndOfFileForInTemplateContents(AtomicHTMLToken* token)
{
AtomicHTMLToken endTemplate(HTMLToken::EndTag, templateTag.localName());
- if (!processTemplateEndTag(endTemplate))
+ if (!processTemplateEndTag(&endTemplate))
return false;
processEndOfFile(token);
return true;
}
-
#endif
bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
{
bool ignoreFakeEndTag = m_tree.currentIsRootNode();
#if ENABLE(TEMPLATE_ELEMENT)
- ignoreFakeEndTag = ignoreFakeEndTag || m_tree.currentNode().hasTagName(templateTag);
+ ignoreFakeEndTag = ignoreFakeEndTag || m_tree.currentNode()->hasTagName(templateTag);
#endif
if (ignoreFakeEndTag) {
@@ -951,60 +997,61 @@ bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
// FIXME: parse error
return false;
}
- m_tree.openElements().pop();
- m_insertionMode = InsertionMode::InTable;
+ m_tree.openElements()->pop();
+ setInsertionMode(InsertionMode::InTable);
return true;
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#close-the-cell
void HTMLTreeBuilder::closeTheCell()
{
- ASSERT(m_insertionMode == InsertionMode::InCell);
- if (m_tree.openElements().inTableScope(tdTag)) {
- ASSERT(!m_tree.openElements().inTableScope(thTag));
+ ASSERT(insertionMode() == InsertionMode::InCell);
+ if (m_tree.openElements()->inTableScope(tdTag)) {
+ ASSERT(!m_tree.openElements()->inTableScope(thTag));
processFakeEndTag(tdTag);
return;
}
- ASSERT(m_tree.openElements().inTableScope(thTag));
+ ASSERT(m_tree.openElements()->inTableScope(thTag));
processFakeEndTag(thTag);
- ASSERT(m_insertionMode == InsertionMode::InRow);
+ ASSERT(insertionMode() == InsertionMode::InRow);
}
-void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::StartTag);
- if (token.name() == captionTag) {
- m_tree.openElements().popUntilTableScopeMarker();
- m_tree.activeFormattingElements().appendMarker();
- m_tree.insertHTMLElement(&token);
- m_insertionMode = InsertionMode::InCaption;
+ ASSERT(token->type() == HTMLToken::StartTag);
+ if (token->name() == captionTag) {
+ m_tree.openElements()->popUntilTableScopeMarker();
+ m_tree.activeFormattingElements()->appendMarker();
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InsertionMode::InCaption);
return;
}
- if (token.name() == colgroupTag) {
- m_tree.openElements().popUntilTableScopeMarker();
- m_tree.insertHTMLElement(&token);
- m_insertionMode = InsertionMode::InColumnGroup;
+ if (token->name() == colgroupTag) {
+ m_tree.openElements()->popUntilTableScopeMarker();
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InsertionMode::InColumnGroup);
return;
}
- if (token.name() == colTag) {
+ if (token->name() == colTag) {
processFakeStartTag(colgroupTag);
- ASSERT(m_insertionMode == InsertionMode::InColumnGroup);
+ ASSERT(insertionMode() == InsertionMode::InColumnGroup);
processStartTag(token);
return;
}
- if (isTableBodyContextTag(token.name())) {
- m_tree.openElements().popUntilTableScopeMarker();
- m_tree.insertHTMLElement(&token);
- m_insertionMode = InsertionMode::InTableBody;
+ if (isTableBodyContextTag(token->name())) {
+ m_tree.openElements()->popUntilTableScopeMarker();
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InsertionMode::InTableBody);
return;
}
- if (isTableCellContextTag(token.name()) || token.name() == trTag) {
+ if (isTableCellContextTag(token->name())
+ || token->name() == trTag) {
processFakeStartTag(tbodyTag);
- ASSERT(m_insertionMode == InsertionMode::InTableBody);
+ ASSERT(insertionMode() == InsertionMode::InTableBody);
processStartTag(token);
return;
}
- if (token.name() == tableTag) {
+ if (token->name() == tableTag) {
parseError(token);
if (!processTableEndTagForInTable()) {
ASSERT(isParsingFragmentOrTemplateContents());
@@ -1013,29 +1060,29 @@ void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken& token)
processStartTag(token);
return;
}
- if (token.name() == styleTag || token.name() == scriptTag) {
+ if (token->name() == styleTag || token->name() == scriptTag) {
processStartTagForInHead(token);
return;
}
- if (token.name() == inputTag) {
- Attribute* typeAttribute = findAttribute(token.attributes(), typeAttr);
+ if (token->name() == inputTag) {
+ Attribute* typeAttribute = token->getAttributeItem(typeAttr);
if (typeAttribute && equalIgnoringCase(typeAttribute->value(), "hidden")) {
parseError(token);
- m_tree.insertSelfClosingHTMLElement(&token);
+ m_tree.insertSelfClosingHTMLElement(token);
return;
}
// Fall through to "anything else" case.
}
- if (token.name() == formTag) {
+ if (token->name() == formTag) {
parseError(token);
if (m_tree.form() && !isParsingTemplateContents())
return;
- m_tree.insertHTMLFormElement(&token, true);
- m_tree.openElements().pop();
+ m_tree.insertHTMLFormElement(token, true);
+ m_tree.openElements()->pop();
return;
}
#if ENABLE(TEMPLATE_ELEMENT)
- if (token.name() == templateTag) {
+ if (token->name() == templateTag) {
processTemplateStartTag(token);
return;
}
@@ -1045,94 +1092,98 @@ void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken& token)
processStartTagForInBody(token);
}
-void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::StartTag);
- switch (m_insertionMode) {
+ ASSERT(token->type() == HTMLToken::StartTag);
+ switch (insertionMode()) {
case InsertionMode::Initial:
+ ASSERT(insertionMode() == InsertionMode::Initial);
defaultForInitial();
- ASSERT(m_insertionMode == InsertionMode::BeforeHTML);
FALLTHROUGH;
case InsertionMode::BeforeHTML:
- if (token.name() == htmlTag) {
- m_tree.insertHTMLHtmlStartTagBeforeHTML(&token);
- m_insertionMode = InsertionMode::BeforeHead;
+ ASSERT(insertionMode() == InsertionMode::BeforeHTML);
+ if (token->name() == htmlTag) {
+ m_tree.insertHTMLHtmlStartTagBeforeHTML(token);
+ setInsertionMode(InsertionMode::BeforeHead);
return;
}
defaultForBeforeHTML();
- ASSERT(m_insertionMode == InsertionMode::BeforeHead);
FALLTHROUGH;
case InsertionMode::BeforeHead:
- if (token.name() == htmlTag) {
+ ASSERT(insertionMode() == InsertionMode::BeforeHead);
+ if (token->name() == htmlTag) {
processHtmlStartTagForInBody(token);
return;
}
- if (token.name() == headTag) {
- m_tree.insertHTMLHeadElement(&token);
- m_insertionMode = InsertionMode::InHead;
+ if (token->name() == headTag) {
+ m_tree.insertHTMLHeadElement(token);
+ setInsertionMode(InsertionMode::InHead);
return;
}
defaultForBeforeHead();
- ASSERT(m_insertionMode == InsertionMode::InHead);
FALLTHROUGH;
case InsertionMode::InHead:
+ ASSERT(insertionMode() == InsertionMode::InHead);
if (processStartTagForInHead(token))
return;
defaultForInHead();
- ASSERT(m_insertionMode == InsertionMode::AfterHead);
FALLTHROUGH;
case InsertionMode::AfterHead:
- if (token.name() == htmlTag) {
+ ASSERT(insertionMode() == InsertionMode::AfterHead);
+ if (token->name() == htmlTag) {
processHtmlStartTagForInBody(token);
return;
}
- if (token.name() == bodyTag) {
+ if (token->name() == bodyTag) {
m_framesetOk = false;
- m_tree.insertHTMLBodyElement(&token);
- m_insertionMode = InsertionMode::InBody;
+ m_tree.insertHTMLBodyElement(token);
+ setInsertionMode(InsertionMode::InBody);
return;
}
- if (token.name() == framesetTag) {
- m_tree.insertHTMLElement(&token);
- m_insertionMode = InsertionMode::InFrameset;
+ if (token->name() == framesetTag) {
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InsertionMode::InFrameset);
return;
}
- if (token.name() == baseTag
- || token.name() == basefontTag
- || token.name() == bgsoundTag
- || token.name() == linkTag
- || token.name() == metaTag
- || token.name() == noframesTag
- || token.name() == scriptTag
- || token.name() == styleTag
+ if (token->name() == baseTag
+ || token->name() == basefontTag
+ || token->name() == bgsoundTag
+ || token->name() == linkTag
+ || token->name() == metaTag
+ || token->name() == noframesTag
+ || token->name() == scriptTag
+ || token->name() == styleTag
#if ENABLE(TEMPLATE_ELEMENT)
- || token.name() == templateTag
+ || token->name() == templateTag
#endif
- || token.name() == titleTag) {
+ || token->name() == titleTag) {
parseError(token);
- m_tree.openElements().pushHTMLHeadElement(m_tree.headStackItem());
+ ASSERT(m_tree.head());
+ m_tree.openElements()->pushHTMLHeadElement(m_tree.headStackItem());
processStartTagForInHead(token);
- m_tree.openElements().removeHTMLHeadElement(&m_tree.head());
+ m_tree.openElements()->removeHTMLHeadElement(m_tree.head());
return;
}
- if (token.name() == headTag) {
+ if (token->name() == headTag) {
parseError(token);
return;
}
defaultForAfterHead();
- ASSERT(m_insertionMode == InsertionMode::InBody);
FALLTHROUGH;
case InsertionMode::InBody:
+ ASSERT(insertionMode() == InsertionMode::InBody);
processStartTagForInBody(token);
break;
case InsertionMode::InTable:
+ ASSERT(insertionMode() == InsertionMode::InTable);
processStartTagForInTable(token);
break;
case InsertionMode::InCaption:
- if (isCaptionColOrColgroupTag(token.name())
- || isTableBodyContextTag(token.name())
- || isTableCellContextTag(token.name())
- || token.name() == trTag) {
+ ASSERT(insertionMode() == InsertionMode::InCaption);
+ if (isCaptionColOrColgroupTag(token->name())
+ || isTableBodyContextTag(token->name())
+ || isTableCellContextTag(token->name())
+ || token->name() == trTag) {
parseError(token);
if (!processCaptionEndTagForInCaption()) {
ASSERT(isParsingFragment());
@@ -1144,16 +1195,17 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
processStartTagForInBody(token);
break;
case InsertionMode::InColumnGroup:
- if (token.name() == htmlTag) {
+ ASSERT(insertionMode() == InsertionMode::InColumnGroup);
+ if (token->name() == htmlTag) {
processHtmlStartTagForInBody(token);
return;
}
- if (token.name() == colTag) {
- m_tree.insertSelfClosingHTMLElement(&token);
+ if (token->name() == colTag) {
+ m_tree.insertSelfClosingHTMLElement(token);
return;
}
#if ENABLE(TEMPLATE_ELEMENT)
- if (token.name() == templateTag) {
+ if (token->name() == templateTag) {
processTemplateStartTag(token);
return;
}
@@ -1165,62 +1217,65 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
processStartTag(token);
break;
case InsertionMode::InTableBody:
- if (token.name() == trTag) {
- m_tree.openElements().popUntilTableBodyScopeMarker(); // How is there ever anything to pop?
- m_tree.insertHTMLElement(&token);
- m_insertionMode = InsertionMode::InRow;
+ ASSERT(insertionMode() == InsertionMode::InTableBody);
+ if (token->name() == trTag) {
+ m_tree.openElements()->popUntilTableBodyScopeMarker(); // How is there ever anything to pop?
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InsertionMode::InRow);
return;
}
- if (isTableCellContextTag(token.name())) {
+ if (isTableCellContextTag(token->name())) {
parseError(token);
processFakeStartTag(trTag);
- ASSERT(m_insertionMode == InsertionMode::InRow);
+ ASSERT(insertionMode() == InsertionMode::InRow);
processStartTag(token);
return;
}
- if (isCaptionColOrColgroupTag(token.name()) || isTableBodyContextTag(token.name())) {
+ if (isCaptionColOrColgroupTag(token->name()) || isTableBodyContextTag(token->name())) {
// FIXME: This is slow.
- if (!m_tree.openElements().inTableScope(tbodyTag) && !m_tree.openElements().inTableScope(theadTag) && !m_tree.openElements().inTableScope(tfootTag)) {
+ if (!m_tree.openElements()->inTableScope(tbodyTag) && !m_tree.openElements()->inTableScope(theadTag) && !m_tree.openElements()->inTableScope(tfootTag)) {
ASSERT(isParsingFragmentOrTemplateContents());
parseError(token);
return;
}
- m_tree.openElements().popUntilTableBodyScopeMarker();
- ASSERT(isTableBodyContextTag(m_tree.currentStackItem().localName()));
- processFakeEndTag(m_tree.currentStackItem().localName());
+ m_tree.openElements()->popUntilTableBodyScopeMarker();
+ ASSERT(isTableBodyContextTag(m_tree.currentStackItem()->localName()));
+ processFakeEndTag(m_tree.currentStackItem()->localName());
processStartTag(token);
return;
}
processStartTagForInTable(token);
break;
case InsertionMode::InRow:
- if (isTableCellContextTag(token.name())) {
- m_tree.openElements().popUntilTableRowScopeMarker();
- m_tree.insertHTMLElement(&token);
- m_insertionMode = InsertionMode::InCell;
- m_tree.activeFormattingElements().appendMarker();
+ ASSERT(insertionMode() == InsertionMode::InRow);
+ if (isTableCellContextTag(token->name())) {
+ m_tree.openElements()->popUntilTableRowScopeMarker();
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InsertionMode::InCell);
+ m_tree.activeFormattingElements()->appendMarker();
return;
}
- if (token.name() == trTag
- || isCaptionColOrColgroupTag(token.name())
- || isTableBodyContextTag(token.name())) {
+ if (token->name() == trTag
+ || isCaptionColOrColgroupTag(token->name())
+ || isTableBodyContextTag(token->name())) {
if (!processTrEndTagForInRow()) {
ASSERT(isParsingFragmentOrTemplateContents());
return;
}
- ASSERT(m_insertionMode == InsertionMode::InTableBody);
+ ASSERT(insertionMode() == InsertionMode::InTableBody);
processStartTag(token);
return;
}
processStartTagForInTable(token);
break;
case InsertionMode::InCell:
- if (isCaptionColOrColgroupTag(token.name())
- || isTableCellContextTag(token.name())
- || token.name() == trTag
- || isTableBodyContextTag(token.name())) {
+ ASSERT(insertionMode() == InsertionMode::InCell);
+ if (isCaptionColOrColgroupTag(token->name())
+ || isTableCellContextTag(token->name())
+ || token->name() == trTag
+ || isTableBodyContextTag(token->name())) {
// FIXME: This could be more efficient.
- if (!m_tree.openElements().inTableScope(tdTag) && !m_tree.openElements().inTableScope(thTag)) {
+ if (!m_tree.openElements()->inTableScope(tdTag) && !m_tree.openElements()->inTableScope(thTag)) {
ASSERT(isParsingFragment());
parseError(token);
return;
@@ -1233,29 +1288,31 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
break;
case InsertionMode::AfterBody:
case InsertionMode::AfterAfterBody:
- if (token.name() == htmlTag) {
+ ASSERT(insertionMode() == InsertionMode::AfterBody || insertionMode() == InsertionMode::AfterAfterBody);
+ if (token->name() == htmlTag) {
processHtmlStartTagForInBody(token);
return;
}
- m_insertionMode = InsertionMode::InBody;
+ setInsertionMode(InsertionMode::InBody);
processStartTag(token);
break;
case InsertionMode::InHeadNoscript:
- if (token.name() == htmlTag) {
+ ASSERT(insertionMode() == InsertionMode::InHeadNoscript);
+ if (token->name() == htmlTag) {
processHtmlStartTagForInBody(token);
return;
}
- if (token.name() == basefontTag
- || token.name() == bgsoundTag
- || token.name() == linkTag
- || token.name() == metaTag
- || token.name() == noframesTag
- || token.name() == styleTag) {
+ if (token->name() == basefontTag
+ || token->name() == bgsoundTag
+ || token->name() == linkTag
+ || token->name() == metaTag
+ || token->name() == noframesTag
+ || token->name() == styleTag) {
bool didProcess = processStartTagForInHead(token);
ASSERT_UNUSED(didProcess, didProcess);
return;
}
- if (token.name() == htmlTag || token.name() == noscriptTag) {
+ if (token->name() == htmlTag || token->name() == noscriptTag) {
parseError(token);
return;
}
@@ -1263,24 +1320,25 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
processToken(token);
break;
case InsertionMode::InFrameset:
- if (token.name() == htmlTag) {
+ ASSERT(insertionMode() == InsertionMode::InFrameset);
+ if (token->name() == htmlTag) {
processHtmlStartTagForInBody(token);
return;
}
- if (token.name() == framesetTag) {
- m_tree.insertHTMLElement(&token);
+ if (token->name() == framesetTag) {
+ m_tree.insertHTMLElement(token);
return;
}
- if (token.name() == frameTag) {
- m_tree.insertSelfClosingHTMLElement(&token);
+ if (token->name() == frameTag) {
+ m_tree.insertSelfClosingHTMLElement(token);
return;
}
- if (token.name() == noframesTag) {
+ if (token->name() == noframesTag) {
processStartTagForInHead(token);
return;
}
#if ENABLE(TEMPLATE_ELEMENT)
- if (token.name() == templateTag) {
+ if (token->name() == templateTag) {
processTemplateStartTag(token);
return;
}
@@ -1289,78 +1347,83 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
break;
case InsertionMode::AfterFrameset:
case InsertionMode::AfterAfterFrameset:
- if (token.name() == htmlTag) {
+ ASSERT(insertionMode() == InsertionMode::AfterFrameset || insertionMode() == InsertionMode::AfterAfterFrameset);
+ if (token->name() == htmlTag) {
processHtmlStartTagForInBody(token);
return;
}
- if (token.name() == noframesTag) {
+ if (token->name() == noframesTag) {
processStartTagForInHead(token);
return;
}
parseError(token);
break;
case InsertionMode::InSelectInTable:
- if (token.name() == captionTag
- || token.name() == tableTag
- || isTableBodyContextTag(token.name())
- || token.name() == trTag
- || isTableCellContextTag(token.name())) {
+ ASSERT(insertionMode() == InsertionMode::InSelectInTable);
+ if (token->name() == captionTag
+ || token->name() == tableTag
+ || isTableBodyContextTag(token->name())
+ || token->name() == trTag
+ || isTableCellContextTag(token->name())) {
parseError(token);
AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
- processEndTag(endSelect);
+ processEndTag(&endSelect);
processStartTag(token);
return;
}
FALLTHROUGH;
case InsertionMode::InSelect:
- if (token.name() == htmlTag) {
+ ASSERT(insertionMode() == InsertionMode::InSelect || insertionMode() == InsertionMode::InSelectInTable);
+ if (token->name() == htmlTag) {
processHtmlStartTagForInBody(token);
return;
}
- if (token.name() == optionTag) {
- if (is<HTMLOptionElement>(m_tree.currentStackItem().node())) {
+ if (token->name() == optionTag) {
+ if (isHTMLOptionElement(m_tree.currentStackItem()->node())) {
AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
- processEndTag(endOption);
+ processEndTag(&endOption);
}
- m_tree.insertHTMLElement(&token);
+ m_tree.insertHTMLElement(token);
return;
}
- if (token.name() == optgroupTag) {
- if (is<HTMLOptionElement>(m_tree.currentStackItem().node())) {
+ if (token->name() == optgroupTag) {
+ if (isHTMLOptionElement(m_tree.currentStackItem()->node())) {
AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
- processEndTag(endOption);
+ processEndTag(&endOption);
}
- if (is<HTMLOptGroupElement>(m_tree.currentStackItem().node())) {
+ if (isHTMLOptGroupElement(m_tree.currentStackItem()->node())) {
AtomicHTMLToken endOptgroup(HTMLToken::EndTag, optgroupTag.localName());
- processEndTag(endOptgroup);
+ processEndTag(&endOptgroup);
}
- m_tree.insertHTMLElement(&token);
+ m_tree.insertHTMLElement(token);
return;
}
- if (token.name() == selectTag) {
+ if (token->name() == selectTag) {
parseError(token);
AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
- processEndTag(endSelect);
+ processEndTag(&endSelect);
return;
}
- if (token.name() == inputTag || token.name() == keygenTag || token.name() == textareaTag) {
+ if (token->name() == inputTag
+ || token->name() == keygenTag
+ || token->name() == textareaTag) {
parseError(token);
- if (!m_tree.openElements().inSelectScope(selectTag)) {
+ if (!m_tree.openElements()->inSelectScope(selectTag)) {
ASSERT(isParsingFragment());
return;
}
AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
- processEndTag(endSelect);
+ processEndTag(&endSelect);
processStartTag(token);
return;
}
- if (token.name() == scriptTag) {
+ if (token->name() == scriptTag) {
bool didProcess = processStartTagForInHead(token);
ASSERT_UNUSED(didProcess, didProcess);
return;
}
#if ENABLE(TEMPLATE_ELEMENT)
- if (token.name() == templateTag) {
+ if (token->name() == templateTag) {
processTemplateStartTag(token);
return;
}
@@ -1373,31 +1436,31 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
case InsertionMode::Text:
ASSERT_NOT_REACHED();
break;
-#if ENABLE(TEMPLATE_ELEMENT)
case InsertionMode::TemplateContents:
- if (token.name() == templateTag) {
+#if ENABLE(TEMPLATE_ELEMENT)
+ if (token->name() == templateTag) {
processTemplateStartTag(token);
return;
}
- if (token.name() == linkTag
- || token.name() == scriptTag
- || token.name() == styleTag
- || token.name() == metaTag) {
+ if (token->name() == linkTag
+ || token->name() == scriptTag
+ || token->name() == styleTag
+ || token->name() == metaTag) {
processStartTagForInHead(token);
return;
}
InsertionMode insertionMode = InsertionMode::TemplateContents;
- if (token.name() == frameTag)
+ if (token->name() == frameTag)
insertionMode = InsertionMode::InFrameset;
- else if (token.name() == colTag)
+ else if (token->name() == colTag)
insertionMode = InsertionMode::InColumnGroup;
- else if (isCaptionColOrColgroupTag(token.name()) || isTableBodyContextTag(token.name()))
+ else if (isCaptionColOrColgroupTag(token->name()) || isTableBodyContextTag(token->name()))
insertionMode = InsertionMode::InTable;
- else if (token.name() == trTag)
+ else if (token->name() == trTag)
insertionMode = InsertionMode::InTableBody;
- else if (isTableCellContextTag(token.name()))
+ else if (isTableCellContextTag(token->name()))
insertionMode = InsertionMode::InRow;
else
insertionMode = InsertionMode::InBody;
@@ -1405,60 +1468,64 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
ASSERT(insertionMode != InsertionMode::TemplateContents);
ASSERT(m_templateInsertionModes.last() == InsertionMode::TemplateContents);
m_templateInsertionModes.last() = insertionMode;
- m_insertionMode = insertionMode;
+ setInsertionMode(insertionMode);
processStartTag(token);
- break;
+#else
+ ASSERT_NOT_REACHED();
#endif
+ break;
}
}
-void HTMLTreeBuilder::processHtmlStartTagForInBody(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processHtmlStartTagForInBody(AtomicHTMLToken* token)
{
parseError(token);
#if ENABLE(TEMPLATE_ELEMENT)
- if (m_tree.openElements().hasTemplateInHTMLScope()) {
+ if (m_tree.openElements()->hasTemplateInHTMLScope()) {
ASSERT(isParsingTemplateContents());
return;
}
#endif
- m_tree.insertHTMLHtmlStartTagInBody(&token);
+ m_tree.insertHTMLHtmlStartTagInBody(token);
}
-bool HTMLTreeBuilder::processBodyEndTagForInBody(AtomicHTMLToken& token)
+bool HTMLTreeBuilder::processBodyEndTagForInBody(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::EndTag);
- ASSERT(token.name() == bodyTag);
- if (!m_tree.openElements().inScope(bodyTag.localName())) {
+ ASSERT(token->type() == HTMLToken::EndTag);
+ ASSERT(token->name() == bodyTag);
+ if (!m_tree.openElements()->inScope(bodyTag.localName())) {
parseError(token);
return false;
}
notImplemented(); // Emit a more specific parse error based on stack contents.
- m_insertionMode = InsertionMode::AfterBody;
+ setInsertionMode(InsertionMode::AfterBody);
return true;
}
-void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::EndTag);
- for (auto* record = &m_tree.openElements().topRecord(); ; record = record->next()) {
- HTMLStackItem& item = record->stackItem();
- if (item.matchesHTMLTag(token.name())) {
- m_tree.generateImpliedEndTagsWithExclusion(token.name());
- if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
+ ASSERT(token->type() == HTMLToken::EndTag);
+ HTMLElementStack::ElementRecord* record = m_tree.openElements()->topRecord();
+ while (1) {
+ RefPtr<HTMLStackItem> item = record->stackItem();
+ if (item->matchesHTMLTag(token->name())) {
+ m_tree.generateImpliedEndTagsWithExclusion(token->name());
+ if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
parseError(token);
- m_tree.openElements().popUntilPopped(&item.element());
+ m_tree.openElements()->popUntilPopped(item->element());
return;
}
- if (isSpecialNode(item)) {
+ if (item->isSpecialNode()) {
parseError(token);
return;
}
+ record = record->next();
}
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-inbody
-void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
+void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token)
{
// The adoption agency algorithm is N^2. We limit the number of iterations
// to stop from hanging the whole browser. This limit is specified in the
@@ -1470,43 +1537,43 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
// 1, 2, 3 and 16 are covered by the for() loop.
for (int i = 0; i < outerIterationLimit; ++i) {
// 4.
- Element* formattingElement = m_tree.activeFormattingElements().closestElementInScopeWithName(token.name());
+ Element* formattingElement = m_tree.activeFormattingElements()->closestElementInScopeWithName(token->name());
// 4.a
if (!formattingElement)
return processAnyOtherEndTagForInBody(token);
// 4.c
- if ((m_tree.openElements().contains(formattingElement)) && !m_tree.openElements().inScope(formattingElement)) {
+ if ((m_tree.openElements()->contains(formattingElement)) && !m_tree.openElements()->inScope(formattingElement)) {
parseError(token);
notImplemented(); // Check the stack of open elements for a more specific parse error.
return;
}
// 4.b
- auto* formattingElementRecord = m_tree.openElements().find(formattingElement);
+ HTMLElementStack::ElementRecord* formattingElementRecord = m_tree.openElements()->find(formattingElement);
if (!formattingElementRecord) {
parseError(token);
- m_tree.activeFormattingElements().remove(formattingElement);
+ m_tree.activeFormattingElements()->remove(formattingElement);
return;
}
// 4.d
- if (formattingElement != &m_tree.currentElement())
+ if (formattingElement != m_tree.currentElement())
parseError(token);
// 5.
- auto* furthestBlock = m_tree.openElements().furthestBlockForFormattingElement(formattingElement);
+ HTMLElementStack::ElementRecord* furthestBlock = m_tree.openElements()->furthestBlockForFormattingElement(formattingElement);
// 6.
if (!furthestBlock) {
- m_tree.openElements().popUntilPopped(formattingElement);
- m_tree.activeFormattingElements().remove(formattingElement);
+ m_tree.openElements()->popUntilPopped(formattingElement);
+ m_tree.activeFormattingElements()->remove(formattingElement);
return;
}
// 7.
ASSERT(furthestBlock->isAbove(formattingElementRecord));
- Ref<HTMLStackItem> commonAncestor = formattingElementRecord->next()->stackItem();
+ RefPtr<HTMLStackItem> commonAncestor = formattingElementRecord->next()->stackItem();
// 8.
- HTMLFormattingElementList::Bookmark bookmark = m_tree.activeFormattingElements().bookmarkFor(formattingElement);
+ HTMLFormattingElementList::Bookmark bookmark = m_tree.activeFormattingElements()->bookmarkFor(formattingElement);
// 9.
- auto* node = furthestBlock;
- auto* nextNode = node->next();
- auto* lastNode = furthestBlock;
+ HTMLElementStack::ElementRecord* node = furthestBlock;
+ HTMLElementStack::ElementRecord* nextNode = node->next();
+ HTMLElementStack::ElementRecord* lastNode = furthestBlock;
// 9.1, 9.2, 9.3 and 9.11 are covered by the for() loop.
for (int i = 0; i < innerIterationLimit; ++i) {
// 9.4
@@ -1514,8 +1581,8 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
ASSERT(node);
nextNode = node->next(); // Save node->next() for the next iteration in case node is deleted in 9.5.
// 9.5
- if (!m_tree.activeFormattingElements().contains(&node->element())) {
- m_tree.openElements().remove(&node->element());
+ if (!m_tree.activeFormattingElements()->contains(node->element())) {
+ m_tree.openElements()->remove(node->element());
node = 0;
continue;
}
@@ -1523,10 +1590,10 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
if (node == formattingElementRecord)
break;
// 9.7
- RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(&node->stackItem());
+ RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(node->stackItem().get());
- HTMLFormattingElementList::Entry* nodeEntry = m_tree.activeFormattingElements().find(&node->element());
- nodeEntry->replaceElement(newItem.copyRef());
+ HTMLFormattingElementList::Entry* nodeEntry = m_tree.activeFormattingElements()->find(node->element());
+ nodeEntry->replaceElement(newItem);
node->replaceElement(newItem.release());
// 9.8
@@ -1538,18 +1605,18 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
lastNode = node;
}
// 10.
- m_tree.insertAlreadyParsedChild(commonAncestor.get(), *lastNode);
+ m_tree.insertAlreadyParsedChild(*commonAncestor, *lastNode);
// 11.
- RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(&formattingElementRecord->stackItem());
+ RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(formattingElementRecord->stackItem().get());
// 12.
m_tree.takeAllChildren(*newItem, *furthestBlock);
// 13.
m_tree.reparent(*furthestBlock, *newItem);
// 14.
- m_tree.activeFormattingElements().swapTo(formattingElement, newItem, bookmark);
+ m_tree.activeFormattingElements()->swapTo(formattingElement, newItem, bookmark);
// 15.
- m_tree.openElements().remove(formattingElement);
- m_tree.openElements().insertAbove(newItem, furthestBlock);
+ m_tree.openElements()->remove(formattingElement);
+ m_tree.openElements()->insertAbove(newItem, furthestBlock);
}
}
@@ -1557,9 +1624,10 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
{
// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#reset-the-insertion-mode-appropriately
bool last = false;
- for (auto* record = &m_tree.openElements().topRecord(); ; record = record->next()) {
- HTMLStackItem* item = &record->stackItem();
- if (&item->node() == &m_tree.openElements().rootNode()) {
+ HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
+ while (1) {
+ RefPtr<HTMLStackItem> item = nodeRecord->stackItem();
+ if (item->node() == m_tree.openElements()->rootNode()) {
last = true;
#if ENABLE(TEMPLATE_ELEMENT)
bool shouldCreateItem = isParsingFragment();
@@ -1568,193 +1636,167 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
bool shouldCreateItem = true;
#endif
if (shouldCreateItem)
- item = &m_fragmentContext.contextElementStackItem();
+ item = HTMLStackItem::create(m_fragmentContext.contextElement(), HTMLStackItem::ItemForContextElement);
}
-
#if ENABLE(TEMPLATE_ELEMENT)
- if (item->hasTagName(templateTag)) {
- m_insertionMode = m_templateInsertionModes.last();
- return;
- }
+ if (item->hasTagName(templateTag))
+ return setInsertionMode(m_templateInsertionModes.last());
#endif
if (item->hasTagName(selectTag)) {
#if ENABLE(TEMPLATE_ELEMENT)
if (!last) {
- while (&item->node() != &m_tree.openElements().rootNode() && !item->hasTagName(templateTag)) {
- record = record->next();
- item = &record->stackItem();
- if (is<HTMLTableElement>(item->node())) {
- m_insertionMode = InsertionMode::InSelectInTable;
- return;
- }
+ while (item->node() != m_tree.openElements()->rootNode() && !item->hasTagName(templateTag)) {
+ nodeRecord = nodeRecord->next();
+ item = nodeRecord->stackItem();
+ if (isHTMLTableElement(item->node()))
+ return setInsertionMode(InsertionMode::InSelectInTable);
}
}
#endif
- m_insertionMode = InsertionMode::InSelect;
- return;
- }
- if (item->hasTagName(tdTag) || item->hasTagName(thTag)) {
- m_insertionMode = InsertionMode::InCell;
- return;
- }
- if (item->hasTagName(trTag)) {
- m_insertionMode = InsertionMode::InRow;
- return;
- }
- if (item->hasTagName(tbodyTag) || item->hasTagName(theadTag) || item->hasTagName(tfootTag)) {
- m_insertionMode = InsertionMode::InTableBody;
- return;
- }
- if (item->hasTagName(captionTag)) {
- m_insertionMode = InsertionMode::InCaption;
- return;
- }
+ return setInsertionMode(InsertionMode::InSelect);
+ }
+ if (item->hasTagName(tdTag) || item->hasTagName(thTag))
+ return setInsertionMode(InsertionMode::InCell);
+ if (item->hasTagName(trTag))
+ return setInsertionMode(InsertionMode::InRow);
+ if (item->hasTagName(tbodyTag) || item->hasTagName(theadTag) || item->hasTagName(tfootTag))
+ return setInsertionMode(InsertionMode::InTableBody);
+ if (item->hasTagName(captionTag))
+ return setInsertionMode(InsertionMode::InCaption);
if (item->hasTagName(colgroupTag)) {
- m_insertionMode = InsertionMode::InColumnGroup;
- return;
- }
- if (is<HTMLTableElement>(item->node())) {
- m_insertionMode = InsertionMode::InTable;
- return;
+ return setInsertionMode(InsertionMode::InColumnGroup);
}
+ if (isHTMLTableElement(item->node()))
+ return setInsertionMode(InsertionMode::InTable);
if (item->hasTagName(headTag)) {
#if ENABLE(TEMPLATE_ELEMENT)
- if (!m_fragmentContext.fragment() || &m_fragmentContext.contextElement() != &item->node()) {
- m_insertionMode = InsertionMode::InHead;
- return;
- }
+ if (!m_fragmentContext.fragment() || m_fragmentContext.contextElement() != item->node())
+ return setInsertionMode(InsertionMode::InHead);
#endif
- m_insertionMode = InsertionMode::InBody;
- return;
- }
- if (item->hasTagName(bodyTag)) {
- m_insertionMode = InsertionMode::InBody;
- return;
+ return setInsertionMode(InsertionMode::InBody);
}
+ if (item->hasTagName(bodyTag))
+ return setInsertionMode(InsertionMode::InBody);
if (item->hasTagName(framesetTag)) {
- m_insertionMode = InsertionMode::InFrameset;
- return;
+ return setInsertionMode(InsertionMode::InFrameset);
}
if (item->hasTagName(htmlTag)) {
- if (m_tree.headStackItem()) {
- m_insertionMode = InsertionMode::AfterHead;
- return;
- }
+ if (m_tree.headStackItem())
+ return setInsertionMode(InsertionMode::AfterHead);
ASSERT(isParsingFragment());
- m_insertionMode = InsertionMode::BeforeHead;
- return;
+ return setInsertionMode(InsertionMode::BeforeHead);
}
if (last) {
ASSERT(isParsingFragment());
- m_insertionMode = InsertionMode::InBody;
- return;
+ return setInsertionMode(InsertionMode::InBody);
}
+ nodeRecord = nodeRecord->next();
}
}
-void HTMLTreeBuilder::processEndTagForInTableBody(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processEndTagForInTableBody(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::EndTag);
- if (isTableBodyContextTag(token.name())) {
- if (!m_tree.openElements().inTableScope(token.name())) {
+ ASSERT(token->type() == HTMLToken::EndTag);
+ if (isTableBodyContextTag(token->name())) {
+ if (!m_tree.openElements()->inTableScope(token->name())) {
parseError(token);
return;
}
- m_tree.openElements().popUntilTableBodyScopeMarker();
- m_tree.openElements().pop();
- m_insertionMode = InsertionMode::InTable;
+ m_tree.openElements()->popUntilTableBodyScopeMarker();
+ m_tree.openElements()->pop();
+ setInsertionMode(InsertionMode::InTable);
return;
}
- if (token.name() == tableTag) {
+ if (token->name() == tableTag) {
// FIXME: This is slow.
- if (!m_tree.openElements().inTableScope(tbodyTag) && !m_tree.openElements().inTableScope(theadTag) && !m_tree.openElements().inTableScope(tfootTag)) {
+ if (!m_tree.openElements()->inTableScope(tbodyTag) && !m_tree.openElements()->inTableScope(theadTag) && !m_tree.openElements()->inTableScope(tfootTag)) {
ASSERT(isParsingFragmentOrTemplateContents());
parseError(token);
return;
}
- m_tree.openElements().popUntilTableBodyScopeMarker();
- ASSERT(isTableBodyContextTag(m_tree.currentStackItem().localName()));
- processFakeEndTag(m_tree.currentStackItem().localName());
+ m_tree.openElements()->popUntilTableBodyScopeMarker();
+ ASSERT(isTableBodyContextTag(m_tree.currentStackItem()->localName()));
+ processFakeEndTag(m_tree.currentStackItem()->localName());
processEndTag(token);
return;
}
- if (token.name() == bodyTag
- || isCaptionColOrColgroupTag(token.name())
- || token.name() == htmlTag
- || isTableCellContextTag(token.name())
- || token.name() == trTag) {
+ if (token->name() == bodyTag
+ || isCaptionColOrColgroupTag(token->name())
+ || token->name() == htmlTag
+ || isTableCellContextTag(token->name())
+ || token->name() == trTag) {
parseError(token);
return;
}
processEndTagForInTable(token);
}
-void HTMLTreeBuilder::processEndTagForInRow(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processEndTagForInRow(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::EndTag);
- if (token.name() == trTag) {
+ ASSERT(token->type() == HTMLToken::EndTag);
+ if (token->name() == trTag) {
processTrEndTagForInRow();
return;
}
- if (token.name() == tableTag) {
+ if (token->name() == tableTag) {
if (!processTrEndTagForInRow()) {
ASSERT(isParsingFragmentOrTemplateContents());
return;
}
- ASSERT(m_insertionMode == InsertionMode::InTableBody);
+ ASSERT(insertionMode() == InsertionMode::InTableBody);
processEndTag(token);
return;
}
- if (isTableBodyContextTag(token.name())) {
- if (!m_tree.openElements().inTableScope(token.name())) {
+ if (isTableBodyContextTag(token->name())) {
+ if (!m_tree.openElements()->inTableScope(token->name())) {
parseError(token);
return;
}
processFakeEndTag(trTag);
- ASSERT(m_insertionMode == InsertionMode::InTableBody);
+ ASSERT(insertionMode() == InsertionMode::InTableBody);
processEndTag(token);
return;
}
- if (token.name() == bodyTag
- || isCaptionColOrColgroupTag(token.name())
- || token.name() == htmlTag
- || isTableCellContextTag(token.name())) {
+ if (token->name() == bodyTag
+ || isCaptionColOrColgroupTag(token->name())
+ || token->name() == htmlTag
+ || isTableCellContextTag(token->name())) {
parseError(token);
return;
}
processEndTagForInTable(token);
}
-void HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::EndTag);
- if (isTableCellContextTag(token.name())) {
- if (!m_tree.openElements().inTableScope(token.name())) {
+ ASSERT(token->type() == HTMLToken::EndTag);
+ if (isTableCellContextTag(token->name())) {
+ if (!m_tree.openElements()->inTableScope(token->name())) {
parseError(token);
return;
}
m_tree.generateImpliedEndTags();
- if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
+ if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
parseError(token);
- m_tree.openElements().popUntilPopped(token.name());
- m_tree.activeFormattingElements().clearToLastMarker();
- m_insertionMode = InsertionMode::InRow;
+ m_tree.openElements()->popUntilPopped(token->name());
+ m_tree.activeFormattingElements()->clearToLastMarker();
+ setInsertionMode(InsertionMode::InRow);
return;
}
- if (token.name() == bodyTag
- || isCaptionColOrColgroupTag(token.name())
- || token.name() == htmlTag) {
+ if (token->name() == bodyTag
+ || isCaptionColOrColgroupTag(token->name())
+ || token->name() == htmlTag) {
parseError(token);
return;
}
- if (token.name() == tableTag
- || token.name() == trTag
- || isTableBodyContextTag(token.name())) {
- if (!m_tree.openElements().inTableScope(token.name())) {
+ if (token->name() == tableTag
+ || token->name() == trTag
+ || isTableBodyContextTag(token->name())) {
+ if (!m_tree.openElements()->inTableScope(token->name())) {
#if ENABLE(TEMPLATE_ELEMENT)
- ASSERT(isTableBodyContextTag(token.name()) || m_tree.openElements().inTableScope(templateTag) || isParsingFragment());
+ ASSERT(isTableBodyContextTag(token->name()) || m_tree.openElements()->inTableScope(templateTag) || isParsingFragment());
#else
- ASSERT(isTableBodyContextTag(token.name()) || isParsingFragment());
+ ASSERT(isTableBodyContextTag(token->name()) || isParsingFragment());
#endif
parseError(token);
return;
@@ -1766,146 +1808,149 @@ void HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken& token)
processEndTagForInBody(token);
}
-void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::EndTag);
- if (token.name() == bodyTag) {
+ ASSERT(token->type() == HTMLToken::EndTag);
+ if (token->name() == bodyTag) {
processBodyEndTagForInBody(token);
return;
}
- if (token.name() == htmlTag) {
+ if (token->name() == htmlTag) {
AtomicHTMLToken endBody(HTMLToken::EndTag, bodyTag.localName());
- if (processBodyEndTagForInBody(endBody))
+ if (processBodyEndTagForInBody(&endBody))
processEndTag(token);
return;
}
- if (token.name() == addressTag
- || token.name() == articleTag
- || token.name() == asideTag
- || token.name() == blockquoteTag
- || token.name() == buttonTag
- || token.name() == centerTag
- || token.name() == detailsTag
- || token.name() == dirTag
- || token.name() == divTag
- || token.name() == dlTag
- || token.name() == fieldsetTag
- || token.name() == figcaptionTag
- || token.name() == figureTag
- || token.name() == footerTag
- || token.name() == headerTag
- || token.name() == hgroupTag
- || token.name() == listingTag
- || token.name() == mainTag
- || token.name() == menuTag
- || token.name() == navTag
- || token.name() == olTag
- || token.name() == preTag
- || token.name() == sectionTag
- || token.name() == summaryTag
- || token.name() == ulTag) {
- if (!m_tree.openElements().inScope(token.name())) {
+ if (token->name() == addressTag
+ || token->name() == articleTag
+ || token->name() == asideTag
+ || token->name() == blockquoteTag
+ || token->name() == buttonTag
+ || token->name() == centerTag
+ || token->name() == detailsTag
+ || token->name() == dirTag
+ || token->name() == divTag
+ || token->name() == dlTag
+ || token->name() == fieldsetTag
+ || token->name() == figcaptionTag
+ || token->name() == figureTag
+ || token->name() == footerTag
+ || token->name() == headerTag
+ || token->name() == hgroupTag
+ || token->name() == listingTag
+ || token->name() == mainTag
+ || token->name() == menuTag
+ || token->name() == navTag
+ || token->name() == olTag
+ || token->name() == preTag
+ || token->name() == sectionTag
+ || token->name() == summaryTag
+ || token->name() == ulTag) {
+ if (!m_tree.openElements()->inScope(token->name())) {
parseError(token);
return;
}
m_tree.generateImpliedEndTags();
- if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
+ if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
parseError(token);
- m_tree.openElements().popUntilPopped(token.name());
+ m_tree.openElements()->popUntilPopped(token->name());
return;
}
- if (token.name() == formTag) {
+ if (token->name() == formTag) {
if (!isParsingTemplateContents()) {
RefPtr<Element> node = m_tree.takeForm();
- if (!node || !m_tree.openElements().inScope(node.get())) {
+ if (!node || !m_tree.openElements()->inScope(node.get())) {
parseError(token);
return;
}
m_tree.generateImpliedEndTags();
- if (&m_tree.currentNode() != node.get())
+ if (m_tree.currentNode() != node.get())
parseError(token);
- m_tree.openElements().remove(node.get());
+ m_tree.openElements()->remove(node.get());
} else {
- if (!m_tree.openElements().inScope(token.name())) {
+ if (!m_tree.openElements()->inScope(token->name())) {
parseError(token);
return;
}
m_tree.generateImpliedEndTags();
- if (!m_tree.currentNode().hasTagName(formTag))
+ if (!m_tree.currentNode()->hasTagName(formTag))
parseError(token);
- m_tree.openElements().popUntilPopped(token.name());
+ m_tree.openElements()->popUntilPopped(token->name());
}
}
- if (token.name() == pTag) {
- if (!m_tree.openElements().inButtonScope(token.name())) {
+ if (token->name() == pTag) {
+ if (!m_tree.openElements()->inButtonScope(token->name())) {
parseError(token);
processFakeStartTag(pTag);
- ASSERT(m_tree.openElements().inScope(token.name()));
+ ASSERT(m_tree.openElements()->inScope(token->name()));
processEndTag(token);
return;
}
- m_tree.generateImpliedEndTagsWithExclusion(token.name());
- if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
+ m_tree.generateImpliedEndTagsWithExclusion(token->name());
+ if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
parseError(token);
- m_tree.openElements().popUntilPopped(token.name());
+ m_tree.openElements()->popUntilPopped(token->name());
return;
}
- if (token.name() == liTag) {
- if (!m_tree.openElements().inListItemScope(token.name())) {
+ if (token->name() == liTag) {
+ if (!m_tree.openElements()->inListItemScope(token->name())) {
parseError(token);
return;
}
- m_tree.generateImpliedEndTagsWithExclusion(token.name());
- if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
+ m_tree.generateImpliedEndTagsWithExclusion(token->name());
+ if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
parseError(token);
- m_tree.openElements().popUntilPopped(token.name());
+ m_tree.openElements()->popUntilPopped(token->name());
return;
}
- if (token.name() == ddTag || token.name() == dtTag) {
- if (!m_tree.openElements().inScope(token.name())) {
+ if (token->name() == ddTag
+ || token->name() == dtTag) {
+ if (!m_tree.openElements()->inScope(token->name())) {
parseError(token);
return;
}
- m_tree.generateImpliedEndTagsWithExclusion(token.name());
- if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
+ m_tree.generateImpliedEndTagsWithExclusion(token->name());
+ if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
parseError(token);
- m_tree.openElements().popUntilPopped(token.name());
+ m_tree.openElements()->popUntilPopped(token->name());
return;
}
- if (isNumberedHeaderTag(token.name())) {
- if (!m_tree.openElements().hasNumberedHeaderElementInScope()) {
+ if (isNumberedHeaderTag(token->name())) {
+ if (!m_tree.openElements()->hasNumberedHeaderElementInScope()) {
parseError(token);
return;
}
m_tree.generateImpliedEndTags();
- if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
+ if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
parseError(token);
- m_tree.openElements().popUntilNumberedHeaderElementPopped();
+ m_tree.openElements()->popUntilNumberedHeaderElementPopped();
return;
}
- if (isFormattingTag(token.name())) {
+ if (isFormattingTag(token->name())) {
callTheAdoptionAgency(token);
return;
}
- if (token.name() == appletTag || token.name() == marqueeTag || token.name() == objectTag) {
- if (!m_tree.openElements().inScope(token.name())) {
+ if (token->name() == appletTag
+ || token->name() == marqueeTag
+ || token->name() == objectTag) {
+ if (!m_tree.openElements()->inScope(token->name())) {
parseError(token);
return;
}
m_tree.generateImpliedEndTags();
- if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
+ if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
parseError(token);
- m_tree.openElements().popUntilPopped(token.name());
- m_tree.activeFormattingElements().clearToLastMarker();
+ m_tree.openElements()->popUntilPopped(token->name());
+ m_tree.activeFormattingElements()->clearToLastMarker();
return;
}
- if (token.name() == brTag) {
+ if (token->name() == brTag) {
parseError(token);
processFakeStartTag(brTag);
return;
}
#if ENABLE(TEMPLATE_ELEMENT)
- if (token.name() == templateTag) {
+ if (token->name() == templateTag) {
processTemplateEndTag(token);
return;
}
@@ -1915,58 +1960,58 @@ void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken& token)
bool HTMLTreeBuilder::processCaptionEndTagForInCaption()
{
- if (!m_tree.openElements().inTableScope(captionTag.localName())) {
+ if (!m_tree.openElements()->inTableScope(captionTag.localName())) {
ASSERT(isParsingFragment());
// FIXME: parse error
return false;
}
m_tree.generateImpliedEndTags();
- // FIXME: parse error if (!m_tree.currentStackItem().hasTagName(captionTag))
- m_tree.openElements().popUntilPopped(captionTag.localName());
- m_tree.activeFormattingElements().clearToLastMarker();
- m_insertionMode = InsertionMode::InTable;
+ // FIXME: parse error if (!m_tree.currentStackItem()->hasTagName(captionTag))
+ m_tree.openElements()->popUntilPopped(captionTag.localName());
+ m_tree.activeFormattingElements()->clearToLastMarker();
+ setInsertionMode(InsertionMode::InTable);
return true;
}
bool HTMLTreeBuilder::processTrEndTagForInRow()
{
- if (!m_tree.openElements().inTableScope(trTag)) {
+ if (!m_tree.openElements()->inTableScope(trTag)) {
ASSERT(isParsingFragmentOrTemplateContents());
// FIXME: parse error
return false;
}
- m_tree.openElements().popUntilTableRowScopeMarker();
- ASSERT(m_tree.currentStackItem().hasTagName(trTag));
- m_tree.openElements().pop();
- m_insertionMode = InsertionMode::InTableBody;
+ m_tree.openElements()->popUntilTableRowScopeMarker();
+ ASSERT(m_tree.currentStackItem()->hasTagName(trTag));
+ m_tree.openElements()->pop();
+ setInsertionMode(InsertionMode::InTableBody);
return true;
}
bool HTMLTreeBuilder::processTableEndTagForInTable()
{
- if (!m_tree.openElements().inTableScope(tableTag)) {
+ if (!m_tree.openElements()->inTableScope(tableTag)) {
ASSERT(isParsingFragmentOrTemplateContents());
// FIXME: parse error.
return false;
}
- m_tree.openElements().popUntilPopped(tableTag.localName());
+ m_tree.openElements()->popUntilPopped(tableTag.localName());
resetInsertionModeAppropriately();
return true;
}
-void HTMLTreeBuilder::processEndTagForInTable(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processEndTagForInTable(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::EndTag);
- if (token.name() == tableTag) {
+ ASSERT(token->type() == HTMLToken::EndTag);
+ if (token->name() == tableTag) {
processTableEndTagForInTable();
return;
}
- if (token.name() == bodyTag
- || isCaptionColOrColgroupTag(token.name())
- || token.name() == htmlTag
- || isTableBodyContextTag(token.name())
- || isTableCellContextTag(token.name())
- || token.name() == trTag) {
+ if (token->name() == bodyTag
+ || isCaptionColOrColgroupTag(token->name())
+ || token->name() == htmlTag
+ || isTableBodyContextTag(token->name())
+ || isTableCellContextTag(token->name())
+ || token->name() == trTag) {
parseError(token);
return;
}
@@ -1976,72 +2021,75 @@ void HTMLTreeBuilder::processEndTagForInTable(AtomicHTMLToken& token)
processEndTagForInBody(token);
}
-void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::EndTag);
- switch (m_insertionMode) {
+ ASSERT(token->type() == HTMLToken::EndTag);
+ switch (insertionMode()) {
case InsertionMode::Initial:
+ ASSERT(insertionMode() == InsertionMode::Initial);
defaultForInitial();
- ASSERT(m_insertionMode == InsertionMode::BeforeHTML);
FALLTHROUGH;
case InsertionMode::BeforeHTML:
- if (token.name() != headTag && token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
+ ASSERT(insertionMode() == InsertionMode::BeforeHTML);
+ if (token->name() != headTag && token->name() != bodyTag && token->name() != htmlTag && token->name() != brTag) {
parseError(token);
return;
}
defaultForBeforeHTML();
- ASSERT(m_insertionMode == InsertionMode::BeforeHead);
FALLTHROUGH;
case InsertionMode::BeforeHead:
- if (token.name() != headTag && token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
+ ASSERT(insertionMode() == InsertionMode::BeforeHead);
+ if (token->name() != headTag && token->name() != bodyTag && token->name() != htmlTag && token->name() != brTag) {
parseError(token);
return;
}
defaultForBeforeHead();
- ASSERT(m_insertionMode == InsertionMode::InHead);
FALLTHROUGH;
case InsertionMode::InHead:
+ ASSERT(insertionMode() == InsertionMode::InHead);
// FIXME: This case should be broken out into processEndTagForInHead,
// because other end tag cases now refer to it ("process the token for using the rules of the "in head" insertion mode").
// but because the logic falls through to InsertionMode::AfterHead, that gets a little messy.
#if ENABLE(TEMPLATE_ELEMENT)
- if (token.name() == templateTag) {
+ if (token->name() == templateTag) {
processTemplateEndTag(token);
return;
}
#endif
- if (token.name() == headTag) {
- m_tree.openElements().popHTMLHeadElement();
- m_insertionMode = InsertionMode::AfterHead;
+ if (token->name() == headTag) {
+ m_tree.openElements()->popHTMLHeadElement();
+ setInsertionMode(InsertionMode::AfterHead);
return;
}
- if (token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
+ if (token->name() != bodyTag && token->name() != htmlTag && token->name() != brTag) {
parseError(token);
return;
}
defaultForInHead();
- ASSERT(m_insertionMode == InsertionMode::AfterHead);
FALLTHROUGH;
case InsertionMode::AfterHead:
- if (token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
+ ASSERT(insertionMode() == InsertionMode::AfterHead);
+ if (token->name() != bodyTag && token->name() != htmlTag && token->name() != brTag) {
parseError(token);
return;
}
defaultForAfterHead();
- ASSERT(m_insertionMode == InsertionMode::InBody);
FALLTHROUGH;
case InsertionMode::InBody:
+ ASSERT(insertionMode() == InsertionMode::InBody);
processEndTagForInBody(token);
break;
case InsertionMode::InTable:
+ ASSERT(insertionMode() == InsertionMode::InTable);
processEndTagForInTable(token);
break;
case InsertionMode::InCaption:
- if (token.name() == captionTag) {
+ ASSERT(insertionMode() == InsertionMode::InCaption);
+ if (token->name() == captionTag) {
processCaptionEndTagForInCaption();
return;
}
- if (token.name() == tableTag) {
+ if (token->name() == tableTag) {
parseError(token);
if (!processCaptionEndTagForInCaption()) {
ASSERT(isParsingFragment());
@@ -2050,29 +2098,30 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
processEndTag(token);
return;
}
- if (token.name() == bodyTag
- || token.name() == colTag
- || token.name() == colgroupTag
- || token.name() == htmlTag
- || isTableBodyContextTag(token.name())
- || isTableCellContextTag(token.name())
- || token.name() == trTag) {
+ if (token->name() == bodyTag
+ || token->name() == colTag
+ || token->name() == colgroupTag
+ || token->name() == htmlTag
+ || isTableBodyContextTag(token->name())
+ || isTableCellContextTag(token->name())
+ || token->name() == trTag) {
parseError(token);
return;
}
processEndTagForInBody(token);
break;
case InsertionMode::InColumnGroup:
- if (token.name() == colgroupTag) {
+ ASSERT(insertionMode() == InsertionMode::InColumnGroup);
+ if (token->name() == colgroupTag) {
processColgroupEndTagForInColumnGroup();
return;
}
- if (token.name() == colTag) {
+ if (token->name() == colTag) {
parseError(token);
return;
}
#if ENABLE(TEMPLATE_ELEMENT)
- if (token.name() == templateTag) {
+ if (token->name() == templateTag) {
processTemplateEndTag(token);
return;
}
@@ -2084,39 +2133,44 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
processEndTag(token);
break;
case InsertionMode::InRow:
+ ASSERT(insertionMode() == InsertionMode::InRow);
processEndTagForInRow(token);
break;
case InsertionMode::InCell:
+ ASSERT(insertionMode() == InsertionMode::InCell);
processEndTagForInCell(token);
break;
case InsertionMode::InTableBody:
+ ASSERT(insertionMode() == InsertionMode::InTableBody);
processEndTagForInTableBody(token);
break;
case InsertionMode::AfterBody:
- if (token.name() == htmlTag) {
+ ASSERT(insertionMode() == InsertionMode::AfterBody);
+ if (token->name() == htmlTag) {
if (isParsingFragment()) {
parseError(token);
return;
}
- m_insertionMode = InsertionMode::AfterAfterBody;
+ setInsertionMode(InsertionMode::AfterAfterBody);
return;
}
FALLTHROUGH;
case InsertionMode::AfterAfterBody:
- ASSERT(m_insertionMode == InsertionMode::AfterBody || m_insertionMode == InsertionMode::AfterAfterBody);
+ ASSERT(insertionMode() == InsertionMode::AfterBody || insertionMode() == InsertionMode::AfterAfterBody);
parseError(token);
- m_insertionMode = InsertionMode::InBody;
+ setInsertionMode(InsertionMode::InBody);
processEndTag(token);
break;
case InsertionMode::InHeadNoscript:
- if (token.name() == noscriptTag) {
- ASSERT(m_tree.currentStackItem().hasTagName(noscriptTag));
- m_tree.openElements().pop();
- ASSERT(m_tree.currentStackItem().hasTagName(headTag));
- m_insertionMode = InsertionMode::InHead;
+ ASSERT(insertionMode() == InsertionMode::InHeadNoscript);
+ if (token->name() == noscriptTag) {
+ ASSERT(m_tree.currentStackItem()->hasTagName(noscriptTag));
+ m_tree.openElements()->pop();
+ ASSERT(m_tree.currentStackItem()->hasTagName(headTag));
+ setInsertionMode(InsertionMode::InHead);
return;
}
- if (token.name() != brTag) {
+ if (token->name() != brTag) {
parseError(token);
return;
}
@@ -2124,105 +2178,110 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
processToken(token);
break;
case InsertionMode::Text:
- if (token.name() == scriptTag) {
+ if (token->name() == scriptTag) {
// Pause ourselves so that parsing stops until the script can be processed by the caller.
- ASSERT(m_tree.currentStackItem().hasTagName(scriptTag));
+ ASSERT(m_tree.currentStackItem()->hasTagName(scriptTag));
if (scriptingContentIsAllowed(m_tree.parserContentPolicy()))
- m_scriptToProcess = &m_tree.currentElement();
- m_tree.openElements().pop();
- m_insertionMode = m_originalInsertionMode;
-
- // This token will not have been created by the tokenizer if a
- // self-closing script tag was encountered and pre-HTML5 parser
- // quirks are enabled. We must set the tokenizer's state to
- // DataState explicitly if the tokenizer didn't have a chance to.
- ASSERT(m_parser.tokenizer().isInDataState() || m_options.usePreHTML5ParserQuirks);
- m_parser.tokenizer().setDataState();
+ m_scriptToProcess = m_tree.currentElement();
+ m_tree.openElements()->pop();
+ setInsertionMode(m_originalInsertionMode);
+
+ if (m_parser.tokenizer()) {
+ // This token will not have been created by the tokenizer if a
+ // self-closing script tag was encountered and pre-HTML5 parser
+ // quirks are enabled. We must set the tokenizer's state to
+ // DataState explicitly if the tokenizer didn't have a chance to.
+ ASSERT(m_parser.tokenizer()->state() == HTMLTokenizer::DataState || m_options.usePreHTML5ParserQuirks);
+ m_parser.tokenizer()->setState(HTMLTokenizer::DataState);
+ }
return;
}
- m_tree.openElements().pop();
- m_insertionMode = m_originalInsertionMode;
+ m_tree.openElements()->pop();
+ setInsertionMode(m_originalInsertionMode);
break;
case InsertionMode::InFrameset:
- if (token.name() == framesetTag) {
+ ASSERT(insertionMode() == InsertionMode::InFrameset);
+ if (token->name() == framesetTag) {
bool ignoreFramesetForFragmentParsing = m_tree.currentIsRootNode();
#if ENABLE(TEMPLATE_ELEMENT)
- ignoreFramesetForFragmentParsing = ignoreFramesetForFragmentParsing || m_tree.openElements().hasTemplateInHTMLScope();
+ ignoreFramesetForFragmentParsing = ignoreFramesetForFragmentParsing || m_tree.openElements()->hasTemplateInHTMLScope();
#endif
if (ignoreFramesetForFragmentParsing) {
ASSERT(isParsingFragmentOrTemplateContents());
parseError(token);
return;
}
- m_tree.openElements().pop();
- if (!isParsingFragment() && !m_tree.currentStackItem().hasTagName(framesetTag))
- m_insertionMode = InsertionMode::AfterFrameset;
+ m_tree.openElements()->pop();
+ if (!isParsingFragment() && !m_tree.currentStackItem()->hasTagName(framesetTag))
+ setInsertionMode(InsertionMode::AfterFrameset);
return;
}
#if ENABLE(TEMPLATE_ELEMENT)
- if (token.name() == templateTag) {
+ if (token->name() == templateTag) {
processTemplateEndTag(token);
return;
}
#endif
break;
case InsertionMode::AfterFrameset:
- if (token.name() == htmlTag) {
- m_insertionMode = InsertionMode::AfterAfterFrameset;
+ ASSERT(insertionMode() == InsertionMode::AfterFrameset);
+ if (token->name() == htmlTag) {
+ setInsertionMode(InsertionMode::AfterAfterFrameset);
return;
}
FALLTHROUGH;
case InsertionMode::AfterAfterFrameset:
- ASSERT(m_insertionMode == InsertionMode::AfterFrameset || m_insertionMode == InsertionMode::AfterAfterFrameset);
+ ASSERT(insertionMode() == InsertionMode::AfterFrameset || insertionMode() == InsertionMode::AfterAfterFrameset);
parseError(token);
break;
case InsertionMode::InSelectInTable:
- if (token.name() == captionTag
- || token.name() == tableTag
- || isTableBodyContextTag(token.name())
- || token.name() == trTag
- || isTableCellContextTag(token.name())) {
+ ASSERT(insertionMode() == InsertionMode::InSelectInTable);
+ if (token->name() == captionTag
+ || token->name() == tableTag
+ || isTableBodyContextTag(token->name())
+ || token->name() == trTag
+ || isTableCellContextTag(token->name())) {
parseError(token);
- if (m_tree.openElements().inTableScope(token.name())) {
+ if (m_tree.openElements()->inTableScope(token->name())) {
AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
- processEndTag(endSelect);
+ processEndTag(&endSelect);
processEndTag(token);
}
return;
}
FALLTHROUGH;
case InsertionMode::InSelect:
- ASSERT(m_insertionMode == InsertionMode::InSelect || m_insertionMode == InsertionMode::InSelectInTable);
- if (token.name() == optgroupTag) {
- if (is<HTMLOptionElement>(m_tree.currentStackItem().node()) && m_tree.oneBelowTop() && is<HTMLOptGroupElement>(m_tree.oneBelowTop()->node()))
+ ASSERT(insertionMode() == InsertionMode::InSelect || insertionMode() == InsertionMode::InSelectInTable);
+ if (token->name() == optgroupTag) {
+ if (isHTMLOptionElement(m_tree.currentStackItem()->node()) && m_tree.oneBelowTop() && isHTMLOptGroupElement(m_tree.oneBelowTop()->node()))
processFakeEndTag(optionTag);
- if (is<HTMLOptGroupElement>(m_tree.currentStackItem().node())) {
- m_tree.openElements().pop();
+ if (isHTMLOptGroupElement(m_tree.currentStackItem()->node())) {
+ m_tree.openElements()->pop();
return;
}
parseError(token);
return;
}
- if (token.name() == optionTag) {
- if (is<HTMLOptionElement>(m_tree.currentStackItem().node())) {
- m_tree.openElements().pop();
+ if (token->name() == optionTag) {
+ if (isHTMLOptionElement(m_tree.currentStackItem()->node())) {
+ m_tree.openElements()->pop();
return;
}
parseError(token);
return;
}
- if (token.name() == selectTag) {
- if (!m_tree.openElements().inSelectScope(token.name())) {
+ if (token->name() == selectTag) {
+ if (!m_tree.openElements()->inSelectScope(token->name())) {
ASSERT(isParsingFragment());
parseError(token);
return;
}
- m_tree.openElements().popUntilPopped(selectTag.localName());
+ m_tree.openElements()->popUntilPopped(selectTag.localName());
resetInsertionModeAppropriately();
return;
}
#if ENABLE(TEMPLATE_ELEMENT)
- if (token.name() == templateTag) {
+ if (token->name() == templateTag) {
processTemplateEndTag(token);
return;
}
@@ -2232,29 +2291,33 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
defaultForInTableText();
processEndTag(token);
break;
-#if ENABLE(TEMPLATE_ELEMENT)
case InsertionMode::TemplateContents:
- if (token.name() == templateTag) {
+#if ENABLE(TEMPLATE_ELEMENT)
+ if (token->name() == templateTag) {
processTemplateEndTag(token);
return;
}
+
break;
+#else
+ ASSERT_NOT_REACHED();
#endif
+ break;
}
}
-void HTMLTreeBuilder::processComment(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processComment(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::Comment);
+ ASSERT(token->type() == HTMLToken::Comment);
if (m_insertionMode == InsertionMode::Initial
|| m_insertionMode == InsertionMode::BeforeHTML
|| m_insertionMode == InsertionMode::AfterAfterBody
|| m_insertionMode == InsertionMode::AfterAfterFrameset) {
- m_tree.insertCommentOnDocument(&token);
+ m_tree.insertCommentOnDocument(token);
return;
}
if (m_insertionMode == InsertionMode::AfterBody) {
- m_tree.insertCommentOnHTMLHtmlElement(&token);
+ m_tree.insertCommentOnHTMLHtmlElement(token);
return;
}
if (m_insertionMode == InsertionMode::InTableText) {
@@ -2262,19 +2325,18 @@ void HTMLTreeBuilder::processComment(AtomicHTMLToken& token)
processComment(token);
return;
}
- m_tree.insertComment(&token);
+ m_tree.insertComment(token);
}
-void HTMLTreeBuilder::processCharacter(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processCharacter(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::Character);
+ ASSERT(token->type() == HTMLToken::Character);
ExternalCharacterTokenBuffer buffer(token);
processCharacterBuffer(buffer);
}
-#if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(IOS)
-
// FIXME: Extract the following iOS-specific code into a separate file.
+#if PLATFORM(IOS)
// From the string 4089961010, creates a link of the form <a href="tel:4089961010">4089961010</a> and inserts it.
void HTMLTreeBuilder::insertPhoneNumberLink(const String& string)
{
@@ -2282,13 +2344,13 @@ void HTMLTreeBuilder::insertPhoneNumberLink(const String& string)
attributes.append(Attribute(HTMLNames::hrefAttr, ASCIILiteral("tel:") + string));
const AtomicString& aTagLocalName = aTag.localName();
- AtomicHTMLToken aStartToken(HTMLToken::StartTag, aTagLocalName, WTF::move(attributes));
+ AtomicHTMLToken aStartToken(HTMLToken::StartTag, aTagLocalName, attributes);
AtomicHTMLToken aEndToken(HTMLToken::EndTag, aTagLocalName);
- processStartTag(aStartToken);
+ processStartTag(&aStartToken);
m_tree.executeQueuedTasks();
m_tree.insertTextNode(string);
- processEndTag(aEndToken);
+ processEndTag(&aEndToken);
}
// Locates the phone numbers in the string and deals with it
@@ -2298,7 +2360,13 @@ void HTMLTreeBuilder::insertPhoneNumberLink(const String& string)
// 4. Appends the rest of the string as a text node.
void HTMLTreeBuilder::linkifyPhoneNumbers(const String& string)
{
- ASSERT(TelephoneNumberDetector::isSupported());
+ static DDDFACacheRef phoneNumbersCache = DDDFACacheCreateFromFramework();
+ if (!phoneNumbersCache) {
+ m_tree.insertTextNode(string);
+ return;
+ }
+
+ static DDDFAScannerRef phoneNumbersScanner = DDDFAScannerCreateFromCache(phoneNumbersCache);
// relativeStartPosition and relativeEndPosition are the endpoints of the phone number range,
// relative to the scannerPosition
@@ -2307,10 +2375,8 @@ void HTMLTreeBuilder::linkifyPhoneNumbers(const String& string)
int relativeStartPosition = 0;
int relativeEndPosition = 0;
- auto characters = StringView(string).upconvertedCharacters();
-
// While there's a phone number in the rest of the string...
- while (scannerPosition < length && TelephoneNumberDetector::find(&characters[scannerPosition], length - scannerPosition, &relativeStartPosition, &relativeEndPosition)) {
+ while ((scannerPosition < length) && DDDFAScannerFirstResultInUnicharArray(phoneNumbersScanner, &string.characters()[scannerPosition], length - scannerPosition, &relativeStartPosition, &relativeEndPosition)) {
// The convention in the Data Detectors framework is that the end position is the first character NOT in the phone number
// (that is, the length of the range is relativeEndPosition - relativeStartPosition). So substract 1 to get the same
// convention as the old WebCore phone number parser (so that the rest of the code is still valid if we want to go back
@@ -2336,11 +2402,12 @@ void HTMLTreeBuilder::linkifyPhoneNumbers(const String& string)
}
// Looks at the ancestors of the element to determine whether we're inside an element which disallows parsing phone numbers.
-static inline bool disallowTelephoneNumberParsing(const ContainerNode& node)
+static inline bool disallowTelephoneNumberParsing(const Node& node)
{
return node.isLink()
+ || node.nodeType() == Node::COMMENT_NODE
|| node.hasTagName(scriptTag)
- || is<HTMLFormControlElement>(node)
+ || (node.isHTMLElement() && toHTMLElement(node).isFormControlElement())
|| node.hasTagName(styleTag)
|| node.hasTagName(ttTag)
|| node.hasTagName(preTag)
@@ -2349,14 +2416,15 @@ static inline bool disallowTelephoneNumberParsing(const ContainerNode& node)
static inline bool shouldParseTelephoneNumbersInNode(const ContainerNode& node)
{
- for (const ContainerNode* ancestor = &node; ancestor; ancestor = ancestor->parentNode()) {
- if (disallowTelephoneNumberParsing(*ancestor))
+ const ContainerNode* currentNode = &node;
+ do {
+ if (currentNode->isElementNode() && disallowTelephoneNumberParsing(*currentNode))
return false;
- }
+ currentNode = currentNode->parentNode();
+ } while (currentNode);
return true;
}
-
-#endif // ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(IOS)
+#endif // PLATFORM(IOS)
void HTMLTreeBuilder::processCharacterBuffer(ExternalCharacterTokenBuffer& buffer)
{
@@ -2379,68 +2447,77 @@ ReprocessBuffer:
return;
}
- switch (m_insertionMode) {
- case InsertionMode::Initial:
+ switch (insertionMode()) {
+ case InsertionMode::Initial: {
+ ASSERT(insertionMode() == InsertionMode::Initial);
buffer.skipLeadingWhitespace();
if (buffer.isEmpty())
return;
defaultForInitial();
- ASSERT(m_insertionMode == InsertionMode::BeforeHTML);
FALLTHROUGH;
- case InsertionMode::BeforeHTML:
+ }
+ case InsertionMode::BeforeHTML: {
+ ASSERT(insertionMode() == InsertionMode::BeforeHTML);
buffer.skipLeadingWhitespace();
if (buffer.isEmpty())
return;
defaultForBeforeHTML();
- ASSERT(m_insertionMode == InsertionMode::BeforeHead);
FALLTHROUGH;
- case InsertionMode::BeforeHead:
+ }
+ case InsertionMode::BeforeHead: {
+ ASSERT(insertionMode() == InsertionMode::BeforeHead);
buffer.skipLeadingWhitespace();
if (buffer.isEmpty())
return;
defaultForBeforeHead();
- ASSERT(m_insertionMode == InsertionMode::InHead);
FALLTHROUGH;
+ }
case InsertionMode::InHead: {
+ ASSERT(insertionMode() == InsertionMode::InHead);
String leadingWhitespace = buffer.takeLeadingWhitespace();
if (!leadingWhitespace.isEmpty())
m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
if (buffer.isEmpty())
return;
defaultForInHead();
- ASSERT(m_insertionMode == InsertionMode::AfterHead);
FALLTHROUGH;
}
case InsertionMode::AfterHead: {
+ ASSERT(insertionMode() == InsertionMode::AfterHead);
String leadingWhitespace = buffer.takeLeadingWhitespace();
if (!leadingWhitespace.isEmpty())
m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
if (buffer.isEmpty())
return;
defaultForAfterHead();
- ASSERT(m_insertionMode == InsertionMode::InBody);
FALLTHROUGH;
}
case InsertionMode::InBody:
case InsertionMode::InCaption:
- case InsertionMode::InCell:
-#if ENABLE(TEMPLATE_ELEMENT)
case InsertionMode::TemplateContents:
+ case InsertionMode::InCell: {
+#if ENABLE(TEMPLATE_ELEMENT)
+ ASSERT(insertionMode() == InsertionMode::InBody || insertionMode() == InsertionMode::InCaption || insertionMode() == InsertionMode::InCell || insertionMode() == InsertionMode::TemplateContents);
+#else
+ ASSERT(insertionMode() != InsertionMode::TemplateContents);
+ ASSERT(insertionMode() == InsertionMode::InBody || insertionMode() == InsertionMode::InCaption || insertionMode() == InsertionMode::InCell);
#endif
processCharacterBufferForInBody(buffer);
break;
+ }
case InsertionMode::InTable:
case InsertionMode::InTableBody:
- case InsertionMode::InRow:
+ case InsertionMode::InRow: {
+ ASSERT(insertionMode() == InsertionMode::InTable || insertionMode() == InsertionMode::InTableBody || insertionMode() == InsertionMode::InRow);
ASSERT(m_pendingTableCharacters.isEmpty());
- if (is<HTMLTableElement>(m_tree.currentStackItem().node())
- || m_tree.currentStackItem().hasTagName(HTMLNames::tbodyTag)
- || m_tree.currentStackItem().hasTagName(HTMLNames::tfootTag)
- || m_tree.currentStackItem().hasTagName(HTMLNames::theadTag)
- || m_tree.currentStackItem().hasTagName(HTMLNames::trTag)) {
-
+ if (m_tree.currentStackItem()->isElementNode()
+ && (isHTMLTableElement(m_tree.currentStackItem()->node())
+ || m_tree.currentStackItem()->hasTagName(HTMLNames::tbodyTag)
+ || m_tree.currentStackItem()->hasTagName(HTMLNames::tfootTag)
+ || m_tree.currentStackItem()->hasTagName(HTMLNames::theadTag)
+ || m_tree.currentStackItem()->hasTagName(HTMLNames::trTag))) {
m_originalInsertionMode = m_insertionMode;
- m_insertionMode = InsertionMode::InTableText;
+ setInsertionMode(InsertionMode::InTableText);
// Note that we fall through to the InsertionMode::InTableText case below.
} else {
HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree);
@@ -2448,10 +2525,13 @@ ReprocessBuffer:
break;
}
FALLTHROUGH;
- case InsertionMode::InTableText:
+ }
+ case InsertionMode::InTableText: {
buffer.giveRemainingTo(m_pendingTableCharacters);
break;
+ }
case InsertionMode::InColumnGroup: {
+ ASSERT(insertionMode() == InsertionMode::InColumnGroup);
String leadingWhitespace = buffer.takeLeadingWhitespace();
if (!leadingWhitespace.isEmpty())
m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
@@ -2467,14 +2547,20 @@ ReprocessBuffer:
goto ReprocessBuffer;
}
case InsertionMode::AfterBody:
- case InsertionMode::AfterAfterBody:
+ case InsertionMode::AfterAfterBody: {
+ ASSERT(insertionMode() == InsertionMode::AfterBody || insertionMode() == InsertionMode::AfterAfterBody);
// FIXME: parse error
- m_insertionMode = InsertionMode::InBody;
+ setInsertionMode(InsertionMode::InBody);
goto ReprocessBuffer;
- case InsertionMode::Text:
+ break;
+ }
+ case InsertionMode::Text: {
+ ASSERT(insertionMode() == InsertionMode::Text);
m_tree.insertTextNode(buffer.takeRemaining());
break;
+ }
case InsertionMode::InHeadNoscript: {
+ ASSERT(insertionMode() == InsertionMode::InHeadNoscript);
String leadingWhitespace = buffer.takeLeadingWhitespace();
if (!leadingWhitespace.isEmpty())
m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
@@ -2482,9 +2568,11 @@ ReprocessBuffer:
return;
defaultForInHeadNoscript();
goto ReprocessBuffer;
+ break;
}
case InsertionMode::InFrameset:
case InsertionMode::AfterFrameset: {
+ ASSERT(insertionMode() == InsertionMode::InFrameset || insertionMode() == InsertionMode::AfterFrameset || insertionMode() == InsertionMode::AfterAfterFrameset);
String leadingWhitespace = buffer.takeRemainingWhitespace();
if (!leadingWhitespace.isEmpty())
m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
@@ -2493,9 +2581,11 @@ ReprocessBuffer:
break;
}
case InsertionMode::InSelectInTable:
- case InsertionMode::InSelect:
+ case InsertionMode::InSelect: {
+ ASSERT(insertionMode() == InsertionMode::InSelect || insertionMode() == InsertionMode::InSelectInTable);
m_tree.insertTextNode(buffer.takeRemaining());
break;
+ }
case InsertionMode::AfterAfterFrameset: {
String leadingWhitespace = buffer.takeRemainingWhitespace();
if (!leadingWhitespace.isEmpty()) {
@@ -2513,63 +2603,72 @@ void HTMLTreeBuilder::processCharacterBufferForInBody(ExternalCharacterTokenBuff
{
m_tree.reconstructTheActiveFormattingElements();
String characters = buffer.takeRemaining();
-#if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(IOS)
- if (!isParsingFragment() && m_tree.isTelephoneNumberParsingEnabled() && shouldParseTelephoneNumbersInNode(m_tree.currentNode()) && TelephoneNumberDetector::isSupported())
+#if PLATFORM(IOS)
+ if (!isParsingFragment() && m_tree.isTelephoneNumberParsingEnabled() && shouldParseTelephoneNumbersInNode(*m_tree.currentNode()) && DataDetectorsCoreLibrary())
linkifyPhoneNumbers(characters);
else
m_tree.insertTextNode(characters);
#else
m_tree.insertTextNode(characters);
#endif
+
if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters))
m_framesetOk = false;
}
-void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::EndOfFile);
- switch (m_insertionMode) {
+ ASSERT(token->type() == HTMLToken::EndOfFile);
+ switch (insertionMode()) {
case InsertionMode::Initial:
+ ASSERT(insertionMode() == InsertionMode::Initial);
defaultForInitial();
- ASSERT(m_insertionMode == InsertionMode::BeforeHTML);
FALLTHROUGH;
case InsertionMode::BeforeHTML:
+ ASSERT(insertionMode() == InsertionMode::BeforeHTML);
defaultForBeforeHTML();
- ASSERT(m_insertionMode == InsertionMode::BeforeHead);
FALLTHROUGH;
case InsertionMode::BeforeHead:
+ ASSERT(insertionMode() == InsertionMode::BeforeHead);
defaultForBeforeHead();
- ASSERT(m_insertionMode == InsertionMode::InHead);
FALLTHROUGH;
case InsertionMode::InHead:
+ ASSERT(insertionMode() == InsertionMode::InHead);
defaultForInHead();
- ASSERT(m_insertionMode == InsertionMode::AfterHead);
FALLTHROUGH;
case InsertionMode::AfterHead:
+ ASSERT(insertionMode() == InsertionMode::AfterHead);
defaultForAfterHead();
- ASSERT(m_insertionMode == InsertionMode::InBody);
FALLTHROUGH;
case InsertionMode::InBody:
case InsertionMode::InCell:
case InsertionMode::InCaption:
case InsertionMode::InRow:
+#if ENABLE(TEMPLATE_ELEMENT)
+ ASSERT(insertionMode() == InsertionMode::InBody || insertionMode() == InsertionMode::InCell || insertionMode() == InsertionMode::InCaption || insertionMode() == InsertionMode::InRow || insertionMode() == InsertionMode::TemplateContents);
+#else
+ ASSERT(insertionMode() != InsertionMode::TemplateContents);
+ ASSERT(insertionMode() == InsertionMode::InBody || insertionMode() == InsertionMode::InCell || insertionMode() == InsertionMode::InCaption || insertionMode() == InsertionMode::InRow);
+#endif
notImplemented(); // Emit parse error based on what elements are still open.
#if ENABLE(TEMPLATE_ELEMENT)
- if (!m_templateInsertionModes.isEmpty()) {
+ if (!m_templateInsertionModes.isEmpty())
if (processEndOfFileForInTemplateContents(token))
return;
- }
#endif
break;
case InsertionMode::AfterBody:
case InsertionMode::AfterAfterBody:
+ ASSERT(insertionMode() == InsertionMode::AfterBody || insertionMode() == InsertionMode::AfterAfterBody);
break;
case InsertionMode::InHeadNoscript:
+ ASSERT(insertionMode() == InsertionMode::InHeadNoscript);
defaultForInHeadNoscript();
processEndOfFile(token);
return;
case InsertionMode::AfterFrameset:
case InsertionMode::AfterAfterFrameset:
+ ASSERT(insertionMode() == InsertionMode::AfterFrameset || insertionMode() == InsertionMode::AfterAfterFrameset);
break;
case InsertionMode::InColumnGroup:
if (m_tree.currentIsRootNode()) {
@@ -2577,9 +2676,9 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
return; // FIXME: Should we break here instead of returning?
}
#if ENABLE(TEMPLATE_ELEMENT)
- ASSERT(m_tree.currentNode().hasTagName(colgroupTag) || m_tree.currentNode().hasTagName(templateTag));
+ ASSERT(m_tree.currentNode()->hasTagName(colgroupTag) || m_tree.currentNode()->hasTagName(templateTag));
#else
- ASSERT(m_tree.currentNode().hasTagName(colgroupTag));
+ ASSERT(m_tree.currentNode()->hasTagName(colgroupTag));
#endif
processColgroupEndTagForInColumnGroup();
FALLTHROUGH;
@@ -2588,14 +2687,14 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
case InsertionMode::InTableBody:
case InsertionMode::InSelectInTable:
case InsertionMode::InSelect:
- ASSERT(m_insertionMode == InsertionMode::InSelect || m_insertionMode == InsertionMode::InSelectInTable || m_insertionMode == InsertionMode::InTable || m_insertionMode == InsertionMode::InFrameset || m_insertionMode == InsertionMode::InTableBody || m_insertionMode == InsertionMode::InColumnGroup);
- if (&m_tree.currentNode() != &m_tree.openElements().rootNode())
+ ASSERT(insertionMode() == InsertionMode::InSelect || insertionMode() == InsertionMode::InSelectInTable || insertionMode() == InsertionMode::InTable || insertionMode() == InsertionMode::InFrameset || insertionMode() == InsertionMode::InTableBody || insertionMode() == InsertionMode::InColumnGroup);
+ if (m_tree.currentNode() != m_tree.openElements()->rootNode())
parseError(token);
+
#if ENABLE(TEMPLATE_ELEMENT)
- if (!m_templateInsertionModes.isEmpty()) {
+ if (!m_templateInsertionModes.isEmpty())
if (processEndOfFileForInTemplateContents(token))
return;
- }
#endif
break;
case InsertionMode::InTableText:
@@ -2604,21 +2703,24 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
return;
case InsertionMode::Text:
parseError(token);
- if (m_tree.currentStackItem().hasTagName(scriptTag))
+ if (m_tree.currentStackItem()->hasTagName(scriptTag))
notImplemented(); // mark the script element as "already started".
- m_tree.openElements().pop();
+ m_tree.openElements()->pop();
ASSERT(m_originalInsertionMode != InsertionMode::Text);
- m_insertionMode = m_originalInsertionMode;
+ setInsertionMode(m_originalInsertionMode);
processEndOfFile(token);
return;
-#if ENABLE(TEMPLATE_ELEMENT)
case InsertionMode::TemplateContents:
+#if ENABLE(TEMPLATE_ELEMENT)
if (processEndOfFileForInTemplateContents(token))
return;
break;
+#else
+ ASSERT_NOT_REACHED();
#endif
}
- m_tree.openElements().popAll();
+ ASSERT(m_tree.currentNode());
+ m_tree.openElements()->popAll();
}
void HTMLTreeBuilder::defaultForInitial()
@@ -2626,38 +2728,38 @@ void HTMLTreeBuilder::defaultForInitial()
notImplemented();
m_tree.setDefaultCompatibilityMode();
// FIXME: parse error
- m_insertionMode = InsertionMode::BeforeHTML;
+ setInsertionMode(InsertionMode::BeforeHTML);
}
void HTMLTreeBuilder::defaultForBeforeHTML()
{
AtomicHTMLToken startHTML(HTMLToken::StartTag, htmlTag.localName());
m_tree.insertHTMLHtmlStartTagBeforeHTML(&startHTML);
- m_insertionMode = InsertionMode::BeforeHead;
+ setInsertionMode(InsertionMode::BeforeHead);
}
void HTMLTreeBuilder::defaultForBeforeHead()
{
AtomicHTMLToken startHead(HTMLToken::StartTag, headTag.localName());
- processStartTag(startHead);
+ processStartTag(&startHead);
}
void HTMLTreeBuilder::defaultForInHead()
{
AtomicHTMLToken endHead(HTMLToken::EndTag, headTag.localName());
- processEndTag(endHead);
+ processEndTag(&endHead);
}
void HTMLTreeBuilder::defaultForInHeadNoscript()
{
AtomicHTMLToken endNoscript(HTMLToken::EndTag, noscriptTag.localName());
- processEndTag(endNoscript);
+ processEndTag(&endNoscript);
}
void HTMLTreeBuilder::defaultForAfterHead()
{
AtomicHTMLToken startBody(HTMLToken::StartTag, bodyTag.localName());
- processStartTag(startBody);
+ processStartTag(&startBody);
m_framesetOk = true;
}
@@ -2671,149 +2773,135 @@ void HTMLTreeBuilder::defaultForInTableText()
m_tree.reconstructTheActiveFormattingElements();
m_tree.insertTextNode(characters, NotAllWhitespace);
m_framesetOk = false;
- m_insertionMode = m_originalInsertionMode;
+ setInsertionMode(m_originalInsertionMode);
return;
}
m_tree.insertTextNode(characters);
- m_insertionMode = m_originalInsertionMode;
+ setInsertionMode(m_originalInsertionMode);
}
-bool HTMLTreeBuilder::processStartTagForInHead(AtomicHTMLToken& token)
+bool HTMLTreeBuilder::processStartTagForInHead(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::StartTag);
- if (token.name() == htmlTag) {
+ ASSERT(token->type() == HTMLToken::StartTag);
+ if (token->name() == htmlTag) {
processHtmlStartTagForInBody(token);
return true;
}
- if (token.name() == baseTag
- || token.name() == basefontTag
- || token.name() == bgsoundTag
- || token.name() == commandTag
- || token.name() == linkTag
- || token.name() == metaTag) {
- m_tree.insertSelfClosingHTMLElement(&token);
+ if (token->name() == baseTag
+ || token->name() == basefontTag
+ || token->name() == bgsoundTag
+ || token->name() == commandTag
+ || token->name() == linkTag
+ || token->name() == metaTag) {
+ m_tree.insertSelfClosingHTMLElement(token);
// Note: The custom processing for the <meta> tag is done in HTMLMetaElement::process().
return true;
}
- if (token.name() == titleTag) {
+ if (token->name() == titleTag) {
processGenericRCDATAStartTag(token);
return true;
}
- if (token.name() == noscriptTag) {
+ if (token->name() == noscriptTag) {
if (m_options.scriptEnabled) {
processGenericRawTextStartTag(token);
return true;
}
- m_tree.insertHTMLElement(&token);
- m_insertionMode = InsertionMode::InHeadNoscript;
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InsertionMode::InHeadNoscript);
return true;
}
- if (token.name() == noframesTag || token.name() == styleTag) {
+ if (token->name() == noframesTag || token->name() == styleTag) {
processGenericRawTextStartTag(token);
return true;
}
- if (token.name() == scriptTag) {
+ if (token->name() == scriptTag) {
processScriptStartTag(token);
- if (m_options.usePreHTML5ParserQuirks && token.selfClosing())
+ if (m_options.usePreHTML5ParserQuirks && token->selfClosing())
processFakeEndTag(scriptTag);
return true;
}
#if ENABLE(TEMPLATE_ELEMENT)
- if (token.name() == templateTag) {
+ if (token->name() == templateTag) {
processTemplateStartTag(token);
return true;
}
#endif
- if (token.name() == headTag) {
+ if (token->name() == headTag) {
parseError(token);
return true;
}
return false;
}
-void HTMLTreeBuilder::processGenericRCDATAStartTag(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processGenericRCDATAStartTag(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::StartTag);
- m_tree.insertHTMLElement(&token);
- m_parser.tokenizer().setRCDATAState();
+ ASSERT(token->type() == HTMLToken::StartTag);
+ m_tree.insertHTMLElement(token);
+ if (m_parser.tokenizer())
+ m_parser.tokenizer()->setState(HTMLTokenizer::RCDATAState);
m_originalInsertionMode = m_insertionMode;
- m_insertionMode = InsertionMode::Text;
+ setInsertionMode(InsertionMode::Text);
}
-void HTMLTreeBuilder::processGenericRawTextStartTag(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processGenericRawTextStartTag(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::StartTag);
- m_tree.insertHTMLElement(&token);
- m_parser.tokenizer().setRAWTEXTState();
+ ASSERT(token->type() == HTMLToken::StartTag);
+ m_tree.insertHTMLElement(token);
+ if (m_parser.tokenizer())
+ m_parser.tokenizer()->setState(HTMLTokenizer::RAWTEXTState);
m_originalInsertionMode = m_insertionMode;
- m_insertionMode = InsertionMode::Text;
+ setInsertionMode(InsertionMode::Text);
}
-void HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken* token)
{
- ASSERT(token.type() == HTMLToken::StartTag);
- m_tree.insertScriptElement(&token);
- m_parser.tokenizer().setScriptDataState();
+ ASSERT(token->type() == HTMLToken::StartTag);
+ m_tree.insertScriptElement(token);
+ if (m_parser.tokenizer())
+ m_parser.tokenizer()->setState(HTMLTokenizer::ScriptDataState);
m_originalInsertionMode = m_insertionMode;
TextPosition position = m_parser.textPosition();
m_scriptToProcessStartPosition = position;
- m_insertionMode = InsertionMode::Text;
-}
-
-// http://www.whatwg.org/specs/web-apps/current-work/#adjusted-current-node
-HTMLStackItem& HTMLTreeBuilder::adjustedCurrentStackItem() const
-{
- ASSERT(!m_tree.isEmpty());
- if (isParsingFragment() && m_tree.openElements().hasOnlyOneElement())
- return m_fragmentContext.contextElementStackItem();
-
- return m_tree.currentStackItem();
+ setInsertionMode(InsertionMode::Text);
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#tree-construction
-bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken& token)
+bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken* token)
{
if (m_tree.isEmpty())
return false;
- HTMLStackItem& adjustedCurrentNode = adjustedCurrentStackItem();
- if (isInHTMLNamespace(adjustedCurrentNode))
+ HTMLStackItem* item = m_tree.currentStackItem();
+ if (item->isInHTMLNamespace())
return false;
- if (HTMLElementStack::isMathMLTextIntegrationPoint(adjustedCurrentNode)) {
- if (token.type() == HTMLToken::StartTag
- && token.name() != MathMLNames::mglyphTag
- && token.name() != MathMLNames::malignmarkTag)
+ if (HTMLElementStack::isMathMLTextIntegrationPoint(item)) {
+ if (token->type() == HTMLToken::StartTag
+ && token->name() != MathMLNames::mglyphTag
+ && token->name() != MathMLNames::malignmarkTag)
return false;
- if (token.type() == HTMLToken::Character)
+ if (token->type() == HTMLToken::Character)
return false;
}
- if (adjustedCurrentNode.hasTagName(MathMLNames::annotation_xmlTag)
- && token.type() == HTMLToken::StartTag
- && token.name() == SVGNames::svgTag)
+ if (item->hasTagName(MathMLNames::annotation_xmlTag)
+ && token->type() == HTMLToken::StartTag
+ && token->name() == SVGNames::svgTag)
return false;
- if (HTMLElementStack::isHTMLIntegrationPoint(adjustedCurrentNode)) {
- if (token.type() == HTMLToken::StartTag)
+ if (HTMLElementStack::isHTMLIntegrationPoint(item)) {
+ if (token->type() == HTMLToken::StartTag)
return false;
- if (token.type() == HTMLToken::Character)
+ if (token->type() == HTMLToken::Character)
return false;
}
- if (token.type() == HTMLToken::EndOfFile)
+ if (token->type() == HTMLToken::EndOfFile)
return false;
return true;
}
-static bool hasAttribute(AtomicHTMLToken& token, const QualifiedName& name)
+void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token)
{
- return findAttribute(token.attributes(), name);
-}
-
-void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken& token)
-{
- HTMLStackItem& adjustedCurrentNode = adjustedCurrentStackItem();
-
- switch (token.type()) {
+ switch (token->type()) {
case HTMLToken::Uninitialized:
ASSERT_NOT_REACHED();
break;
@@ -2821,52 +2909,52 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken& token)
parseError(token);
break;
case HTMLToken::StartTag: {
- if (token.name() == bTag
- || token.name() == bigTag
- || token.name() == blockquoteTag
- || token.name() == bodyTag
- || token.name() == brTag
- || token.name() == centerTag
- || token.name() == codeTag
- || token.name() == ddTag
- || token.name() == divTag
- || token.name() == dlTag
- || token.name() == dtTag
- || token.name() == emTag
- || token.name() == embedTag
- || isNumberedHeaderTag(token.name())
- || token.name() == headTag
- || token.name() == hrTag
- || token.name() == iTag
- || token.name() == imgTag
- || token.name() == liTag
- || token.name() == listingTag
- || token.name() == menuTag
- || token.name() == metaTag
- || token.name() == nobrTag
- || token.name() == olTag
- || token.name() == pTag
- || token.name() == preTag
- || token.name() == rubyTag
- || token.name() == sTag
- || token.name() == smallTag
- || token.name() == spanTag
- || token.name() == strongTag
- || token.name() == strikeTag
- || token.name() == subTag
- || token.name() == supTag
- || token.name() == tableTag
- || token.name() == ttTag
- || token.name() == uTag
- || token.name() == ulTag
- || token.name() == varTag
- || (token.name() == fontTag && (hasAttribute(token, colorAttr) || hasAttribute(token, faceAttr) || hasAttribute(token, sizeAttr)))) {
+ if (token->name() == bTag
+ || token->name() == bigTag
+ || token->name() == blockquoteTag
+ || token->name() == bodyTag
+ || token->name() == brTag
+ || token->name() == centerTag
+ || token->name() == codeTag
+ || token->name() == ddTag
+ || token->name() == divTag
+ || token->name() == dlTag
+ || token->name() == dtTag
+ || token->name() == emTag
+ || token->name() == embedTag
+ || isNumberedHeaderTag(token->name())
+ || token->name() == headTag
+ || token->name() == hrTag
+ || token->name() == iTag
+ || token->name() == imgTag
+ || token->name() == liTag
+ || token->name() == listingTag
+ || token->name() == menuTag
+ || token->name() == metaTag
+ || token->name() == nobrTag
+ || token->name() == olTag
+ || token->name() == pTag
+ || token->name() == preTag
+ || token->name() == rubyTag
+ || token->name() == sTag
+ || token->name() == smallTag
+ || token->name() == spanTag
+ || token->name() == strongTag
+ || token->name() == strikeTag
+ || token->name() == subTag
+ || token->name() == supTag
+ || token->name() == tableTag
+ || token->name() == ttTag
+ || token->name() == uTag
+ || token->name() == ulTag
+ || token->name() == varTag
+ || (token->name() == fontTag && (token->getAttributeItem(colorAttr) || token->getAttributeItem(faceAttr) || token->getAttributeItem(sizeAttr)))) {
parseError(token);
- m_tree.openElements().popUntilForeignContentScopeMarker();
+ m_tree.openElements()->popUntilForeignContentScopeMarker();
processStartTag(token);
return;
}
- const AtomicString& currentNamespace = adjustedCurrentNode.namespaceURI();
+ const AtomicString& currentNamespace = m_tree.currentStackItem()->namespaceURI();
if (currentNamespace == MathMLNames::mathmlNamespaceURI)
adjustMathMLAttributes(token);
if (currentNamespace == SVGNames::svgNamespaceURI) {
@@ -2874,32 +2962,32 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken& token)
adjustSVGAttributes(token);
}
adjustForeignAttributes(token);
- m_tree.insertForeignElement(&token, currentNamespace);
+ m_tree.insertForeignElement(token, currentNamespace);
break;
}
case HTMLToken::EndTag: {
- if (adjustedCurrentNode.namespaceURI() == SVGNames::svgNamespaceURI)
+ if (m_tree.currentStackItem()->namespaceURI() == SVGNames::svgNamespaceURI)
adjustSVGTagNameCase(token);
- if (token.name() == SVGNames::scriptTag && m_tree.currentStackItem().hasTagName(SVGNames::scriptTag)) {
+ if (token->name() == SVGNames::scriptTag && m_tree.currentStackItem()->hasTagName(SVGNames::scriptTag)) {
if (scriptingContentIsAllowed(m_tree.parserContentPolicy()))
- m_scriptToProcess = &m_tree.currentElement();
- m_tree.openElements().pop();
+ m_scriptToProcess = m_tree.currentElement();
+ m_tree.openElements()->pop();
return;
}
- if (!isInHTMLNamespace(m_tree.currentStackItem())) {
+ if (!m_tree.currentStackItem()->isInHTMLNamespace()) {
// FIXME: This code just wants an Element* iterator, instead of an ElementRecord*
- auto* nodeRecord = &m_tree.openElements().topRecord();
- if (nodeRecord->stackItem().localName() != token.name())
+ HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
+ if (!nodeRecord->stackItem()->hasLocalName(token->name()))
parseError(token);
while (1) {
- if (nodeRecord->stackItem().localName() == token.name()) {
- m_tree.openElements().popUntilPopped(&nodeRecord->element());
+ if (nodeRecord->stackItem()->hasLocalName(token->name())) {
+ m_tree.openElements()->popUntilPopped(nodeRecord->element());
return;
}
nodeRecord = nodeRecord->next();
- if (isInHTMLNamespace(nodeRecord->stackItem()))
+ if (nodeRecord->stackItem()->isInHTMLNamespace())
break;
}
}
@@ -2908,10 +2996,10 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken& token)
break;
}
case HTMLToken::Comment:
- m_tree.insertComment(&token);
+ m_tree.insertComment(token);
return;
case HTMLToken::Character: {
- String characters = String(token.characters(), token.charactersLength());
+ String characters = String(token->characters(), token->charactersLength());
m_tree.insertTextNode(characters);
if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters))
m_framesetOk = false;
@@ -2925,8 +3013,6 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken& token)
void HTMLTreeBuilder::finished()
{
- ASSERT(!m_destroyed);
-
if (isParsingFragment())
return;
@@ -2934,11 +3020,12 @@ void HTMLTreeBuilder::finished()
ASSERT(m_templateInsertionModes.isEmpty());
#endif
+ ASSERT(m_isAttached);
+ // Warning, this may detach the parser. Do not do anything else after this.
m_tree.finishedParsing();
- // The tree builder might have been destroyed as an indirect result of finishing the parsing.
}
-inline void HTMLTreeBuilder::parseError(AtomicHTMLToken&)
+void HTMLTreeBuilder::parseError(AtomicHTMLToken*)
{
}
diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.h b/Source/WebCore/html/parser/HTMLTreeBuilder.h
index 806d97726..37353f2d7 100644
--- a/Source/WebCore/html/parser/HTMLTreeBuilder.h
+++ b/Source/WebCore/html/parser/HTMLTreeBuilder.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Google, Inc. All Rights Reserved.
- * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,37 +27,65 @@
#ifndef HTMLTreeBuilder_h
#define HTMLTreeBuilder_h
+#include "FragmentScriptingPermission.h"
#include "HTMLConstructionSite.h"
+#include "HTMLElementStack.h"
+#include "HTMLFormattingElementList.h"
#include "HTMLParserOptions.h"
+#include "HTMLTokenizer.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/TextPosition.h>
namespace WebCore {
+class AtomicHTMLToken;
+class Document;
+class DocumentFragment;
+class Element;
+class Frame;
+class HTMLToken;
+class HTMLDocument;
+class Node;
class HTMLDocumentParser;
class HTMLTreeBuilder {
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_NONCOPYABLE(HTMLTreeBuilder); WTF_MAKE_FAST_ALLOCATED;
public:
HTMLTreeBuilder(HTMLDocumentParser&, HTMLDocument&, ParserContentPolicy, const HTMLParserOptions&);
- HTMLTreeBuilder(HTMLDocumentParser&, DocumentFragment&, Element& contextElement, ParserContentPolicy, const HTMLParserOptions&);
- void setShouldSkipLeadingNewline(bool);
-
+ HTMLTreeBuilder(HTMLDocumentParser&, DocumentFragment&, Element* contextElement, ParserContentPolicy, const HTMLParserOptions&);
~HTMLTreeBuilder();
- bool isParsingFragment() const;
+ const HTMLElementStack* openElements() const { return m_tree.openElements(); }
- void constructTree(AtomicHTMLToken&);
+ bool isParsingFragment() const { return !!m_fragmentContext.fragment(); }
+#if ENABLE(TEMPLATE_ELEMENT)
+ bool isParsingTemplateContents() const { return m_tree.openElements()->hasTemplateInHTMLScope(); }
+#else
+ bool isParsingTemplateContents() const { return false; }
+#endif
+ bool isParsingFragmentOrTemplateContents() const { return isParsingFragment() || isParsingTemplateContents(); }
- bool hasParserBlockingScript() const;
+ void detach();
+ void constructTree(AtomicHTMLToken*);
+
+ bool hasParserBlockingScript() const { return !!m_scriptToProcess; }
// Must be called to take the parser-blocking script before calling the parser again.
- RefPtr<Element> takeScriptToProcess(TextPosition& scriptStartPosition);
+ PassRefPtr<Element> takeScriptToProcess(TextPosition& scriptStartPosition);
// Done, close any open tags, etc.
void finished();
+ void setShouldSkipLeadingNewline(bool shouldSkip) { m_shouldSkipLeadingNewline = shouldSkip; }
+
private:
class ExternalCharacterTokenBuffer;
-
// Represents HTML5 "insertion mode"
// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode
enum class InsertionMode {
@@ -67,9 +95,7 @@ private:
InHead,
InHeadNoscript,
AfterHead,
-#if ENABLE(TEMPLATE_ELEMENT)
TemplateContents,
-#endif
InBody,
Text,
InTable,
@@ -88,54 +114,52 @@ private:
AfterAfterFrameset,
};
- bool isParsingTemplateContents() const;
- bool isParsingFragmentOrTemplateContents() const;
-
-#if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(IOS)
+#if PLATFORM(IOS)
void insertPhoneNumberLink(const String&);
void linkifyPhoneNumbers(const String&);
#endif
- void processToken(AtomicHTMLToken&);
-
- void processDoctypeToken(AtomicHTMLToken&);
- void processStartTag(AtomicHTMLToken&);
- void processEndTag(AtomicHTMLToken&);
- void processComment(AtomicHTMLToken&);
- void processCharacter(AtomicHTMLToken&);
- void processEndOfFile(AtomicHTMLToken&);
-
- bool processStartTagForInHead(AtomicHTMLToken&);
- void processStartTagForInBody(AtomicHTMLToken&);
- void processStartTagForInTable(AtomicHTMLToken&);
- void processEndTagForInBody(AtomicHTMLToken&);
- void processEndTagForInTable(AtomicHTMLToken&);
- void processEndTagForInTableBody(AtomicHTMLToken&);
- void processEndTagForInRow(AtomicHTMLToken&);
- void processEndTagForInCell(AtomicHTMLToken&);
-
- void processIsindexStartTagForInBody(AtomicHTMLToken&);
- void processHtmlStartTagForInBody(AtomicHTMLToken&);
- bool processBodyEndTagForInBody(AtomicHTMLToken&);
+ void processToken(AtomicHTMLToken*);
+
+ void processDoctypeToken(AtomicHTMLToken*);
+ void processStartTag(AtomicHTMLToken*);
+ void processEndTag(AtomicHTMLToken*);
+ void processComment(AtomicHTMLToken*);
+ void processCharacter(AtomicHTMLToken*);
+ void processEndOfFile(AtomicHTMLToken*);
+
+ bool processStartTagForInHead(AtomicHTMLToken*);
+ void processStartTagForInBody(AtomicHTMLToken*);
+ void processStartTagForInTable(AtomicHTMLToken*);
+ void processEndTagForInBody(AtomicHTMLToken*);
+ void processEndTagForInTable(AtomicHTMLToken*);
+ void processEndTagForInTableBody(AtomicHTMLToken*);
+ void processEndTagForInRow(AtomicHTMLToken*);
+ void processEndTagForInCell(AtomicHTMLToken*);
+
+ void processIsindexStartTagForInBody(AtomicHTMLToken*);
+ void processHtmlStartTagForInBody(AtomicHTMLToken*);
+ bool processBodyEndTagForInBody(AtomicHTMLToken*);
bool processTableEndTagForInTable();
bool processCaptionEndTagForInCaption();
bool processColgroupEndTagForInColumnGroup();
bool processTrEndTagForInRow();
-
- void processAnyOtherEndTagForInBody(AtomicHTMLToken&);
+ // FIXME: This function should be inlined into its one call site or it
+ // needs to assert which tokens it can be called with.
+ void processAnyOtherEndTagForInBody(AtomicHTMLToken*);
void processCharacterBuffer(ExternalCharacterTokenBuffer&);
inline void processCharacterBufferForInBody(ExternalCharacterTokenBuffer&);
- void processFakeStartTag(const QualifiedName&, Vector<Attribute>&& attributes = Vector<Attribute>());
+ void processFakeStartTag(const QualifiedName&, const Vector<Attribute>& attributes = Vector<Attribute>());
void processFakeEndTag(const QualifiedName&);
void processFakeEndTag(const AtomicString&);
void processFakeCharacters(const String&);
void processFakePEndTagIfPInButtonScope();
- void processGenericRCDATAStartTag(AtomicHTMLToken&);
- void processGenericRawTextStartTag(AtomicHTMLToken&);
- void processScriptStartTag(AtomicHTMLToken&);
+ void processGenericRCDATAStartTag(AtomicHTMLToken*);
+ void processGenericRawTextStartTag(AtomicHTMLToken*);
+ void processScriptStartTag(AtomicHTMLToken*);
// Default processing for the different insertion modes.
void defaultForInitial();
@@ -146,104 +170,78 @@ private:
void defaultForAfterHead();
void defaultForInTableText();
- bool shouldProcessTokenInForeignContent(AtomicHTMLToken&);
- void processTokenInForeignContent(AtomicHTMLToken&);
-
- HTMLStackItem& adjustedCurrentStackItem() const;
+ inline bool shouldProcessTokenInForeignContent(AtomicHTMLToken*);
+ void processTokenInForeignContent(AtomicHTMLToken*);
- Vector<Attribute> attributesForIsindexInput(AtomicHTMLToken&);
+ Vector<Attribute> attributesForIsindexInput(AtomicHTMLToken*);
- void callTheAdoptionAgency(AtomicHTMLToken&);
+ void callTheAdoptionAgency(AtomicHTMLToken*);
void closeTheCell();
- template <bool shouldClose(const HTMLStackItem&)> void processCloseWhenNestedTag(AtomicHTMLToken&);
+ template <bool shouldClose(const HTMLStackItem*)>
+ void processCloseWhenNestedTag(AtomicHTMLToken*);
+
+ void parseError(AtomicHTMLToken*);
- void parseError(AtomicHTMLToken&);
+ InsertionMode insertionMode() const { return m_insertionMode; }
+ void setInsertionMode(InsertionMode mode) { m_insertionMode = mode; }
void resetInsertionModeAppropriately();
#if ENABLE(TEMPLATE_ELEMENT)
- void processTemplateStartTag(AtomicHTMLToken&);
- bool processTemplateEndTag(AtomicHTMLToken&);
- bool processEndOfFileForInTemplateContents(AtomicHTMLToken&);
+ void processTemplateStartTag(AtomicHTMLToken*);
+ bool processTemplateEndTag(AtomicHTMLToken*);
+ bool processEndOfFileForInTemplateContents(AtomicHTMLToken*);
#endif
class FragmentParsingContext {
+ WTF_MAKE_NONCOPYABLE(FragmentParsingContext);
public:
FragmentParsingContext();
- FragmentParsingContext(DocumentFragment&, Element& contextElement);
+ FragmentParsingContext(DocumentFragment&, Element* contextElement);
+ ~FragmentParsingContext();
- DocumentFragment* fragment() const;
- Element& contextElement() const;
- HTMLStackItem& contextElementStackItem() const;
+ DocumentFragment* fragment() const { return m_fragment; }
+ Element* contextElement() const { ASSERT(m_fragment); return m_contextElement; }
private:
- DocumentFragment* m_fragment { nullptr };
- RefPtr<HTMLStackItem> m_contextElementStackItem;
+ DocumentFragment* m_fragment;
+ Element* m_contextElement;
};
- HTMLDocumentParser& m_parser;
- const HTMLParserOptions m_options;
- const FragmentParsingContext m_fragmentContext;
-
+ bool m_framesetOk;
+#ifndef NDEBUG
+ bool m_isAttached;
+#endif
+ FragmentParsingContext m_fragmentContext;
HTMLConstructionSite m_tree;
- // https://html.spec.whatwg.org/multipage/syntax.html#the-insertion-mode
- InsertionMode m_insertionMode { InsertionMode::Initial };
- InsertionMode m_originalInsertionMode { InsertionMode::Initial };
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode
+ InsertionMode m_insertionMode;
+
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#original-insertion-mode
+ InsertionMode m_originalInsertionMode;
+
#if ENABLE(TEMPLATE_ELEMENT)
- Vector<InsertionMode, 1> m_templateInsertionModes;
+ Vector<InsertionMode> m_templateInsertionModes;
#endif
- // https://html.spec.whatwg.org/multipage/syntax.html#concept-pending-table-char-tokens
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#pending-table-character-tokens
StringBuilder m_pendingTableCharacters;
- RefPtr<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser.
- TextPosition m_scriptToProcessStartPosition; // Starting line number of the script tag needing processing.
+ bool m_shouldSkipLeadingNewline;
- bool m_shouldSkipLeadingNewline { false };
+ // We access parser because HTML5 spec requires that we be able to change the state of the tokenizer
+ // from within parser actions. We also need it to track the current position.
+ HTMLDocumentParser& m_parser;
- bool m_framesetOk { true };
+ RefPtr<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser.
+ TextPosition m_scriptToProcessStartPosition; // Starting line number of the script tag needing processing.
-#if !ASSERT_DISABLED
- bool m_destroyed { false };
- bool m_destructionProhibited { true };
-#endif
+ HTMLParserOptions m_options;
};
-inline HTMLTreeBuilder::~HTMLTreeBuilder()
-{
-#if !ASSERT_DISABLED
- ASSERT(!m_destroyed);
- ASSERT(!m_destructionProhibited);
- m_destroyed = true;
-#endif
-}
-
-inline void HTMLTreeBuilder::setShouldSkipLeadingNewline(bool shouldSkip)
-{
- ASSERT(!m_destroyed);
- m_shouldSkipLeadingNewline = shouldSkip;
-}
-
-inline bool HTMLTreeBuilder::isParsingFragment() const
-{
- ASSERT(!m_destroyed);
- return !!m_fragmentContext.fragment();
-}
-
-inline bool HTMLTreeBuilder::hasParserBlockingScript() const
-{
- ASSERT(!m_destroyed);
- return !!m_scriptToProcess;
-}
-
-inline DocumentFragment* HTMLTreeBuilder::FragmentParsingContext::fragment() const
-{
- return m_fragment;
-}
-
}
#endif
diff --git a/Source/WebCore/html/parser/HTMLViewSourceParser.cpp b/Source/WebCore/html/parser/HTMLViewSourceParser.cpp
new file mode 100644
index 000000000..35ccebea2
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLViewSourceParser.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2010 Google, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLViewSourceParser.h"
+
+#include "HTMLDocumentParser.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument& document)
+ : DecodedDataDocumentParser(document)
+ , m_tokenizer(std::make_unique<HTMLTokenizer>(HTMLParserOptions(document)))
+{
+}
+
+HTMLViewSourceParser::~HTMLViewSourceParser()
+{
+}
+
+void HTMLViewSourceParser::insert(const SegmentedString&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void HTMLViewSourceParser::pumpTokenizer()
+{
+ while (true) {
+ m_sourceTracker.start(m_input.current(), m_tokenizer.get(), m_token);
+ if (!m_tokenizer->nextToken(m_input.current(), m_token))
+ break;
+ m_sourceTracker.end(m_input.current(), m_tokenizer.get(), m_token);
+
+ document()->addSource(sourceForToken(), m_token);
+ updateTokenizerState();
+ m_token.clear();
+ }
+}
+
+void HTMLViewSourceParser::append(PassRefPtr<StringImpl> input)
+{
+ m_input.appendToEnd(String(input));
+ pumpTokenizer();
+}
+
+String HTMLViewSourceParser::sourceForToken()
+{
+ return m_sourceTracker.sourceForToken(m_token);
+}
+
+void HTMLViewSourceParser::updateTokenizerState()
+{
+ // FIXME: The tokenizer should do this work for us.
+ if (m_token.type() != HTMLToken::StartTag)
+ return;
+ m_tokenizer->updateStateFor(AtomicString(m_token.name()));
+}
+
+void HTMLViewSourceParser::finish()
+{
+ if (!m_input.haveSeenEndOfFile())
+ m_input.markEndOfFile();
+ pumpTokenizer();
+ document()->finishedParsing();
+}
+
+}
diff --git a/Source/WebCore/html/parser/HTMLViewSourceParser.h b/Source/WebCore/html/parser/HTMLViewSourceParser.h
new file mode 100644
index 000000000..c48adbeb7
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLViewSourceParser.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010 Google, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLViewSourceParser_h
+#define HTMLViewSourceParser_h
+
+#include "DecodedDataDocumentParser.h"
+#include "HTMLInputStream.h"
+#include "HTMLSourceTracker.h"
+#include "HTMLToken.h"
+#include "HTMLTokenizer.h"
+#include "HTMLViewSourceDocument.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class HTMLTokenizer;
+class HTMLScriptRunner;
+class HTMLTreeBuilder;
+class HTMLPreloadScanner;
+class ScriptController;
+class ScriptSourceCode;
+
+class HTMLViewSourceParser : public DecodedDataDocumentParser {
+public:
+ static PassRefPtr<HTMLViewSourceParser> create(HTMLViewSourceDocument& document)
+ {
+ return adoptRef(new HTMLViewSourceParser(document));
+ }
+ virtual ~HTMLViewSourceParser();
+
+protected:
+ explicit HTMLViewSourceParser(HTMLViewSourceDocument&);
+
+ HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); }
+
+private:
+ // DocumentParser
+ virtual void insert(const SegmentedString&) override;
+ virtual void append(PassRefPtr<StringImpl>) override;
+ virtual void finish() override;
+
+ HTMLViewSourceDocument* document() const { return static_cast<HTMLViewSourceDocument*>(DecodedDataDocumentParser::document()); }
+
+ void pumpTokenizer();
+ String sourceForToken();
+ void updateTokenizerState();
+
+ HTMLInputStream m_input;
+ HTMLToken m_token;
+ HTMLSourceTracker m_sourceTracker;
+ std::unique_ptr<HTMLTokenizer> m_tokenizer;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/InputStreamPreprocessor.h b/Source/WebCore/html/parser/InputStreamPreprocessor.h
index 8e100704b..ffd639abe 100644
--- a/Source/WebCore/html/parser/InputStreamPreprocessor.h
+++ b/Source/WebCore/html/parser/InputStreamPreprocessor.h
@@ -30,7 +30,6 @@
#include "SegmentedString.h"
#include <wtf/Noncopyable.h>
-#include <wtf/unicode/CharacterNames.h>
namespace WebCore {
@@ -41,7 +40,7 @@ template <typename Tokenizer>
class InputStreamPreprocessor {
WTF_MAKE_NONCOPYABLE(InputStreamPreprocessor);
public:
- explicit InputStreamPreprocessor(Tokenizer& tokenizer)
+ InputStreamPreprocessor(Tokenizer* tokenizer)
: m_tokenizer(tokenizer)
{
reset();
@@ -52,11 +51,8 @@ public:
// Returns whether we succeeded in peeking at the next character.
// The only way we can fail to peek is if there are no more
// characters in |source| (after collapsing \r\n, etc).
- ALWAYS_INLINE bool peek(SegmentedString& source, bool skipNullCharacters = false)
+ ALWAYS_INLINE bool peek(SegmentedString& source)
{
- if (source.isEmpty())
- return false;
-
m_nextInputCharacter = source.currentChar();
// Every branch in this function is expensive, so we have a
@@ -68,14 +64,16 @@ public:
m_skipNextNewLine = false;
return true;
}
- return processNextInputCharacter(source, skipNullCharacters);
+ return processNextInputCharacter(source);
}
// Returns whether there are more characters in |source| after advancing.
- ALWAYS_INLINE bool advance(SegmentedString& source, bool skipNullCharacters = false)
+ ALWAYS_INLINE bool advance(SegmentedString& source)
{
source.advanceAndUpdateLineNumber();
- return peek(source, skipNullCharacters);
+ if (source.isEmpty())
+ return false;
+ return peek(source);
}
bool skipNextNewLine() const { return m_skipNextNewLine; }
@@ -87,7 +85,7 @@ public:
}
private:
- bool processNextInputCharacter(SegmentedString& source, bool skipNullCharacters)
+ bool processNextInputCharacter(SegmentedString& source)
{
ProcessAgain:
ASSERT(m_nextInputCharacter == source.currentChar());
@@ -109,14 +107,14 @@ private:
// by the replacement character. We suspect this is a problem with the spec as doing
// that filtering breaks surrogate pair handling and causes us not to match Minefield.
if (m_nextInputCharacter == '\0' && !shouldTreatNullAsEndOfFileMarker(source)) {
- if (skipNullCharacters && !m_tokenizer.neverSkipNullCharacters()) {
+ if (m_tokenizer->shouldSkipNullCharacters()) {
source.advancePastNonNewline();
if (source.isEmpty())
return false;
m_nextInputCharacter = source.currentChar();
goto ProcessAgain;
}
- m_nextInputCharacter = replacementCharacter;
+ m_nextInputCharacter = 0xFFFD;
}
}
return true;
@@ -127,7 +125,7 @@ private:
return source.isClosed() && source.length() == 1;
}
- Tokenizer& m_tokenizer;
+ Tokenizer* m_tokenizer;
// http://www.whatwg.org/specs/web-apps/current-work/#next-input-character
UChar m_nextInputCharacter;
diff --git a/Source/WebCore/html/parser/TextDocumentParser.cpp b/Source/WebCore/html/parser/TextDocumentParser.cpp
index 5fa62a322..30bed65b2 100644
--- a/Source/WebCore/html/parser/TextDocumentParser.cpp
+++ b/Source/WebCore/html/parser/TextDocumentParser.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
@@ -25,6 +25,7 @@
#include "config.h"
#include "TextDocumentParser.h"
+#include "HTMLDocument.h"
#include "HTMLTreeBuilder.h"
namespace WebCore {
@@ -33,6 +34,11 @@ using namespace HTMLNames;
TextDocumentParser::TextDocumentParser(HTMLDocument& document)
: HTMLDocumentParser(document)
+ , m_haveInsertedFakePreElement(false)
+{
+}
+
+TextDocumentParser::~TextDocumentParser()
{
}
@@ -52,16 +58,16 @@ void TextDocumentParser::insertFakePreElement()
// distrubing the line/column number calculations.
Vector<Attribute> attributes;
attributes.append(Attribute(styleAttr, "word-wrap: break-word; white-space: pre-wrap;"));
- AtomicHTMLToken fakePre(HTMLToken::StartTag, preTag.localName(), WTF::move(attributes));
- treeBuilder().constructTree(fakePre);
+ AtomicHTMLToken fakePre(HTMLToken::StartTag, preTag.localName(), attributes);
+ treeBuilder()->constructTree(&fakePre);
// Normally we would skip the first \n after a <pre> element, but we don't
// want to skip the first \n for text documents!
- treeBuilder().setShouldSkipLeadingNewline(false);
+ treeBuilder()->setShouldSkipLeadingNewline(false);
// Although Text Documents expose a "pre" element in their DOM, they
// act like a <plaintext> tag, so we have to force plaintext mode.
- tokenizer().setPLAINTEXTState();
+ forcePlaintextForTextDocument();
m_haveInsertedFakePreElement = true;
}
diff --git a/Source/WebCore/html/parser/TextDocumentParser.h b/Source/WebCore/html/parser/TextDocumentParser.h
index 5f5a09ed2..dcf235112 100644
--- a/Source/WebCore/html/parser/TextDocumentParser.h
+++ b/Source/WebCore/html/parser/TextDocumentParser.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
@@ -22,6 +22,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#ifndef TextDocumentParser_h
#define TextDocumentParser_h
@@ -31,19 +32,19 @@ namespace WebCore {
class TextDocumentParser final : public HTMLDocumentParser {
public:
- static Ref<TextDocumentParser> create(HTMLDocument& document)
+ static PassRefPtr<TextDocumentParser> create(HTMLDocument& document)
{
- return adoptRef(*new TextDocumentParser(document));
+ return adoptRef(new TextDocumentParser(document));
}
+ virtual ~TextDocumentParser();
private:
explicit TextDocumentParser(HTMLDocument&);
virtual void append(PassRefPtr<StringImpl>) override;
-
void insertFakePreElement();
- bool m_haveInsertedFakePreElement { false };
+ bool m_haveInsertedFakePreElement;
};
}
diff --git a/Source/WebCore/html/WebAutocapitalize.h b/Source/WebCore/html/parser/TextViewSourceParser.cpp
index b76dda564..1f25721eb 100644
--- a/Source/WebCore/html/WebAutocapitalize.h
+++ b/Source/WebCore/html/parser/TextViewSourceParser.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2010 Google, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,15 +23,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebAutocapitalize_h
-#define WebAutocapitalize_h
+#include "config.h"
+#include "TextViewSourceParser.h"
-typedef enum {
- WebAutocapitalizeTypeDefault,
- WebAutocapitalizeTypeNone,
- WebAutocapitalizeTypeWords,
- WebAutocapitalizeTypeSentences,
- WebAutocapitalizeTypeAllCharacters
-} WebAutocapitalizeType;
+#include "HTMLTokenizer.h"
-#endif // WebAutocapitalize_h
+namespace WebCore {
+
+TextViewSourceParser::TextViewSourceParser(HTMLViewSourceDocument& document)
+ : HTMLViewSourceParser(document)
+{
+ tokenizer()->setState(HTMLTokenizer::PLAINTEXTState);
+}
+
+TextViewSourceParser::~TextViewSourceParser()
+{
+}
+
+}
diff --git a/Source/WebCore/html/Autocapitalize.h b/Source/WebCore/html/parser/TextViewSourceParser.h
index 809ff10de..c80932ca6 100644
--- a/Source/WebCore/html/Autocapitalize.h
+++ b/Source/WebCore/html/parser/TextViewSourceParser.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2010 Google, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,19 +23,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef Autocapitalize_h
-#define Autocapitalize_h
+#ifndef TextViewSourceParser_h
+#define TextViewSourceParser_h
-#include "WebAutocapitalize.h"
-
-// FIXME: Forward declare AtomicString instead of including AtomicString.h once we upstream the iOS port.
-#include <wtf/text/AtomicString.h>
+#include "HTMLViewSourceParser.h"
namespace WebCore {
-WebAutocapitalizeType autocapitalizeTypeForAttributeValue(const AtomicString&);
-const AtomicString& stringForAutocapitalizeType(WebAutocapitalizeType);
+class TextViewSourceParser final : public HTMLViewSourceParser {
+public:
+ static PassRefPtr<TextViewSourceParser> create(HTMLViewSourceDocument& document)
+ {
+ return adoptRef(new TextViewSourceParser(document));
+ }
+ virtual ~TextViewSourceParser();
+
+private:
+ explicit TextViewSourceParser(HTMLViewSourceDocument&);
+};
}
-#endif // Autocapitalize_h
+#endif
diff --git a/Source/WebCore/html/parser/XSSAuditor.cpp b/Source/WebCore/html/parser/XSSAuditor.cpp
index 82c5edc4f..1bf5a096e 100644
--- a/Source/WebCore/html/parser/XSSAuditor.cpp
+++ b/Source/WebCore/html/parser/XSSAuditor.cpp
@@ -37,13 +37,15 @@
#include "HTMLNames.h"
#include "HTMLParamElement.h"
#include "HTMLParserIdioms.h"
-#include "SVGNames.h"
#include "Settings.h"
#include "TextResourceDecoder.h"
#include "XLinkNames.h"
-#include <wtf/ASCIICType.h>
#include <wtf/MainThread.h>
+#if ENABLE(SVG)
+#include "SVGNames.h"
+#endif
+
namespace WebCore {
using namespace HTMLNames;
@@ -88,28 +90,17 @@ static bool isJSNewline(UChar c)
static bool startsHTMLCommentAt(const String& string, size_t start)
{
- return (start + 3 < string.length() && string[start] == '<' && string[start + 1] == '!' && string[start + 2] == '-' && string[start + 3] == '-');
+ return (start + 3 < string.length() && string[start] == '<' && string[start+1] == '!' && string[start+2] == '-' && string[start+3] == '-');
}
static bool startsSingleLineCommentAt(const String& string, size_t start)
{
- return (start + 1 < string.length() && string[start] == '/' && string[start + 1] == '/');
+ return (start + 1 < string.length() && string[start] == '/' && string[start+1] == '/');
}
static bool startsMultiLineCommentAt(const String& string, size_t start)
{
- return (start + 1 < string.length() && string[start] == '/' && string[start + 1] == '*');
-}
-
-static bool startsOpeningScriptTagAt(const String& string, size_t start)
-{
- return start + 6 < string.length() && string[start] == '<'
- && WTF::toASCIILowerUnchecked(string[start + 1]) == 's'
- && WTF::toASCIILowerUnchecked(string[start + 2]) == 'c'
- && WTF::toASCIILowerUnchecked(string[start + 3]) == 'r'
- && WTF::toASCIILowerUnchecked(string[start + 4]) == 'i'
- && WTF::toASCIILowerUnchecked(string[start + 5]) == 'p'
- && WTF::toASCIILowerUnchecked(string[start + 6]) == 't';
+ return (start + 1 < string.length() && string[start] == '/' && string[start+1] == '*');
}
// If other files need this, we should move this to HTMLParserIdioms.h
@@ -190,7 +181,12 @@ static ContentSecurityPolicy::ReflectedXSSDisposition combineXSSProtectionHeader
static bool isSemicolonSeparatedAttribute(const HTMLToken::Attribute& attribute)
{
+#if ENABLE(SVG)
return threadSafeMatch(attribute.name, SVGNames::valuesAttr);
+#else
+ UNUSED_PARAM(attribute);
+ return false;
+#endif
}
static bool semicolonSeparatedValueContainsJavaScriptURL(const String& value)
@@ -244,7 +240,7 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
if (!m_isEnabled)
return;
- m_documentURL = document->url().isolatedCopy();
+ m_documentURL = document->url().copy();
// In theory, the Document could have detached from the Frame after the
// XSSAuditor was constructed.
@@ -273,7 +269,7 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
String httpBodyAsString;
if (DocumentLoader* documentLoader = document->frame()->loader().documentLoader()) {
- DEPRECATED_DEFINE_STATIC_LOCAL(String, XSSProtectionHeader, (ASCIILiteral("X-XSS-Protection")));
+ DEFINE_STATIC_LOCAL(String, XSSProtectionHeader, (ASCIILiteral("X-XSS-Protection")));
String headerValue = documentLoader->response().httpHeaderField(XSSProtectionHeader);
String errorDetails;
unsigned errorPosition = 0;
@@ -292,7 +288,7 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
}
}
if (xssProtectionHeader == ContentSecurityPolicy::ReflectedXSSInvalid)
- document->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Error parsing header X-XSS-Protection: " + headerValue + ": " + errorDetails + " at character position " + String::format("%u", errorPosition) + ". The default protections will be applied.");
+ document->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Error parsing header X-XSS-Protection: " + headerValue + ": " + errorDetails + " at character position " + String::format("%u", errorPosition) + ". The default protections will be applied.");
ContentSecurityPolicy::ReflectedXSSDisposition cspHeader = document->contentSecurityPolicy()->reflectedXSSDisposition();
m_didSendValidCSPHeader = cspHeader != ContentSecurityPolicy::ReflectedXSSUnset && cspHeader != ContentSecurityPolicy::ReflectedXSSInvalid;
@@ -300,7 +296,7 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
m_xssProtection = combineXSSProtectionHeaderAndCSP(xssProtectionHeader, cspHeader);
// FIXME: Combine the two report URLs in some reasonable way.
if (auditorDelegate)
- auditorDelegate->setReportURL(xssProtectionReportURL.isolatedCopy());
+ auditorDelegate->setReportURL(xssProtectionReportURL.copy());
FormData* httpBody = documentLoader->originalRequest().httpBody();
if (httpBody && !httpBody->isEmpty()) {
httpBodyAsString = httpBody->flattenToString();
@@ -340,7 +336,7 @@ std::unique_ptr<XSSInfo> XSSAuditor::filterToken(const FilterTokenRequest& reque
return nullptr;
bool didBlockEntirePage = (m_xssProtection == ContentSecurityPolicy::BlockReflectedXSS);
- return std::make_unique<XSSInfo>(m_documentURL, didBlockEntirePage, m_didSendValidXSSProtectionHeader, m_didSendValidCSPHeader);
+ return std::make_unique<XSSInfo>(didBlockEntirePage, m_didSendValidXSSProtectionHeader, m_didSendValidCSPHeader);
}
bool XSSAuditor::filterStartToken(const FilterTokenRequest& request)
@@ -359,8 +355,8 @@ bool XSSAuditor::filterStartToken(const FilterTokenRequest& request)
didBlockScript |= filterEmbedToken(request);
else if (hasName(request.token, appletTag))
didBlockScript |= filterAppletToken(request);
- else if (hasName(request.token, iframeTag) || hasName(request.token, frameTag))
- didBlockScript |= filterFrameToken(request);
+ else if (hasName(request.token, iframeTag))
+ didBlockScript |= filterIframeToken(request);
else if (hasName(request.token, metaTag))
didBlockScript |= filterMetaToken(request);
else if (hasName(request.token, baseTag))
@@ -388,9 +384,8 @@ bool XSSAuditor::filterCharacterToken(const FilterTokenRequest& request)
{
ASSERT(m_scriptTagNestingLevel);
if (isContainedInRequest(m_cachedDecodedSnippet) && isContainedInRequest(decodedSnippetForJavaScript(request))) {
- request.token.clear();
- LChar space = ' ';
- request.token.appendToCharacter(space); // Technically, character tokens can't be empty.
+ request.token.eraseCharacters();
+ request.token.appendToCharacter(' '); // Technically, character tokens can't be empty.
return true;
}
return false;
@@ -469,10 +464,10 @@ bool XSSAuditor::filterAppletToken(const FilterTokenRequest& request)
return didBlockScript;
}
-bool XSSAuditor::filterFrameToken(const FilterTokenRequest& request)
+bool XSSAuditor::filterIframeToken(const FilterTokenRequest& request)
{
ASSERT(request.token.type() == HTMLToken::StartTag);
- ASSERT(hasName(request.token, iframeTag) || hasName(request.token, frameTag));
+ ASSERT(hasName(request.token, iframeTag));
bool didBlockScript = eraseAttributeIfInjected(request, srcdocAttr, String(), ScriptLikeAttribute);
if (isContainedInRequest(decodedSnippetForName(request)))
@@ -523,7 +518,7 @@ bool XSSAuditor::filterButtonToken(const FilterTokenRequest& request)
bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& request)
{
- DEPRECATED_DEFINE_STATIC_LOCAL(String, safeJavaScriptURL, (ASCIILiteral("javascript:void(0)")));
+ DEFINE_STATIC_LOCAL(String, safeJavaScriptURL, (ASCIILiteral("javascript:void(0)")));
bool didBlockScript = false;
for (size_t i = 0; i < request.token.attributes().size(); ++i) {
@@ -566,18 +561,18 @@ bool XSSAuditor::eraseAttributeIfInjected(const FilterTokenRequest& request, con
String XSSAuditor::decodedSnippetForName(const FilterTokenRequest& request)
{
// Grab a fixed number of characters equal to the length of the token's name plus one (to account for the "<").
- return fullyDecodeString(request.sourceTracker.source(request.token), m_encoding).substring(0, request.token.name().size() + 1);
+ return fullyDecodeString(request.sourceTracker.sourceForToken(request.token), m_encoding).substring(0, request.token.name().size() + 1);
}
String XSSAuditor::decodedSnippetForAttribute(const FilterTokenRequest& request, const HTMLToken::Attribute& attribute, AttributeKind treatment)
{
- // The range doesn't include the character which terminates the value. So,
+ // The range doesn't inlcude the character which terminates the value. So,
// for an input of |name="value"|, the snippet is |name="value|. For an
// unquoted input of |name=value |, the snippet is |name=value|.
// FIXME: We should grab one character before the name also.
- unsigned start = attribute.startOffset;
- unsigned end = attribute.endOffset;
- String decodedSnippet = fullyDecodeString(request.sourceTracker.source(request.token, start, end), m_encoding);
+ int start = attribute.nameRange.start - request.token.startIndex();
+ int end = attribute.valueRange.end - request.token.startIndex();
+ String decodedSnippet = fullyDecodeString(request.sourceTracker.sourceForToken(request.token).substring(start, end - start), m_encoding);
decodedSnippet.truncate(kMaximumFragmentLengthTarget);
if (treatment == SrcLikeAttribute) {
int slashCount = 0;
@@ -619,7 +614,7 @@ String XSSAuditor::decodedSnippetForAttribute(const FilterTokenRequest& request,
// !-- following a less-than sign. We stop instead on any ampersand
// slash, or less-than sign.
size_t position = 0;
- if ((position = decodedSnippet.find('=')) != notFound
+ if ((position = decodedSnippet.find("=")) != notFound
&& (position = decodedSnippet.find(isNotHTMLSpace, position + 1)) != notFound
&& (position = decodedSnippet.find(isTerminatingCharacter, isHTMLQuote(decodedSnippet[position]) ? position + 1 : position)) != notFound) {
decodedSnippet.truncate(position);
@@ -630,11 +625,10 @@ String XSSAuditor::decodedSnippetForAttribute(const FilterTokenRequest& request,
String XSSAuditor::decodedSnippetForJavaScript(const FilterTokenRequest& request)
{
- String string = request.sourceTracker.source(request.token);
+ String string = request.sourceTracker.sourceForToken(request.token);
size_t startPosition = 0;
size_t endPosition = string.length();
size_t foundPosition = notFound;
- size_t lastNonSpacePosition = notFound;
// Skip over initial comments to find start of code.
while (startPosition < endPosition) {
@@ -663,10 +657,13 @@ String XSSAuditor::decodedSnippetForJavaScript(const FilterTokenRequest& request
String result;
while (startPosition < endPosition && !result.length()) {
- // Stop at next comment (using the same rules as above for SVG/XML vs HTML), when we encounter a comma,
- // when we hit an opening <script> tag, or when we exceed the maximum length target. The comma rule
- // covers a common parameter concatenation case performed by some web servers.
- lastNonSpacePosition = notFound;
+ // Stop at next comment (using the same rules as above for SVG/XML vs HTML), when we
+ // encounter a comma, or when we exceed the maximum length target. The comma rule
+ // covers a common parameter concatenation case performed by some webservers.
+ // After hitting the length target, we can only stop at a point where we know we are
+ // not in the middle of a %-escape sequence. For the sake of simplicity, approximate
+ // not stopping inside a (possibly multiply encoded) %-esacpe sequence by breaking on
+ // whitespace only. We should have enough text in these cases to avoid false positives.
for (foundPosition = startPosition; foundPosition < endPosition; foundPosition++) {
if (!request.shouldAllowCDATA) {
if (startsSingleLineCommentAt(string, foundPosition) || startsMultiLineCommentAt(string, foundPosition)) {
@@ -678,25 +675,9 @@ String XSSAuditor::decodedSnippetForJavaScript(const FilterTokenRequest& request
break;
}
}
- if (string[foundPosition] == ',')
- break;
-
- if (lastNonSpacePosition != notFound && startsOpeningScriptTagAt(string, foundPosition)) {
- foundPosition = lastNonSpacePosition;
+ if (string[foundPosition] == ',' || (foundPosition > startPosition + kMaximumFragmentLengthTarget && isHTMLSpace(string[foundPosition]))) {
break;
}
-
- if (foundPosition > startPosition + kMaximumFragmentLengthTarget) {
- // After hitting the length target, we can only stop at a point where we know we are
- // not in the middle of a %-escape sequence. For the sake of simplicity, approximate
- // not stopping inside a (possibly multiply encoded) %-escape sequence by breaking on
- // whitespace only. We should have enough text in these cases to avoid false positives.
- if (isHTMLSpace(string[foundPosition]))
- break;
- }
-
- if (!isHTMLSpace(string[foundPosition]))
- lastNonSpacePosition = foundPosition;
}
result = fullyDecodeString(string.substring(startPosition, foundPosition - startPosition), m_encoding);
@@ -737,4 +718,12 @@ bool XSSAuditor::isLikelySafeResource(const String& url)
return (m_documentURL.host() == resourceURL.host() && resourceURL.query().isEmpty());
}
+bool XSSAuditor::isSafeToSendToAnotherThread() const
+{
+ return m_documentURL.isSafeToSendToAnotherThread()
+ && m_decodedURL.isSafeToSendToAnotherThread()
+ && m_decodedHTTPBody.isSafeToSendToAnotherThread()
+ && m_cachedDecodedSnippet.isSafeToSendToAnotherThread();
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/html/parser/XSSAuditor.h b/Source/WebCore/html/parser/XSSAuditor.h
index 34b6a8f93..28fe3dec9 100644
--- a/Source/WebCore/html/parser/XSSAuditor.h
+++ b/Source/WebCore/html/parser/XSSAuditor.h
@@ -31,6 +31,7 @@
#include "URL.h"
#include "SuffixTree.h"
#include "TextEncoding.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
@@ -61,6 +62,7 @@ public:
void initForFragment();
std::unique_ptr<XSSInfo> filterToken(const FilterTokenRequest&);
+ bool isSafeToSendToAnotherThread() const;
private:
static const size_t kMaximumFragmentLengthTarget = 100;
@@ -84,7 +86,7 @@ private:
bool filterParamToken(const FilterTokenRequest&);
bool filterEmbedToken(const FilterTokenRequest&);
bool filterAppletToken(const FilterTokenRequest&);
- bool filterFrameToken(const FilterTokenRequest&);
+ bool filterIframeToken(const FilterTokenRequest&);
bool filterMetaToken(const FilterTokenRequest&);
bool filterBaseToken(const FilterTokenRequest&);
bool filterFormToken(const FilterTokenRequest&);
diff --git a/Source/WebCore/html/parser/XSSAuditorDelegate.cpp b/Source/WebCore/html/parser/XSSAuditorDelegate.cpp
index f54d92afe..d06069b31 100644
--- a/Source/WebCore/html/parser/XSSAuditorDelegate.cpp
+++ b/Source/WebCore/html/parser/XSSAuditorDelegate.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "XSSAuditorDelegate.h"
+#include "Console.h"
+#include "DOMWindow.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "FormData.h"
@@ -50,28 +52,28 @@ XSSAuditorDelegate::XSSAuditorDelegate(Document& document)
ASSERT(isMainThread());
}
-static inline String buildConsoleError(const XSSInfo& xssInfo)
+static inline String buildConsoleError(const XSSInfo& xssInfo, const String& url)
{
StringBuilder message;
- message.appendLiteral("The XSS Auditor ");
+ message.append("The XSS Auditor ");
message.append(xssInfo.m_didBlockEntirePage ? "blocked access to" : "refused to execute a script in");
- message.appendLiteral(" '");
- message.append(xssInfo.m_originalURL);
- message.appendLiteral("' because ");
+ message.append(" '");
+ message.append(url);
+ message.append("' because ");
message.append(xssInfo.m_didBlockEntirePage ? "the source code of a script" : "its source code");
- message.appendLiteral(" was found within the request.");
+ message.append(" was found within the request.");
if (xssInfo.m_didSendCSPHeader)
- message.appendLiteral(" The server sent a 'Content-Security-Policy' header requesting this behavior.");
+ message.append(" The server sent a 'Content-Security-Policy' header requesting this behavior.");
else if (xssInfo.m_didSendXSSProtectionHeader)
- message.appendLiteral(" The server sent an 'X-XSS-Protection' header requesting this behavior.");
+ message.append(" The server sent an 'X-XSS-Protection' header requesting this behavior.");
else
- message.appendLiteral(" The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header.");
+ message.append(" The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header.");
return message.toString();
}
-PassRefPtr<FormData> XSSAuditorDelegate::generateViolationReport(const XSSInfo& xssInfo)
+PassRefPtr<FormData> XSSAuditorDelegate::generateViolationReport()
{
ASSERT(isMainThread());
@@ -82,12 +84,12 @@ PassRefPtr<FormData> XSSAuditorDelegate::generateViolationReport(const XSSInfo&
httpBody = formData->flattenToString();
}
- Ref<InspectorObject> reportDetails = InspectorObject::create();
- reportDetails->setString("request-url", xssInfo.m_originalURL);
+ RefPtr<InspectorObject> reportDetails = InspectorObject::create();
+ reportDetails->setString("request-url", m_document.url().string());
reportDetails->setString("request-body", httpBody);
- Ref<InspectorObject> reportObject = InspectorObject::create();
- reportObject->setObject("xss-report", WTF::move(reportDetails));
+ RefPtr<InspectorObject> reportObject = InspectorObject::create();
+ reportObject->setObject("xss-report", reportDetails.release());
return FormData::create(reportObject->toJSONString().utf8().data());
}
@@ -96,7 +98,7 @@ void XSSAuditorDelegate::didBlockScript(const XSSInfo& xssInfo)
{
ASSERT(isMainThread());
- m_document.addConsoleMessage(MessageSource::JS, MessageLevel::Error, buildConsoleError(xssInfo));
+ m_document.addConsoleMessage(JSMessageSource, ErrorMessageLevel, buildConsoleError(xssInfo, m_document.url().string()));
FrameLoader& frameLoader = m_document.frame()->loader();
if (xssInfo.m_didBlockEntirePage)
@@ -108,11 +110,11 @@ void XSSAuditorDelegate::didBlockScript(const XSSInfo& xssInfo)
frameLoader.client().didDetectXSS(m_document.url(), xssInfo.m_didBlockEntirePage);
if (!m_reportURL.isEmpty())
- PingLoader::sendViolationReport(*m_document.frame(), m_reportURL, generateViolationReport(xssInfo));
+ PingLoader::sendViolationReport(m_document.frame(), m_reportURL, generateViolationReport());
}
if (xssInfo.m_didBlockEntirePage)
- m_document.frame()->navigationScheduler().scheduleLocationChange(&m_document, m_document.securityOrigin(), SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
+ m_document.frame()->navigationScheduler().scheduleLocationChange(m_document.securityOrigin(), SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
}
} // namespace WebCore
diff --git a/Source/WebCore/html/parser/XSSAuditorDelegate.h b/Source/WebCore/html/parser/XSSAuditorDelegate.h
index 82adb1f61..e12760e32 100644
--- a/Source/WebCore/html/parser/XSSAuditorDelegate.h
+++ b/Source/WebCore/html/parser/XSSAuditorDelegate.h
@@ -27,9 +27,10 @@
#define XSSAuditorDelegate_h
#include "URL.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/TextPosition.h>
-#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -38,15 +39,13 @@ class FormData;
class XSSInfo {
public:
- XSSInfo(const String& originalURL, bool didBlockEntirePage, bool didSendXSSProtectionHeader, bool didSendCSPHeader)
- : m_originalURL(originalURL.isolatedCopy())
- , m_didBlockEntirePage(didBlockEntirePage)
+ XSSInfo(bool didBlockEntirePage, bool didSendXSSProtectionHeader, bool didSendCSPHeader)
+ : m_didBlockEntirePage(didBlockEntirePage)
, m_didSendXSSProtectionHeader(didSendXSSProtectionHeader)
, m_didSendCSPHeader(didSendCSPHeader)
{
}
- String m_originalURL;
bool m_didBlockEntirePage;
bool m_didSendXSSProtectionHeader;
bool m_didSendCSPHeader;
@@ -62,7 +61,7 @@ public:
void setReportURL(const URL& url) { m_reportURL = url; }
private:
- PassRefPtr<FormData> generateViolationReport(const XSSInfo&);
+ PassRefPtr<FormData> generateViolationReport();
Document& m_document;
bool m_didSendNotifications;
diff --git a/Source/WebCore/html/shadow/AutoFillButtonElement.cpp b/Source/WebCore/html/shadow/AutoFillButtonElement.cpp
deleted file mode 100644
index 0931bcdd3..000000000
--- a/Source/WebCore/html/shadow/AutoFillButtonElement.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "AutoFillButtonElement.h"
-
-#include "Event.h"
-#include "EventNames.h"
-#include "HTMLNames.h"
-#include "MouseEvent.h"
-#include "TextFieldInputType.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-Ref<AutoFillButtonElement> AutoFillButtonElement::create(Document& document, AutoFillButtonOwner& owner)
-{
- return adoptRef(*new AutoFillButtonElement(document, owner));
-}
-
-AutoFillButtonElement::AutoFillButtonElement(Document& document, AutoFillButtonOwner& owner)
- : HTMLDivElement(divTag, document)
- , m_owner(owner)
-{
-}
-
-void AutoFillButtonElement::defaultEventHandler(Event* event)
-{
- if (!is<MouseEvent>(*event)) {
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
- return;
- }
-
- MouseEvent& mouseEvent = downcast<MouseEvent>(*event);
-
- if (mouseEvent.type() == eventNames().clickEvent) {
- m_owner.autoFillButtonElementWasClicked();
- event->setDefaultHandled();
- }
-
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/html/shadow/AutoFillButtonElement.h b/Source/WebCore/html/shadow/AutoFillButtonElement.h
deleted file mode 100644
index f416853a8..000000000
--- a/Source/WebCore/html/shadow/AutoFillButtonElement.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AutoFillButtonElement_h
-#define AutoFillButtonElement_h
-
-#include "HTMLDivElement.h"
-
-namespace WebCore {
-
-class TextFieldInputType;
-
-class AutoFillButtonElement final : public HTMLDivElement {
-public:
- class AutoFillButtonOwner {
- public:
- virtual ~AutoFillButtonOwner() { }
- virtual void autoFillButtonElementWasClicked() = 0;
- };
-
- static Ref<AutoFillButtonElement> create(Document&, AutoFillButtonOwner&);
-
-private:
- explicit AutoFillButtonElement(Document&, AutoFillButtonOwner&);
-
- virtual void defaultEventHandler(Event*) override;
-
- AutoFillButtonOwner& m_owner;
-};
-
-} // namespace WebCore
-
-#endif // AutoFillButtonElement_h
diff --git a/Source/WebCore/html/shadow/ContentDistributor.cpp b/Source/WebCore/html/shadow/ContentDistributor.cpp
index 8e867e81f..c4c77a747 100644
--- a/Source/WebCore/html/shadow/ContentDistributor.cpp
+++ b/Source/WebCore/html/shadow/ContentDistributor.cpp
@@ -56,8 +56,10 @@ const Vector<RefPtr<InsertionPoint>>& ContentDistributor::ensureInsertionPointLi
m_insertionPointListIsValid = true;
ASSERT(m_insertionPointList.isEmpty());
- for (auto& element : descendantsOfType<InsertionPoint>(*shadowRoot))
- m_insertionPointList.append(&element);
+ for (auto& element : descendantsOfType<Element>(*shadowRoot)) {
+ if (element.isInsertionPoint())
+ m_insertionPointList.append(toInsertionPoint(&element));
+ }
return m_insertionPointList;
}
diff --git a/Source/WebCore/html/shadow/DetailsMarkerControl.cpp b/Source/WebCore/html/shadow/DetailsMarkerControl.cpp
index 676b1ecff..a48e29f49 100644
--- a/Source/WebCore/html/shadow/DetailsMarkerControl.cpp
+++ b/Source/WebCore/html/shadow/DetailsMarkerControl.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -39,25 +38,32 @@
namespace WebCore {
-Ref<DetailsMarkerControl> DetailsMarkerControl::create(Document& document)
-{
- return adoptRef(*new DetailsMarkerControl(document));
-}
+using namespace HTMLNames;
DetailsMarkerControl::DetailsMarkerControl(Document& document)
- : HTMLDivElement(HTMLNames::divTag, document)
+ : HTMLDivElement(divTag, document)
{
- setPseudo(AtomicString("-webkit-details-marker", AtomicString::ConstructFromLiteral));
}
-RenderPtr<RenderElement> DetailsMarkerControl::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> DetailsMarkerControl::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderDetailsMarker>(*this, WTF::move(style));
+ return createRenderer<RenderDetailsMarker>(*this, std::move(style));
}
bool DetailsMarkerControl::rendererIsNeeded(const RenderStyle& style)
{
- return downcast<HTMLSummaryElement>(shadowHost())->isMainSummary() && HTMLDivElement::rendererIsNeeded(style);
+ return summaryElement()->isMainSummary() && HTMLDivElement::rendererIsNeeded(style);
+}
+
+const AtomicString& DetailsMarkerControl::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, pseudId, ("-webkit-details-marker", AtomicString::ConstructFromLiteral));
+ return pseudId;
+}
+
+HTMLSummaryElement* DetailsMarkerControl::summaryElement()
+{
+ return toHTMLSummaryElement(shadowHost());
}
}
diff --git a/Source/WebCore/html/shadow/DetailsMarkerControl.h b/Source/WebCore/html/shadow/DetailsMarkerControl.h
index 39717ab66..004dd10e3 100644
--- a/Source/WebCore/html/shadow/DetailsMarkerControl.h
+++ b/Source/WebCore/html/shadow/DetailsMarkerControl.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,20 +32,31 @@
#define DetailsMarkerControl_h
#include "HTMLDivElement.h"
+#include <wtf/Forward.h>
namespace WebCore {
+class HTMLSummaryElement;
+
class DetailsMarkerControl final : public HTMLDivElement {
public:
- static Ref<DetailsMarkerControl> create(Document&);
+ static PassRefPtr<DetailsMarkerControl> create(Document&);
private:
DetailsMarkerControl(Document&);
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual bool rendererIsNeeded(const RenderStyle&) override;
+ virtual const AtomicString& shadowPseudoId() const override;
+
+ HTMLSummaryElement* summaryElement();
};
+inline PassRefPtr<DetailsMarkerControl> DetailsMarkerControl::create(Document& document)
+{
+ return adoptRef(new DetailsMarkerControl(document));
+}
+
}
#endif
diff --git a/Source/WebCore/html/shadow/ImageControlsRootElement.cpp b/Source/WebCore/html/shadow/ImageControlsRootElement.cpp
deleted file mode 100644
index f178dfad8..000000000
--- a/Source/WebCore/html/shadow/ImageControlsRootElement.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ImageControlsRootElement.h"
-
-#if ENABLE(SERVICE_CONTROLS)
-
-namespace WebCore {
-
-#if !PLATFORM(MAC)
-Ref<ImageControlsRootElement> ImageControlsRootElement::maybeCreate(Document& document)
-{
- return adoptRef(*new ImageControlsRootElement(document));
-}
-#endif
-
-ImageControlsRootElement::ImageControlsRootElement(Document& document)
- : HTMLDivElement(HTMLNames::divTag, document)
-{
-}
-
-ImageControlsRootElement::~ImageControlsRootElement()
-{
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(SERVICE_CONTROLS)
diff --git a/Source/WebCore/html/shadow/ImageControlsRootElement.h b/Source/WebCore/html/shadow/ImageControlsRootElement.h
deleted file mode 100644
index 14c11579b..000000000
--- a/Source/WebCore/html/shadow/ImageControlsRootElement.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ImageControlsRootElement_h
-#define ImageControlsRootElement_h
-
-#if ENABLE(SERVICE_CONTROLS)
-
-#include "HTMLDivElement.h"
-
-namespace WebCore {
-
-class Document;
-
-class ImageControlsRootElement : public HTMLDivElement {
-public:
- virtual ~ImageControlsRootElement();
-
- static RefPtr<ImageControlsRootElement> maybeCreate(Document&);
-
-protected:
- explicit ImageControlsRootElement(Document&);
-
-private:
- virtual bool isImageControlsRootElement() const override final { return true; }
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(SERVICE_CONTROLS)
-#endif // ImageControlsRootElement_h
diff --git a/Source/WebCore/html/shadow/InsertionPoint.h b/Source/WebCore/html/shadow/InsertionPoint.h
index c63b72887..c7927d273 100644
--- a/Source/WebCore/html/shadow/InsertionPoint.h
+++ b/Source/WebCore/html/shadow/InsertionPoint.h
@@ -51,7 +51,7 @@ public:
bool hasDistribution() const { return m_hasDistribution; }
void setHasDistribution() { m_hasDistribution = true; }
void clearDistribution() { m_hasDistribution = false; }
- WEBCORE_EXPORT bool isActive() const;
+ bool isActive() const;
virtual MatchType matchTypeFor(Node*) const { return AlwaysMatches; }
@@ -68,16 +68,20 @@ protected:
virtual void childrenChanged(const ChildChange&) override;
virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
virtual void removedFrom(ContainerNode&) override;
+ virtual bool isInsertionPointNode() const override { return true; }
private:
- virtual bool isInsertionPointNode() const override final { return true; }
bool m_hasDistribution;
};
+inline bool isInsertionPoint(const Node& node) { return node.isInsertionPoint(); }
+
+NODE_TYPE_CASTS(InsertionPoint);
+
inline bool isActiveInsertionPoint(const Node* node)
{
- return is<InsertionPoint>(node) && downcast<InsertionPoint>(*node).isActive();
+ return node && node->isInsertionPoint() && toInsertionPoint(node)->isActive();
}
inline Node* parentNodeForDistribution(const Node* node)
@@ -85,22 +89,22 @@ inline Node* parentNodeForDistribution(const Node* node)
ASSERT(node);
if (Node* parent = node->parentNode()) {
- if (is<InsertionPoint>(*parent) && downcast<InsertionPoint>(*parent).shouldUseFallbackElements())
+ if (parent->isInsertionPoint() && toInsertionPoint(parent)->shouldUseFallbackElements())
return parent->parentNode();
return parent;
}
- return nullptr;
+ return 0;
}
inline Element* parentElementForDistribution(const Node* node)
{
if (Node* parent = parentNodeForDistribution(node)) {
- if (is<Element>(*parent))
- return downcast<Element>(parent);
+ if (parent->isElementNode())
+ return toElement(parent);
}
- return nullptr;
+ return 0;
}
inline ShadowRoot* shadowRootOfParentForDistribution(const Node* node)
@@ -109,7 +113,7 @@ inline ShadowRoot* shadowRootOfParentForDistribution(const Node* node)
if (Element* parent = parentElementForDistribution(node))
return parent->shadowRoot();
- return nullptr;
+ return 0;
}
InsertionPoint* findInsertionPointOf(const Node*);
@@ -123,8 +127,4 @@ inline bool hasShadowRootOrActiveInsertionPointParent(const Node& node)
} // namespace WebCore
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::InsertionPoint)
- static bool isType(const WebCore::Node& node) { return node.isInsertionPoint(); }
-SPECIALIZE_TYPE_TRAITS_END()
-
#endif // InsertionPoint_h
diff --git a/Source/WebCore/html/shadow/MediaControlElementTypes.cpp b/Source/WebCore/html/shadow/MediaControlElementTypes.cpp
index 6d95f3433..d6049a508 100644
--- a/Source/WebCore/html/shadow/MediaControlElementTypes.cpp
+++ b/Source/WebCore/html/shadow/MediaControlElementTypes.cpp
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -46,6 +46,12 @@ using namespace HTMLNames;
class Event;
+// FIXME: These constants may need to be tweaked to better match the seeking in the QuickTime plug-in.
+static const double cSkipRepeatDelay = 0.1;
+static const double cSkipTime = 0.2;
+static const double cScanRepeatDelay = 1.5;
+static const double cScanMaximumRate = 8;
+
HTMLMediaElement* parentMediaElement(Node* node)
{
if (!node)
@@ -53,17 +59,18 @@ HTMLMediaElement* parentMediaElement(Node* node)
Node* mediaNode = node->shadowHost();
if (!mediaNode)
mediaNode = node;
- if (!is<HTMLMediaElement>(*mediaNode))
+ if (!mediaNode->isElementNode() || !toElement(mediaNode)->isMediaElement())
return nullptr;
- return downcast<HTMLMediaElement>(mediaNode);
+ return toHTMLMediaElement(mediaNode);
}
MediaControlElementType mediaControlElementType(Node* node)
{
ASSERT_WITH_SECURITY_IMPLICATION(node->isMediaControlElement());
- if (is<HTMLInputElement>(*node))
- return static_cast<MediaControlInputElement*>(node)->displayType();
- return static_cast<MediaControlDivElement*>(node)->displayType();
+ HTMLElement* element = toHTMLElement(node);
+ if (isHTMLInputElement(element))
+ return static_cast<MediaControlInputElement*>(element)->displayType();
+ return static_cast<MediaControlDivElement*>(element)->displayType();
}
MediaControlElement::MediaControlElement(MediaControlElementType displayType, HTMLElement* element)
@@ -161,6 +168,9 @@ void MediaControlMuteButtonElement::updateDisplayType()
MediaControlSeekButtonElement::MediaControlSeekButtonElement(Document& document, MediaControlElementType displayType)
: MediaControlInputElement(document, displayType)
+ , m_actionOnStop(Nothing)
+ , m_seekType(Skip)
+ , m_seekTimer(this, &MediaControlSeekButtonElement::seekTimerFired)
{
}
@@ -178,13 +188,62 @@ void MediaControlSeekButtonElement::setActive(bool flag, bool pause)
return;
if (flag)
- mediaController()->beginScanning(isForwardButton() ? MediaControllerInterface::Forward : MediaControllerInterface::Backward);
+ startTimer();
else
- mediaController()->endScanning();
+ stopTimer();
MediaControlInputElement::setActive(flag, pause);
}
+void MediaControlSeekButtonElement::startTimer()
+{
+ m_seekType = mediaController()->supportsScanning() ? Scan : Skip;
+
+ if (m_seekType == Skip) {
+ // Seeking by skipping requires the video to be paused during seeking.
+ m_actionOnStop = mediaController()->paused() ? Nothing : Play;
+ mediaController()->pause();
+ } else {
+ // Seeking by scanning requires the video to be playing during seeking.
+ m_actionOnStop = mediaController()->paused() ? Pause : Nothing;
+ mediaController()->play();
+ mediaController()->setPlaybackRate(nextRate());
+ }
+
+ m_seekTimer.start(0, m_seekType == Skip ? cSkipRepeatDelay : cScanRepeatDelay);
+}
+
+void MediaControlSeekButtonElement::stopTimer()
+{
+ if (m_seekType == Scan)
+ mediaController()->setPlaybackRate(mediaController()->defaultPlaybackRate());
+
+ if (m_actionOnStop == Play)
+ mediaController()->play();
+ else if (m_actionOnStop == Pause)
+ mediaController()->pause();
+
+ if (m_seekTimer.isActive())
+ m_seekTimer.stop();
+}
+
+double MediaControlSeekButtonElement::nextRate() const
+{
+ double rate = std::min(cScanMaximumRate, fabs(mediaController()->playbackRate() * 2));
+ if (!isForwardButton())
+ rate *= -1;
+ return rate;
+}
+
+void MediaControlSeekButtonElement::seekTimerFired(Timer<MediaControlSeekButtonElement>&)
+{
+ if (m_seekType == Skip) {
+ double skipTime = isForwardButton() ? cSkipTime : -cSkipTime;
+ mediaController()->setCurrentTime(mediaController()->currentTime() + skipTime);
+ } else
+ mediaController()->setPlaybackRate(nextRate());
+}
+
// ----------------------------
MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document& document)
@@ -196,7 +255,7 @@ MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document& docum
void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
{
// Left button is 0. Rejects mouse events not from left button.
- if (is<MouseEvent>(*event) && downcast<MouseEvent>(*event).button())
+ if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
return;
if (!renderer())
diff --git a/Source/WebCore/html/shadow/MediaControlElementTypes.h b/Source/WebCore/html/shadow/MediaControlElementTypes.h
index 00f04a37e..d4e4c07aa 100644
--- a/Source/WebCore/html/shadow/MediaControlElementTypes.h
+++ b/Source/WebCore/html/shadow/MediaControlElementTypes.h
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -75,7 +75,7 @@ enum MediaControlElementType {
};
HTMLMediaElement* parentMediaElement(Node*);
-inline HTMLMediaElement* parentMediaElement(const RenderObject& renderer) { return parentMediaElement(renderer.node()); }
+inline HTMLMediaElement* parentMediaElement(RenderObject& renderer) { return parentMediaElement(renderer.node()); }
MediaControlElementType mediaControlElementType(Node*);
@@ -88,6 +88,7 @@ public:
virtual bool isShowing() const;
virtual MediaControlElementType displayType() { return m_displayType; }
+ virtual const AtomicString& shadowPseudoId() const = 0;
virtual void setMediaController(MediaControllerInterface* controller) { m_mediaController = controller; }
virtual MediaControllerInterface* mediaController() const { return m_mediaController; }
@@ -109,20 +110,18 @@ private:
class MediaControlDivElement : public HTMLDivElement, public MediaControlElement {
protected:
+ virtual bool isMediaControlElement() const override { return MediaControlElement::isMediaControlElement(); }
explicit MediaControlDivElement(Document&, MediaControlElementType);
-
-private:
- virtual bool isMediaControlElement() const override final { return MediaControlElement::isMediaControlElement(); }
};
// ----------------------------
class MediaControlInputElement : public HTMLInputElement, public MediaControlElement {
protected:
+ virtual bool isMediaControlElement() const override { return MediaControlElement::isMediaControlElement(); }
explicit MediaControlInputElement(Document&, MediaControlElementType);
private:
- virtual bool isMediaControlElement() const override final { return MediaControlElement::isMediaControlElement(); }
virtual void updateDisplayType() { }
};
@@ -171,6 +170,17 @@ protected:
private:
virtual void setActive(bool /*flag*/ = true, bool /*pause*/ = false) override final;
+
+ void startTimer();
+ void stopTimer();
+ double nextRate() const;
+ void seekTimerFired(Timer<MediaControlSeekButtonElement>&);
+
+ enum ActionType { Nothing, Play, Pause };
+ ActionType m_actionOnStop;
+ enum SeekType { Skip, Scan };
+ SeekType m_seekType;
+ Timer<MediaControlSeekButtonElement> m_seekTimer;
};
// ----------------------------
diff --git a/Source/WebCore/html/shadow/MediaControlElements.cpp b/Source/WebCore/html/shadow/MediaControlElements.cpp
index 9cad8eed6..91df2d97b 100644
--- a/Source/WebCore/html/shadow/MediaControlElements.cpp
+++ b/Source/WebCore/html/shadow/MediaControlElements.cpp
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -33,7 +33,6 @@
#include "MediaControlElements.h"
#include "DOMTokenList.h"
-#include "ElementChildIterator.h"
#include "EventHandler.h"
#include "EventNames.h"
#include "ExceptionCodePlaceholder.h"
@@ -43,7 +42,6 @@
#include "ImageBuffer.h"
#include "Language.h"
#include "LocalizedStrings.h"
-#include "Logging.h"
#include "MediaControls.h"
#include "PageGroup.h"
#include "RenderLayer.h"
@@ -57,8 +55,8 @@
#include "TextTrackList.h"
#endif
-#if ENABLE(WEBVTT_REGIONS)
-#include "VTTRegionList.h"
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "RenderWidget.h"
#endif
namespace WebCore {
@@ -74,14 +72,19 @@ MediaControlPanelElement::MediaControlPanelElement(Document& document)
, m_isBeingDragged(false)
, m_isDisplayed(false)
, m_opaque(true)
- , m_transitionTimer(*this, &MediaControlPanelElement::transitionTimerFired)
+ , m_transitionTimer(this, &MediaControlPanelElement::transitionTimerFired)
{
- setPseudo(AtomicString("-webkit-media-controls-panel", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlPanelElement> MediaControlPanelElement::create(Document& document)
+PassRefPtr<MediaControlPanelElement> MediaControlPanelElement::create(Document& document)
{
- return adoptRef(*new MediaControlPanelElement(document));
+ return adoptRef(new MediaControlPanelElement(document));
+}
+
+const AtomicString& MediaControlPanelElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-panel", AtomicString::ConstructFromLiteral));
+ return id;
}
void MediaControlPanelElement::startDrag(const LayoutPoint& eventLocation)
@@ -149,7 +152,7 @@ void MediaControlPanelElement::stopTimer()
m_transitionTimer.stop();
}
-void MediaControlPanelElement::transitionTimerFired()
+void MediaControlPanelElement::transitionTimerFired(Timer<MediaControlPanelElement>&)
{
if (!m_opaque)
hide();
@@ -169,7 +172,7 @@ void MediaControlPanelElement::setPosition(const LayoutPoint& position)
setInlineStyleProperty(CSSPropertyMarginLeft, 0.0, CSSPrimitiveValue::CSS_PX);
setInlineStyleProperty(CSSPropertyMarginTop, 0.0, CSSPrimitiveValue::CSS_PX);
- classList().add("dragged", IGNORE_EXCEPTION);
+ classList()->add("dragged", IGNORE_EXCEPTION);
}
void MediaControlPanelElement::resetPosition()
@@ -179,7 +182,7 @@ void MediaControlPanelElement::resetPosition()
removeInlineStyleProperty(CSSPropertyMarginLeft);
removeInlineStyleProperty(CSSPropertyMarginTop);
- classList().remove("dragged", IGNORE_EXCEPTION);
+ classList()->remove("dragged", IGNORE_EXCEPTION);
m_cumulativeDragOffset.setX(0);
m_cumulativeDragOffset.setY(0);
@@ -221,8 +224,8 @@ void MediaControlPanelElement::defaultEventHandler(Event* event)
{
MediaControlDivElement::defaultEventHandler(event);
- if (is<MouseEvent>(*event)) {
- LayoutPoint location = downcast<MouseEvent>(*event).absoluteLocation();
+ if (event->isMouseEvent()) {
+ LayoutPoint location = static_cast<MouseEvent*>(event)->absoluteLocation();
if (event->type() == eventNames().mousedownEvent && event->target() == this) {
startDrag(location);
event->setDefaultHandled();
@@ -258,12 +261,17 @@ MediaControlPanelEnclosureElement::MediaControlPanelEnclosureElement(Document& d
// Mapping onto same MediaControlElementType as panel element, since it has similar properties.
: MediaControlDivElement(document, MediaControlsPanel)
{
- setPseudo(AtomicString("-webkit-media-controls-enclosure", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlPanelEnclosureElement> MediaControlPanelEnclosureElement::create(Document& document)
+PassRefPtr<MediaControlPanelEnclosureElement> MediaControlPanelEnclosureElement::create(Document& document)
{
- return adoptRef(*new MediaControlPanelEnclosureElement(document));
+ return adoptRef(new MediaControlPanelEnclosureElement(document));
+}
+
+const AtomicString& MediaControlPanelEnclosureElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-enclosure", AtomicString::ConstructFromLiteral));
+ return id;
}
// ----------------------------
@@ -272,12 +280,17 @@ MediaControlOverlayEnclosureElement::MediaControlOverlayEnclosureElement(Documen
// Mapping onto same MediaControlElementType as panel element, since it has similar properties.
: MediaControlDivElement(document, MediaControlsPanel)
{
- setPseudo(AtomicString("-webkit-media-controls-overlay-enclosure", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlOverlayEnclosureElement> MediaControlOverlayEnclosureElement::create(Document& document)
+PassRefPtr<MediaControlOverlayEnclosureElement> MediaControlOverlayEnclosureElement::create(Document& document)
+{
+ return adoptRef(new MediaControlOverlayEnclosureElement(document));
+}
+
+const AtomicString& MediaControlOverlayEnclosureElement::shadowPseudoId() const
{
- return adoptRef(*new MediaControlOverlayEnclosureElement(document));
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-overlay-enclosure", AtomicString::ConstructFromLiteral));
+ return id;
}
// ----------------------------
@@ -285,34 +298,43 @@ Ref<MediaControlOverlayEnclosureElement> MediaControlOverlayEnclosureElement::cr
MediaControlTimelineContainerElement::MediaControlTimelineContainerElement(Document& document)
: MediaControlDivElement(document, MediaTimelineContainer)
{
- setPseudo(AtomicString("-webkit-media-controls-timeline-container", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlTimelineContainerElement> MediaControlTimelineContainerElement::create(Document& document)
+PassRefPtr<MediaControlTimelineContainerElement> MediaControlTimelineContainerElement::create(Document& document)
{
- Ref<MediaControlTimelineContainerElement> element = adoptRef(*new MediaControlTimelineContainerElement(document));
+ RefPtr<MediaControlTimelineContainerElement> element = adoptRef(new MediaControlTimelineContainerElement(document));
element->hide();
- return element;
+ return element.release();
+}
+
+const AtomicString& MediaControlTimelineContainerElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline-container", AtomicString::ConstructFromLiteral));
+ return id;
}
void MediaControlTimelineContainerElement::setTimeDisplaysHidden(bool hidden)
{
- for (auto& element : childrenOfType<Element>(*this)) {
- if (element.shadowPseudoId() != getMediaControlTimeRemainingDisplayElementShadowPseudoId()
- && element.shadowPseudoId() != getMediaControlCurrentTimeDisplayElementShadowPseudoId())
+ for (unsigned i = 0; i < childNodeCount(); ++i) {
+ Node* child = childNode(i);
+ if (!child || !child->isElementNode())
+ continue;
+ Element* element = toElement(child);
+ if (element->shadowPseudoId() != getMediaControlTimeRemainingDisplayElementShadowPseudoId()
+ && element->shadowPseudoId() != getMediaControlCurrentTimeDisplayElementShadowPseudoId())
continue;
- MediaControlTimeDisplayElement& timeDisplay = static_cast<MediaControlTimeDisplayElement&>(element);
+ MediaControlTimeDisplayElement* timeDisplay = static_cast<MediaControlTimeDisplayElement*>(element);
if (hidden)
- timeDisplay.hide();
+ timeDisplay->hide();
else
- timeDisplay.show();
+ timeDisplay->show();
}
}
-RenderPtr<RenderElement> MediaControlTimelineContainerElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> MediaControlTimelineContainerElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderMediaControlTimelineContainer>(*this, WTF::move(style));
+ return createRenderer<RenderMediaControlTimelineContainer>(*this, std::move(style));
}
// ----------------------------
@@ -320,29 +342,28 @@ RenderPtr<RenderElement> MediaControlTimelineContainerElement::createElementRend
MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement(Document& document)
: MediaControlDivElement(document, MediaVolumeSliderContainer)
{
- setPseudo(AtomicString("-webkit-media-controls-volume-slider-container", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlVolumeSliderContainerElement> MediaControlVolumeSliderContainerElement::create(Document& document)
+PassRefPtr<MediaControlVolumeSliderContainerElement> MediaControlVolumeSliderContainerElement::create(Document& document)
{
- Ref<MediaControlVolumeSliderContainerElement> element = adoptRef(*new MediaControlVolumeSliderContainerElement(document));
+ RefPtr<MediaControlVolumeSliderContainerElement> element = adoptRef(new MediaControlVolumeSliderContainerElement(document));
element->hide();
- return element;
+ return element.release();
}
-RenderPtr<RenderElement> MediaControlVolumeSliderContainerElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> MediaControlVolumeSliderContainerElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderMediaVolumeSliderContainer>(*this, WTF::move(style));
+ return createRenderer<RenderMediaVolumeSliderContainer>(*this, std::move(style));
}
void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event* event)
{
- if (!is<MouseEvent>(*event) || event->type() != eventNames().mouseoutEvent)
+ if (!event->isMouseEvent() || event->type() != eventNames().mouseoutEvent)
return;
// Poor man's mouseleave event detection.
- MouseEvent& mouseEvent = downcast<MouseEvent>(*event);
- EventTarget* relatedTarget = mouseEvent.relatedTarget();
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ EventTarget* relatedTarget = mouseEvent->relatedTarget();
if (!relatedTarget || !relatedTarget->toNode())
return;
@@ -352,20 +373,25 @@ void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event* event)
hide();
}
+const AtomicString& MediaControlVolumeSliderContainerElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider-container", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
// ----------------------------
MediaControlStatusDisplayElement::MediaControlStatusDisplayElement(Document& document)
: MediaControlDivElement(document, MediaStatusDisplay)
, m_stateBeingDisplayed(Nothing)
{
- setPseudo(AtomicString("-webkit-media-controls-status-display", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlStatusDisplayElement> MediaControlStatusDisplayElement::create(Document& document)
+PassRefPtr<MediaControlStatusDisplayElement> MediaControlStatusDisplayElement::create(Document& document)
{
- Ref<MediaControlStatusDisplayElement> element = adoptRef(*new MediaControlStatusDisplayElement(document));
+ RefPtr<MediaControlStatusDisplayElement> element = adoptRef(new MediaControlStatusDisplayElement(document));
element->hide();
- return element;
+ return element.release();
}
void MediaControlStatusDisplayElement::update()
@@ -401,23 +427,29 @@ void MediaControlStatusDisplayElement::update()
}
}
+const AtomicString& MediaControlStatusDisplayElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-status-display", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
+
// ----------------------------
MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(Document& document, MediaControls* controls)
: MediaControlMuteButtonElement(document, MediaMuteButton)
, m_controls(controls)
{
- setPseudo(AtomicString("-webkit-media-controls-mute-button", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(Document& document, MediaControls* controls)
+PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(Document& document, MediaControls* controls)
{
ASSERT(controls);
- Ref<MediaControlPanelMuteButtonElement> button = adoptRef(*new MediaControlPanelMuteButtonElement(document, controls));
+ RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(document, controls));
button->ensureUserAgentShadowRoot();
button->setType("button");
- return button;
+ return button.release();
}
void MediaControlPanelMuteButtonElement::defaultEventHandler(Event* event)
@@ -428,20 +460,31 @@ void MediaControlPanelMuteButtonElement::defaultEventHandler(Event* event)
MediaControlMuteButtonElement::defaultEventHandler(event);
}
+const AtomicString& MediaControlPanelMuteButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
// ----------------------------
MediaControlVolumeSliderMuteButtonElement::MediaControlVolumeSliderMuteButtonElement(Document& document)
: MediaControlMuteButtonElement(document, MediaMuteButton)
{
- setPseudo(AtomicString("-webkit-media-controls-volume-slider-mute-button", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlVolumeSliderMuteButtonElement> MediaControlVolumeSliderMuteButtonElement::create(Document& document)
+PassRefPtr<MediaControlVolumeSliderMuteButtonElement> MediaControlVolumeSliderMuteButtonElement::create(Document& document)
{
- Ref<MediaControlVolumeSliderMuteButtonElement> button = adoptRef(*new MediaControlVolumeSliderMuteButtonElement(document));
+ RefPtr<MediaControlVolumeSliderMuteButtonElement> button = adoptRef(new MediaControlVolumeSliderMuteButtonElement(document));
button->ensureUserAgentShadowRoot();
button->setType("button");
- return button;
+ return button.release();
+}
+
+const AtomicString& MediaControlVolumeSliderMuteButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider-mute-button", AtomicString::ConstructFromLiteral));
+ return id;
}
// ----------------------------
@@ -449,15 +492,14 @@ Ref<MediaControlVolumeSliderMuteButtonElement> MediaControlVolumeSliderMuteButto
MediaControlPlayButtonElement::MediaControlPlayButtonElement(Document& document)
: MediaControlInputElement(document, MediaPlayButton)
{
- setPseudo(AtomicString("-webkit-media-controls-play-button", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(Document& document)
+PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(Document& document)
{
- Ref<MediaControlPlayButtonElement> button = adoptRef(*new MediaControlPlayButtonElement(document));
+ RefPtr<MediaControlPlayButtonElement> button = adoptRef(new MediaControlPlayButtonElement(document));
button->ensureUserAgentShadowRoot();
button->setType("button");
- return button;
+ return button.release();
}
void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
@@ -478,20 +520,25 @@ void MediaControlPlayButtonElement::updateDisplayType()
setDisplayType(mediaController()->canPlay() ? MediaPlayButton : MediaPauseButton);
}
+const AtomicString& MediaControlPlayButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-play-button", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
// ----------------------------
MediaControlOverlayPlayButtonElement::MediaControlOverlayPlayButtonElement(Document& document)
: MediaControlInputElement(document, MediaOverlayPlayButton)
{
- setPseudo(AtomicString("-webkit-media-controls-overlay-play-button", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonElement::create(Document& document)
+PassRefPtr<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonElement::create(Document& document)
{
- Ref<MediaControlOverlayPlayButtonElement> button = adoptRef(*new MediaControlOverlayPlayButtonElement(document));
+ RefPtr<MediaControlOverlayPlayButtonElement> button = adoptRef(new MediaControlOverlayPlayButtonElement(document));
button->ensureUserAgentShadowRoot();
button->setType("button");
- return button;
+ return button.release();
}
void MediaControlOverlayPlayButtonElement::defaultEventHandler(Event* event)
@@ -512,20 +559,32 @@ void MediaControlOverlayPlayButtonElement::updateDisplayType()
hide();
}
+const AtomicString& MediaControlOverlayPlayButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-overlay-play-button", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
+
// ----------------------------
MediaControlSeekForwardButtonElement::MediaControlSeekForwardButtonElement(Document& document)
: MediaControlSeekButtonElement(document, MediaSeekForwardButton)
{
- setPseudo(AtomicString("-webkit-media-controls-seek-forward-button", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlSeekForwardButtonElement> MediaControlSeekForwardButtonElement::create(Document& document)
+PassRefPtr<MediaControlSeekForwardButtonElement> MediaControlSeekForwardButtonElement::create(Document& document)
{
- Ref<MediaControlSeekForwardButtonElement> button = adoptRef(*new MediaControlSeekForwardButtonElement(document));
+ RefPtr<MediaControlSeekForwardButtonElement> button = adoptRef(new MediaControlSeekForwardButtonElement(document));
button->ensureUserAgentShadowRoot();
button->setType("button");
- return button;
+ return button.release();
+}
+
+const AtomicString& MediaControlSeekForwardButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-seek-forward-button", AtomicString::ConstructFromLiteral));
+ return id;
}
// ----------------------------
@@ -533,15 +592,20 @@ Ref<MediaControlSeekForwardButtonElement> MediaControlSeekForwardButtonElement::
MediaControlSeekBackButtonElement::MediaControlSeekBackButtonElement(Document& document)
: MediaControlSeekButtonElement(document, MediaSeekBackButton)
{
- setPseudo(AtomicString("-webkit-media-controls-seek-back-button", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlSeekBackButtonElement> MediaControlSeekBackButtonElement::create(Document& document)
+PassRefPtr<MediaControlSeekBackButtonElement> MediaControlSeekBackButtonElement::create(Document& document)
{
- Ref<MediaControlSeekBackButtonElement> button = adoptRef(*new MediaControlSeekBackButtonElement(document));
+ RefPtr<MediaControlSeekBackButtonElement> button = adoptRef(new MediaControlSeekBackButtonElement(document));
button->ensureUserAgentShadowRoot();
button->setType("button");
- return button;
+ return button.release();
+}
+
+const AtomicString& MediaControlSeekBackButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-seek-back-button", AtomicString::ConstructFromLiteral));
+ return id;
}
// ----------------------------
@@ -549,15 +613,14 @@ Ref<MediaControlSeekBackButtonElement> MediaControlSeekBackButtonElement::create
MediaControlRewindButtonElement::MediaControlRewindButtonElement(Document& document)
: MediaControlInputElement(document, MediaRewindButton)
{
- setPseudo(AtomicString("-webkit-media-controls-rewind-button", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlRewindButtonElement> MediaControlRewindButtonElement::create(Document& document)
+PassRefPtr<MediaControlRewindButtonElement> MediaControlRewindButtonElement::create(Document& document)
{
- Ref<MediaControlRewindButtonElement> button = adoptRef(*new MediaControlRewindButtonElement(document));
+ RefPtr<MediaControlRewindButtonElement> button = adoptRef(new MediaControlRewindButtonElement(document));
button->ensureUserAgentShadowRoot();
button->setType("button");
- return button;
+ return button.release();
}
void MediaControlRewindButtonElement::defaultEventHandler(Event* event)
@@ -569,21 +632,26 @@ void MediaControlRewindButtonElement::defaultEventHandler(Event* event)
HTMLInputElement::defaultEventHandler(event);
}
+const AtomicString& MediaControlRewindButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-rewind-button", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
// ----------------------------
MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement(Document& document)
: MediaControlInputElement(document, MediaReturnToRealtimeButton)
{
- setPseudo(AtomicString("-webkit-media-controls-return-to-realtime-button", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlReturnToRealtimeButtonElement> MediaControlReturnToRealtimeButtonElement::create(Document& document)
+PassRefPtr<MediaControlReturnToRealtimeButtonElement> MediaControlReturnToRealtimeButtonElement::create(Document& document)
{
- Ref<MediaControlReturnToRealtimeButtonElement> button = adoptRef(*new MediaControlReturnToRealtimeButtonElement(document));
+ RefPtr<MediaControlReturnToRealtimeButtonElement> button = adoptRef(new MediaControlReturnToRealtimeButtonElement(document));
button->ensureUserAgentShadowRoot();
button->setType("button");
button->hide();
- return button;
+ return button.release();
}
void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event)
@@ -595,29 +663,34 @@ void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event
HTMLInputElement::defaultEventHandler(event);
}
+const AtomicString& MediaControlReturnToRealtimeButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-return-to-realtime-button", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
// ----------------------------
MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document& document, MediaControls* controls)
: MediaControlInputElement(document, MediaShowClosedCaptionsButton)
-#if PLATFORM(COCOA) || PLATFORM(WIN) || PLATFORM(GTK)
+#if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK)
, m_controls(controls)
#endif
{
-#if !PLATFORM(COCOA) && !PLATFORM(WIN) || !PLATFORM(GTK)
+#if !PLATFORM(MAC) && !PLATFORM(WIN) || !PLATFORM(GTK)
UNUSED_PARAM(controls);
#endif
- setPseudo(AtomicString("-webkit-media-controls-toggle-closed-captions-button", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(Document& document, MediaControls* controls)
+PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(Document& document, MediaControls* controls)
{
ASSERT(controls);
- Ref<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(*new MediaControlToggleClosedCaptionsButtonElement(document, controls));
+ RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(document, controls));
button->ensureUserAgentShadowRoot();
button->setType("button");
button->hide();
- return button;
+ return button.release();
}
void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
@@ -634,7 +707,7 @@ void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e
// UI. Not all ports may want the closed captions button to toggle a list of tracks, so
// we have to use #if.
// https://bugs.webkit.org/show_bug.cgi?id=101877
-#if !PLATFORM(COCOA) && !PLATFORM(WIN) && !PLATFORM(GTK)
+#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(GTK)
mediaController()->setClosedCaptionsVisible(!mediaController()->closedCaptionsVisible());
setChecked(mediaController()->closedCaptionsVisible());
updateDisplayType();
@@ -647,20 +720,31 @@ void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e
HTMLInputElement::defaultEventHandler(event);
}
+const AtomicString& MediaControlToggleClosedCaptionsButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-toggle-closed-captions-button", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
// ----------------------------
MediaControlClosedCaptionsContainerElement::MediaControlClosedCaptionsContainerElement(Document& document)
: MediaControlDivElement(document, MediaClosedCaptionsContainer)
{
- setPseudo(AtomicString("-webkit-media-controls-closed-captions-container", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlClosedCaptionsContainerElement> MediaControlClosedCaptionsContainerElement::create(Document& document)
+PassRefPtr<MediaControlClosedCaptionsContainerElement> MediaControlClosedCaptionsContainerElement::create(Document& document)
{
- Ref<MediaControlClosedCaptionsContainerElement> element = adoptRef(*new MediaControlClosedCaptionsContainerElement(document));
+ RefPtr<MediaControlClosedCaptionsContainerElement> element = adoptRef(new MediaControlClosedCaptionsContainerElement(document));
element->setAttribute(dirAttr, "auto");
element->hide();
- return element;
+ return element.release();
+}
+
+const AtomicString& MediaControlClosedCaptionsContainerElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-closed-captions-container", AtomicString::ConstructFromLiteral));
+ return id;
}
// ----------------------------
@@ -674,14 +758,13 @@ MediaControlClosedCaptionsTrackListElement::MediaControlClosedCaptionsTrackListE
#if !ENABLE(VIDEO_TRACK)
UNUSED_PARAM(controls);
#endif
- setPseudo(AtomicString("-webkit-media-controls-closed-captions-track-list", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlClosedCaptionsTrackListElement> MediaControlClosedCaptionsTrackListElement::create(Document& document, MediaControls* controls)
+PassRefPtr<MediaControlClosedCaptionsTrackListElement> MediaControlClosedCaptionsTrackListElement::create(Document& document, MediaControls* controls)
{
ASSERT(controls);
- Ref<MediaControlClosedCaptionsTrackListElement> element = adoptRef(*new MediaControlClosedCaptionsTrackListElement(document, controls));
- return element;
+ RefPtr<MediaControlClosedCaptionsTrackListElement> element = adoptRef(new MediaControlClosedCaptionsTrackListElement(document, controls));
+ return element.release();
}
void MediaControlClosedCaptionsTrackListElement::defaultEventHandler(Event* event)
@@ -689,7 +772,7 @@ void MediaControlClosedCaptionsTrackListElement::defaultEventHandler(Event* even
#if ENABLE(VIDEO_TRACK)
if (event->type() == eventNames().clickEvent) {
Node* target = event->target()->toNode();
- if (!is<Element>(target))
+ if (!target || !target->isElementNode())
return;
// When we created the elements in the track list, we gave them a custom
@@ -698,7 +781,7 @@ void MediaControlClosedCaptionsTrackListElement::defaultEventHandler(Event* even
// tell the HTMLMediaElement to enable that track.
RefPtr<TextTrack> textTrack;
- MenuItemToTrackMap::iterator iter = m_menuToTrackMap.find(downcast<Element>(target));
+ MenuItemToTrackMap::iterator iter = m_menuToTrackMap.find(toElement(target));
if (iter != m_menuToTrackMap.end())
textTrack = iter->value;
m_menuToTrackMap.clear();
@@ -721,10 +804,16 @@ void MediaControlClosedCaptionsTrackListElement::defaultEventHandler(Event* even
#endif
}
+const AtomicString& MediaControlClosedCaptionsTrackListElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-closed-captions-track-list", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
void MediaControlClosedCaptionsTrackListElement::updateDisplay()
{
#if ENABLE(VIDEO_TRACK)
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, selectedClassValue, ("selected", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, selectedClassValue, ("selected", AtomicString::ConstructFromLiteral));
if (!mediaController()->hasClosedCaptions())
return;
@@ -764,24 +853,24 @@ void MediaControlClosedCaptionsTrackListElement::updateDisplay()
if (textTrack == TextTrack::captionMenuAutomaticItem()) {
if (displayMode == CaptionUserPreferences::Automatic)
- trackItem->classList().add(selectedClassValue, ASSERT_NO_EXCEPTION);
+ trackItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION);
else
- trackItem->classList().remove(selectedClassValue, ASSERT_NO_EXCEPTION);
+ trackItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION);
continue;
}
if (displayMode != CaptionUserPreferences::Automatic && textTrack->mode() == TextTrack::showingKeyword()) {
trackMenuItemSelected = true;
- trackItem->classList().add(selectedClassValue, ASSERT_NO_EXCEPTION);
+ trackItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION);
} else
- trackItem->classList().remove(selectedClassValue, ASSERT_NO_EXCEPTION);
+ trackItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION);
}
if (offMenuItem) {
if (displayMode == CaptionUserPreferences::ForcedOnly && !trackMenuItemSelected)
- offMenuItem->classList().add(selectedClassValue, ASSERT_NO_EXCEPTION);
+ offMenuItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION);
else
- offMenuItem->classList().remove(selectedClassValue, ASSERT_NO_EXCEPTION);
+ offMenuItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION);
}
#endif
}
@@ -834,24 +923,23 @@ MediaControlTimelineElement::MediaControlTimelineElement(Document& document, Med
: MediaControlInputElement(document, MediaSlider)
, m_controls(controls)
{
- setPseudo(AtomicString("-webkit-media-controls-timeline", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlTimelineElement> MediaControlTimelineElement::create(Document& document, MediaControls* controls)
+PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(Document& document, MediaControls* controls)
{
ASSERT(controls);
- Ref<MediaControlTimelineElement> timeline = adoptRef(*new MediaControlTimelineElement(document, controls));
+ RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(document, controls));
timeline->ensureUserAgentShadowRoot();
timeline->setType("range");
timeline->setAttribute(precisionAttr, "float");
- return timeline;
+ return timeline.release();
}
void MediaControlTimelineElement::defaultEventHandler(Event* event)
{
// Left button is 0. Rejects mouse events not from left button.
- if (is<MouseEvent>(*event) && downcast<MouseEvent>(*event).button())
+ if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
return;
if (!renderer())
@@ -872,8 +960,8 @@ void MediaControlTimelineElement::defaultEventHandler(Event* event)
if (event->type() == eventNames().inputEvent && time != mediaController()->currentTime())
mediaController()->setCurrentTime(time);
- RenderSlider& slider = downcast<RenderSlider>(*renderer());
- if (slider.inDragMode())
+ RenderSlider* slider = toRenderSlider(renderer());
+ if (slider && slider->inDragMode())
m_controls->updateCurrentTimeDisplay();
}
@@ -897,22 +985,34 @@ void MediaControlTimelineElement::setDuration(double duration)
setAttribute(maxAttr, AtomicString::number(std::isfinite(duration) ? duration : 0));
}
+
+const AtomicString& MediaControlTimelineElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
// ----------------------------
MediaControlPanelVolumeSliderElement::MediaControlPanelVolumeSliderElement(Document& document)
: MediaControlVolumeSliderElement(document)
{
- setPseudo(AtomicString("-webkit-media-controls-volume-slider", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlPanelVolumeSliderElement> MediaControlPanelVolumeSliderElement::create(Document& document)
+PassRefPtr<MediaControlPanelVolumeSliderElement> MediaControlPanelVolumeSliderElement::create(Document& document)
{
- Ref<MediaControlPanelVolumeSliderElement> slider = adoptRef(*new MediaControlPanelVolumeSliderElement(document));
+ RefPtr<MediaControlPanelVolumeSliderElement> slider = adoptRef(new MediaControlPanelVolumeSliderElement(document));
slider->ensureUserAgentShadowRoot();
slider->setType("range");
slider->setAttribute(precisionAttr, "float");
slider->setAttribute(maxAttr, "1");
- return slider;
+ return slider.release();
+}
+
+const AtomicString& MediaControlPanelVolumeSliderElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider", AtomicString::ConstructFromLiteral));
+ return id;
}
// ----------------------------
@@ -920,17 +1020,22 @@ Ref<MediaControlPanelVolumeSliderElement> MediaControlPanelVolumeSliderElement::
MediaControlFullscreenVolumeSliderElement::MediaControlFullscreenVolumeSliderElement(Document& document)
: MediaControlVolumeSliderElement(document)
{
- setPseudo(AtomicString("-webkit-media-controls-fullscreen-volume-slider", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlFullscreenVolumeSliderElement> MediaControlFullscreenVolumeSliderElement::create(Document& document)
+PassRefPtr<MediaControlFullscreenVolumeSliderElement> MediaControlFullscreenVolumeSliderElement::create(Document& document)
{
- Ref<MediaControlFullscreenVolumeSliderElement> slider = adoptRef(*new MediaControlFullscreenVolumeSliderElement(document));
+ RefPtr<MediaControlFullscreenVolumeSliderElement> slider = adoptRef(new MediaControlFullscreenVolumeSliderElement(document));
slider->ensureUserAgentShadowRoot();
slider->setType("range");
slider->setAttribute(precisionAttr, "float");
slider->setAttribute(maxAttr, "1");
- return slider;
+ return slider.release();
+}
+
+const AtomicString& MediaControlFullscreenVolumeSliderElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-volume-slider", AtomicString::ConstructFromLiteral));
+ return id;
}
// ----------------------------
@@ -938,16 +1043,15 @@ Ref<MediaControlFullscreenVolumeSliderElement> MediaControlFullscreenVolumeSlide
MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(Document& document)
: MediaControlInputElement(document, MediaEnterFullscreenButton)
{
- setPseudo(AtomicString("-webkit-media-controls-fullscreen-button", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(Document& document)
+PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(Document& document)
{
- Ref<MediaControlFullscreenButtonElement> button = adoptRef(*new MediaControlFullscreenButtonElement(document));
+ RefPtr<MediaControlFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenButtonElement(document));
button->ensureUserAgentShadowRoot();
button->setType("button");
button->hide();
- return button;
+ return button.release();
}
void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event)
@@ -972,6 +1076,12 @@ void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event)
HTMLInputElement::defaultEventHandler(event);
}
+const AtomicString& MediaControlFullscreenButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-button", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
void MediaControlFullscreenButtonElement::setIsFullscreen(bool isFullscreen)
{
setDisplayType(isFullscreen ? MediaExitFullscreenButton : MediaEnterFullscreenButton);
@@ -982,15 +1092,14 @@ void MediaControlFullscreenButtonElement::setIsFullscreen(bool isFullscreen)
MediaControlFullscreenVolumeMinButtonElement::MediaControlFullscreenVolumeMinButtonElement(Document& document)
: MediaControlInputElement(document, MediaUnMuteButton)
{
- setPseudo(AtomicString("-webkit-media-controls-fullscreen-volume-min-button", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlFullscreenVolumeMinButtonElement> MediaControlFullscreenVolumeMinButtonElement::create(Document& document)
+PassRefPtr<MediaControlFullscreenVolumeMinButtonElement> MediaControlFullscreenVolumeMinButtonElement::create(Document& document)
{
- Ref<MediaControlFullscreenVolumeMinButtonElement> button = adoptRef(*new MediaControlFullscreenVolumeMinButtonElement(document));
+ RefPtr<MediaControlFullscreenVolumeMinButtonElement> button = adoptRef(new MediaControlFullscreenVolumeMinButtonElement(document));
button->ensureUserAgentShadowRoot();
button->setType("button");
- return button;
+ return button.release();
}
void MediaControlFullscreenVolumeMinButtonElement::defaultEventHandler(Event* event)
@@ -1003,20 +1112,25 @@ void MediaControlFullscreenVolumeMinButtonElement::defaultEventHandler(Event* ev
HTMLInputElement::defaultEventHandler(event);
}
+const AtomicString& MediaControlFullscreenVolumeMinButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-volume-min-button", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
// ----------------------------
MediaControlFullscreenVolumeMaxButtonElement::MediaControlFullscreenVolumeMaxButtonElement(Document& document)
: MediaControlInputElement(document, MediaMuteButton)
{
- setPseudo(AtomicString("-webkit-media-controls-fullscreen-volume-max-button", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlFullscreenVolumeMaxButtonElement> MediaControlFullscreenVolumeMaxButtonElement::create(Document& document)
+PassRefPtr<MediaControlFullscreenVolumeMaxButtonElement> MediaControlFullscreenVolumeMaxButtonElement::create(Document& document)
{
- Ref<MediaControlFullscreenVolumeMaxButtonElement> button = adoptRef(*new MediaControlFullscreenVolumeMaxButtonElement(document));
+ RefPtr<MediaControlFullscreenVolumeMaxButtonElement> button = adoptRef(new MediaControlFullscreenVolumeMaxButtonElement(document));
button->ensureUserAgentShadowRoot();
button->setType("button");
- return button;
+ return button.release();
}
void MediaControlFullscreenVolumeMaxButtonElement::defaultEventHandler(Event* event)
@@ -1029,74 +1143,92 @@ void MediaControlFullscreenVolumeMaxButtonElement::defaultEventHandler(Event* ev
HTMLInputElement::defaultEventHandler(event);
}
+const AtomicString& MediaControlFullscreenVolumeMaxButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-volume-max-button", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
// ----------------------------
MediaControlTimeRemainingDisplayElement::MediaControlTimeRemainingDisplayElement(Document& document)
: MediaControlTimeDisplayElement(document, MediaTimeRemainingDisplay)
{
- setPseudo(getMediaControlTimeRemainingDisplayElementShadowPseudoId());
}
-Ref<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(Document& document)
+PassRefPtr<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(Document& document)
{
- return adoptRef(*new MediaControlTimeRemainingDisplayElement(document));
+ return adoptRef(new MediaControlTimeRemainingDisplayElement(document));
}
static const AtomicString& getMediaControlTimeRemainingDisplayElementShadowPseudoId()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-time-remaining-display", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-time-remaining-display", AtomicString::ConstructFromLiteral));
return id;
}
+const AtomicString& MediaControlTimeRemainingDisplayElement::shadowPseudoId() const
+{
+ return getMediaControlTimeRemainingDisplayElementShadowPseudoId();
+}
+
// ----------------------------
MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement(Document& document)
: MediaControlTimeDisplayElement(document, MediaCurrentTimeDisplay)
{
- setPseudo(getMediaControlCurrentTimeDisplayElementShadowPseudoId());
}
-Ref<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(Document& document)
+PassRefPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(Document& document)
{
- return adoptRef(*new MediaControlCurrentTimeDisplayElement(document));
+ return adoptRef(new MediaControlCurrentTimeDisplayElement(document));
}
static const AtomicString& getMediaControlCurrentTimeDisplayElementShadowPseudoId()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-current-time-display", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-current-time-display", AtomicString::ConstructFromLiteral));
return id;
}
+const AtomicString& MediaControlCurrentTimeDisplayElement::shadowPseudoId() const
+{
+ return getMediaControlCurrentTimeDisplayElementShadowPseudoId();
+}
+
// ----------------------------
#if ENABLE(VIDEO_TRACK)
MediaControlTextTrackContainerElement::MediaControlTextTrackContainerElement(Document& document)
: MediaControlDivElement(document, MediaTextTrackDisplayContainer)
- , m_updateTimer(*this, &MediaControlTextTrackContainerElement::updateTimerFired)
+ , m_updateTimer(this, &MediaControlTextTrackContainerElement::updateTimerFired)
, m_fontSize(0)
, m_fontSizeIsImportant(false)
- , m_updateTextTrackRepresentationStyle(false)
{
- setPseudo(AtomicString("-webkit-media-text-track-container", AtomicString::ConstructFromLiteral));
}
-Ref<MediaControlTextTrackContainerElement> MediaControlTextTrackContainerElement::create(Document& document)
+PassRefPtr<MediaControlTextTrackContainerElement> MediaControlTextTrackContainerElement::create(Document& document)
{
- auto element = adoptRef(*new MediaControlTextTrackContainerElement(document));
+ RefPtr<MediaControlTextTrackContainerElement> element = adoptRef(new MediaControlTextTrackContainerElement(document));
element->hide();
- return element;
+ return element.release();
}
-RenderPtr<RenderElement> MediaControlTextTrackContainerElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> MediaControlTextTrackContainerElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderTextTrackContainerElement>(*this, WTF::move(style));
+ return createRenderer<RenderTextTrackContainerElement>(*this, std::move(style));
}
-static bool compareCueIntervalForDisplay(const CueInterval& one, const CueInterval& two)
+const AtomicString& MediaControlTextTrackContainerElement::textTrackContainerElementShadowPseudoId()
{
- return one.data()->isPositionedAbove(two.data());
-};
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-text-track-container", AtomicString::ConstructFromLiteral));
+ return id;
+}
+
+const AtomicString& MediaControlTextTrackContainerElement::shadowPseudoId() const
+{
+ return textTrackContainerElementShadowPseudoId();
+}
void MediaControlTextTrackContainerElement::updateDisplay()
{
@@ -1111,7 +1243,7 @@ void MediaControlTextTrackContainerElement::updateDisplay()
return;
// 2. Let video be the media element or other playback mechanism.
- HTMLVideoElement& video = downcast<HTMLVideoElement>(*mediaElement);
+ HTMLVideoElement* video = toHTMLVideoElement(mediaElement);
// 3. Let output be an empty list of absolutely positioned CSS block boxes.
Vector<RefPtr<HTMLDivElement>> output;
@@ -1135,7 +1267,7 @@ void MediaControlTextTrackContainerElement::updateDisplay()
// 7. Let cues be an empty list of text track cues.
// 8. For each track track in tracks, append to cues all the cues from
// track's list of cues that have their text track cue active flag set.
- CueList activeCues = video.currentlyActiveCues();
+ CueList activeCues = video->currentlyActiveCues();
// 9. If reset is false, then, for each text track cue cue in cues: if cue's
// text track cue display state has a set of CSS boxes, then add those boxes
@@ -1145,85 +1277,55 @@ void MediaControlTextTrackContainerElement::updateDisplay()
// within the TextTrackCue instance itself. If parameters of the cue change,
// the display tree is cleared.
- // If the number of CSS boxes in the output is less than the number of cues
- // we wish to render (e.g., we are adding another cue in a set of roll-up
- // cues), remove all the existing CSS boxes representing the cues and re-add
- // them so that the new cue is at the bottom.
- // FIXME: Calling countChildNodes() here is inefficient. We don't need to
- // traverse all children just to check if there are less children than cues.
- if (countChildNodes() < activeCues.size())
- removeChildren();
-
- // Sort the active cues for the appropriate display order. For example, for roll-up
- // or paint-on captions, we need to add the cues in reverse chronological order,
- // so that the newest captions appear at the bottom.
- std::sort(activeCues.begin(), activeCues.end(), &compareCueIntervalForDisplay);
-
// 10. For each text track cue cue in cues that has not yet had
// corresponding CSS boxes added to output, in text track cue order, run the
// following substeps:
for (size_t i = 0; i < activeCues.size(); ++i) {
- if (!mediaController()->closedCaptionsVisible())
- continue;
-
- TextTrackCue* textTrackCue = activeCues[i].data();
- if (!textTrackCue->isRenderable())
- continue;
-
- VTTCue* cue = toVTTCue(textTrackCue);
+ TextTrackCue* cue = activeCues[i].data();
ASSERT(cue->isActive());
if (!cue->track() || !cue->track()->isRendered() || !cue->isActive() || cue->text().isEmpty())
continue;
- LOG(Media, "MediaControlTextTrackContainerElement::updateDisplay(%p) - adding and positioning cue #%zu: \"%s\", start=%.2f, end=%.2f, line=%.2f", this, i, cue->text().utf8().data(), cue->startTime(), cue->endTime(), cue->line());
-
- RefPtr<VTTCueBox> displayBox = cue->getDisplayTree(m_videoDisplaySize.size(), m_fontSize);
-#if ENABLE(WEBVTT_REGIONS)
- if (cue->track()->mode() == TextTrack::disabledKeyword())
- continue;
-
- VTTRegion* region = cue->track()->regions()->getRegionById(cue->regionId());
- if (!region) {
- // If cue has an empty text track cue region identifier or there is no
- // WebVTT region whose region identifier is identical to cue's text
- // track cue region identifier, run the following substeps:
-#endif
- if (displayBox->hasChildNodes() && !contains(displayBox.get())) {
- // Note: the display tree of a cue is removed when the active flag of the cue is unset.
- appendChild(displayBox, ASSERT_NO_EXCEPTION);
- cue->setFontSize(m_fontSize, m_videoDisplaySize.size(), m_fontSizeIsImportant);
- }
-#if ENABLE(WEBVTT_REGIONS)
- } else {
- // Let region be the WebVTT region whose region identifier
- // matches the text track cue region identifier of cue.
- RefPtr<HTMLDivElement> regionNode = region->getDisplayTree();
-
- // Append the region to the viewport, if it was not already.
- if (!contains(regionNode.get()))
- appendChild(region->getDisplayTree());
-
- region->appendTextTrackCueBox(displayBox);
+ RefPtr<TextTrackCueBox> displayBox = cue->getDisplayTree(m_videoDisplaySize.size());
+ if (displayBox->hasChildNodes() && !contains(displayBox.get())) {
+ // Note: the display tree of a cue is removed when the active flag of the cue is unset.
+ appendChild(displayBox, ASSERT_NO_EXCEPTION);
+ cue->setFontSize(m_fontSize, m_videoDisplaySize.size(), m_fontSizeIsImportant);
}
-#endif
}
// 11. Return output.
if (hasChildNodes()) {
show();
- updateTextTrackRepresentation();
+ if (mediaElement->requiresTextTrackRepresentation()) {
+ if (!m_textTrackRepresentation)
+ m_textTrackRepresentation = TextTrackRepresentation::create(this);
+ mediaElement->setTextTrackRepresentation(m_textTrackRepresentation.get());
+
+ if (Page* page = document().page())
+ m_textTrackRepresentation->setContentScale(page->deviceScaleFactor());
+
+ m_textTrackRepresentation->update();
+ setInlineStyleProperty(CSSPropertyWidth, m_videoDisplaySize.size().width(), CSSPrimitiveValue::CSS_PX);
+ setInlineStyleProperty(CSSPropertyHeight, m_videoDisplaySize.size().height(), CSSPrimitiveValue::CSS_PX);
+ }
} else {
hide();
clearTextTrackRepresentation();
}
}
-void MediaControlTextTrackContainerElement::updateActiveCuesFontSize()
+void MediaControlTextTrackContainerElement::updateTimerFired(Timer<MediaControlTextTrackContainerElement>&)
{
if (!document().page())
return;
+ if (m_textTrackRepresentation) {
+ setInlineStyleProperty(CSSPropertyWidth, m_videoDisplaySize.size().width(), CSSPrimitiveValue::CSS_PX);
+ setInlineStyleProperty(CSSPropertyHeight, m_videoDisplaySize.size().height(), CSSPrimitiveValue::CSS_PX);
+ }
+
HTMLMediaElement* mediaElement = parentMediaElement(this);
if (!mediaElement)
return;
@@ -1235,73 +1337,16 @@ void MediaControlTextTrackContainerElement::updateActiveCuesFontSize()
CueList activeCues = mediaElement->currentlyActiveCues();
for (size_t i = 0; i < activeCues.size(); ++i) {
TextTrackCue* cue = activeCues[i].data();
- if (!cue->isRenderable())
- continue;
-
- toVTTCue(cue)->setFontSize(m_fontSize, m_videoDisplaySize.size(), m_fontSizeIsImportant);
+ cue->setFontSize(m_fontSize, m_videoDisplaySize.size(), m_fontSizeIsImportant);
}
-
-}
-
-void MediaControlTextTrackContainerElement::updateTimerFired()
-{
- if (!document().page())
- return;
-
- if (m_textTrackRepresentation)
- updateStyleForTextTrackRepresentation();
-
- updateActiveCuesFontSize();
updateDisplay();
}
-void MediaControlTextTrackContainerElement::updateTextTrackRepresentation()
-{
- HTMLMediaElement* mediaElement = parentMediaElement(this);
- if (!mediaElement)
- return;
-
- if (!mediaElement->requiresTextTrackRepresentation())
- return;
-
- if (!m_textTrackRepresentation) {
- m_textTrackRepresentation = TextTrackRepresentation::create(*this);
- m_updateTextTrackRepresentationStyle = true;
- mediaElement->setTextTrackRepresentation(m_textTrackRepresentation.get());
- }
-
- m_textTrackRepresentation->update();
- updateStyleForTextTrackRepresentation();
-}
-
void MediaControlTextTrackContainerElement::clearTextTrackRepresentation()
{
- if (!m_textTrackRepresentation)
- return;
-
- m_textTrackRepresentation = nullptr;
- m_updateTextTrackRepresentationStyle = true;
if (HTMLMediaElement* mediaElement = parentMediaElement(this))
mediaElement->setTextTrackRepresentation(nullptr);
- updateStyleForTextTrackRepresentation();
- updateActiveCuesFontSize();
-}
-
-void MediaControlTextTrackContainerElement::updateStyleForTextTrackRepresentation()
-{
- if (!m_updateTextTrackRepresentationStyle)
- return;
- m_updateTextTrackRepresentationStyle = false;
-
- if (m_textTrackRepresentation) {
- setInlineStyleProperty(CSSPropertyWidth, m_videoDisplaySize.size().width(), CSSPrimitiveValue::CSS_PX);
- setInlineStyleProperty(CSSPropertyHeight, m_videoDisplaySize.size().height(), CSSPrimitiveValue::CSS_PX);
- setInlineStyleProperty(CSSPropertyPosition, CSSValueAbsolute);
- setInlineStyleProperty(CSSPropertyLeft, 0, CSSPrimitiveValue::CSS_PX);
- setInlineStyleProperty(CSSPropertyTop, 0, CSSPrimitiveValue::CSS_PX);
- return;
- }
-
+ m_textTrackRepresentation = nullptr;
removeInlineStyleProperty(CSSPropertyPosition);
removeInlineStyleProperty(CSSPropertyWidth);
removeInlineStyleProperty(CSSPropertyHeight);
@@ -1311,8 +1356,6 @@ void MediaControlTextTrackContainerElement::updateStyleForTextTrackRepresentatio
void MediaControlTextTrackContainerElement::enteredFullscreen()
{
- if (hasChildNodes())
- updateTextTrackRepresentation();
updateSizes(true);
}
@@ -1331,28 +1374,31 @@ void MediaControlTextTrackContainerElement::updateSizes(bool forceUpdate)
if (!document().page())
return;
- mediaElement->syncTextTrackBounds();
-
IntRect videoBox;
+
if (m_textTrackRepresentation)
videoBox = m_textTrackRepresentation->bounds();
else {
- if (!is<RenderVideo>(mediaElement->renderer()))
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (!mediaElement->renderer() || !mediaElement->renderer()->isWidget())
return;
- videoBox = downcast<RenderVideo>(*mediaElement->renderer()).videoBox();
+ videoBox = pixelSnappedIntRect(toRenderWidget(mediaElement->renderer())->contentBoxRect());
+#else
+ if (!mediaElement->renderer() || !mediaElement->renderer()->isVideo())
+ return;
+ videoBox = toRenderVideo(*mediaElement->renderer()).videoBox();
+#endif
}
if (!forceUpdate && m_videoDisplaySize == videoBox)
return;
-
m_videoDisplaySize = videoBox;
- m_updateTextTrackRepresentationStyle = true;
// FIXME (121170): This function is called during layout, and should lay out the text tracks immediately.
m_updateTimer.startOneShot(0);
}
-RefPtr<Image> MediaControlTextTrackContainerElement::createTextTrackRepresentationImage()
+PassRefPtr<Image> MediaControlTextTrackContainerElement::createTextTrackRepresentationImage()
{
if (!hasChildNodes())
return nullptr;
@@ -1363,14 +1409,14 @@ RefPtr<Image> MediaControlTextTrackContainerElement::createTextTrackRepresentati
document().updateLayout();
- auto* renderer = this->renderer();
+ auto renderer = this->renderer();
if (!renderer)
return nullptr;
if (!renderer->hasLayer())
return nullptr;
- RenderLayer* layer = downcast<RenderLayerModelObject>(*renderer).layer();
+ RenderLayer* layer = toRenderLayerModelObject(renderer)->layer();
float deviceScaleFactor = 1;
if (Page* page = document().page())
@@ -1378,20 +1424,17 @@ RefPtr<Image> MediaControlTextTrackContainerElement::createTextTrackRepresentati
IntRect paintingRect = IntRect(IntPoint(), layer->size());
- // FIXME (149422): This buffer should not be unconditionally unaccelerated.
- std::unique_ptr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), Unaccelerated, deviceScaleFactor));
+ std::unique_ptr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), deviceScaleFactor, ColorSpaceDeviceRGB));
if (!buffer)
return nullptr;
- layer->paint(buffer->context(), paintingRect, LayoutSize(), PaintBehaviorFlattenCompositingLayers, nullptr, RenderLayer::PaintLayerPaintingCompositingAllPhases);
+ layer->paint(buffer->context(), paintingRect, PaintBehaviorFlattenCompositingLayers, nullptr, nullptr, RenderLayer::PaintLayerPaintingCompositingAllPhases);
return buffer->copyImage();
}
void MediaControlTextTrackContainerElement::textTrackRepresentationBoundsChanged(const IntRect&)
{
- if (hasChildNodes())
- updateTextTrackRepresentation();
updateSizes();
}
diff --git a/Source/WebCore/html/shadow/MediaControlElements.h b/Source/WebCore/html/shadow/MediaControlElements.h
index 86d970290..6f5205d4b 100644
--- a/Source/WebCore/html/shadow/MediaControlElements.h
+++ b/Source/WebCore/html/shadow/MediaControlElements.h
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -40,7 +40,7 @@ namespace WebCore {
class MediaControlPanelElement final : public MediaControlDivElement {
public:
- static Ref<MediaControlPanelElement> create(Document&);
+ static PassRefPtr<MediaControlPanelElement> create(Document&);
void setCanBeDragged(bool);
void setIsDisplayed(bool);
@@ -57,6 +57,7 @@ public:
private:
explicit MediaControlPanelElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
void startDrag(const LayoutPoint& eventLocation);
@@ -65,7 +66,7 @@ private:
void startTimer();
void stopTimer();
- void transitionTimerFired();
+ void transitionTimerFired(Timer<MediaControlPanelElement>&);
void setPosition(const LayoutPoint&);
@@ -76,48 +77,51 @@ private:
LayoutPoint m_lastDragEventLocation;
LayoutPoint m_cumulativeDragOffset;
- Timer m_transitionTimer;
+ Timer<MediaControlPanelElement> m_transitionTimer;
};
// ----------------------------
class MediaControlPanelEnclosureElement final : public MediaControlDivElement {
public:
- static Ref<MediaControlPanelEnclosureElement> create(Document&);
+ static PassRefPtr<MediaControlPanelEnclosureElement> create(Document&);
private:
explicit MediaControlPanelEnclosureElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
};
// ----------------------------
class MediaControlOverlayEnclosureElement final : public MediaControlDivElement {
public:
- static Ref<MediaControlOverlayEnclosureElement> create(Document&);
+ static PassRefPtr<MediaControlOverlayEnclosureElement> create(Document&);
private:
explicit MediaControlOverlayEnclosureElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
};
// ----------------------------
-class MediaControlTimelineContainerElement final : public MediaControlDivElement {
+class MediaControlTimelineContainerElement : public MediaControlDivElement {
public:
- static Ref<MediaControlTimelineContainerElement> create(Document&);
+ static PassRefPtr<MediaControlTimelineContainerElement> create(Document&);
void setTimeDisplaysHidden(bool);
private:
explicit MediaControlTimelineContainerElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
};
// ----------------------------
-class MediaControlVolumeSliderContainerElement final : public MediaControlDivElement {
+class MediaControlVolumeSliderContainerElement : public MediaControlDivElement {
public:
- static Ref<MediaControlVolumeSliderContainerElement> create(Document&);
+ static PassRefPtr<MediaControlVolumeSliderContainerElement> create(Document&);
#if !PLATFORM(IOS)
virtual bool willRespondToMouseMoveEvents() override { return true; }
@@ -126,21 +130,23 @@ public:
private:
explicit MediaControlVolumeSliderContainerElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
};
// ----------------------------
-class MediaControlStatusDisplayElement final : public MediaControlDivElement {
+class MediaControlStatusDisplayElement : public MediaControlDivElement {
public:
- static Ref<MediaControlStatusDisplayElement> create(Document&);
+ static PassRefPtr<MediaControlStatusDisplayElement> create(Document&);
void update();
private:
explicit MediaControlStatusDisplayElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
enum StateBeingDisplayed { Nothing, Loading, LiveBroadcast };
StateBeingDisplayed m_stateBeingDisplayed;
@@ -150,7 +156,7 @@ private:
class MediaControlPanelMuteButtonElement final : public MediaControlMuteButtonElement {
public:
- static Ref<MediaControlPanelMuteButtonElement> create(Document&, MediaControls*);
+ static PassRefPtr<MediaControlPanelMuteButtonElement> create(Document&, MediaControls*);
#if !PLATFORM(IOS)
virtual bool willRespondToMouseMoveEvents() override { return true; }
@@ -159,6 +165,7 @@ public:
private:
explicit MediaControlPanelMuteButtonElement(Document&, MediaControls*);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
MediaControls* m_controls;
@@ -168,10 +175,11 @@ private:
class MediaControlVolumeSliderMuteButtonElement final : public MediaControlMuteButtonElement {
public:
- static Ref<MediaControlVolumeSliderMuteButtonElement> create(Document&);
+ static PassRefPtr<MediaControlVolumeSliderMuteButtonElement> create(Document&);
private:
explicit MediaControlVolumeSliderMuteButtonElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
};
@@ -179,7 +187,7 @@ private:
class MediaControlPlayButtonElement final : public MediaControlInputElement {
public:
- static Ref<MediaControlPlayButtonElement> create(Document&);
+ static PassRefPtr<MediaControlPlayButtonElement> create(Document&);
#if !PLATFORM(IOS)
virtual bool willRespondToMouseClickEvents() override { return true; }
@@ -190,6 +198,7 @@ public:
private:
explicit MediaControlPlayButtonElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
};
@@ -197,45 +206,48 @@ private:
class MediaControlOverlayPlayButtonElement final : public MediaControlInputElement {
public:
- static Ref<MediaControlOverlayPlayButtonElement> create(Document&);
+ static PassRefPtr<MediaControlOverlayPlayButtonElement> create(Document&);
virtual void updateDisplayType() override;
private:
explicit MediaControlOverlayPlayButtonElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
};
// ----------------------------
-class MediaControlSeekForwardButtonElement final : public MediaControlSeekButtonElement {
+class MediaControlSeekForwardButtonElement : public MediaControlSeekButtonElement {
public:
- static Ref<MediaControlSeekForwardButtonElement> create(Document&);
+ static PassRefPtr<MediaControlSeekForwardButtonElement> create(Document&);
private:
explicit MediaControlSeekForwardButtonElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual bool isForwardButton() const override { return true; }
};
// ----------------------------
-class MediaControlSeekBackButtonElement final : public MediaControlSeekButtonElement {
+class MediaControlSeekBackButtonElement : public MediaControlSeekButtonElement {
public:
- static Ref<MediaControlSeekBackButtonElement> create(Document&);
+ static PassRefPtr<MediaControlSeekBackButtonElement> create(Document&);
private:
explicit MediaControlSeekBackButtonElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual bool isForwardButton() const override { return false; }
};
// ----------------------------
-class MediaControlRewindButtonElement final : public MediaControlInputElement {
+class MediaControlRewindButtonElement : public MediaControlInputElement {
public:
- static Ref<MediaControlRewindButtonElement> create(Document&);
+ static PassRefPtr<MediaControlRewindButtonElement> create(Document&);
#if !PLATFORM(IOS)
virtual bool willRespondToMouseClickEvents() override { return true; }
@@ -244,14 +256,15 @@ public:
private:
explicit MediaControlRewindButtonElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
};
// ----------------------------
-class MediaControlReturnToRealtimeButtonElement final : public MediaControlInputElement {
+class MediaControlReturnToRealtimeButtonElement : public MediaControlInputElement {
public:
- static Ref<MediaControlReturnToRealtimeButtonElement> create(Document&);
+ static PassRefPtr<MediaControlReturnToRealtimeButtonElement> create(Document&);
#if !PLATFORM(IOS)
virtual bool willRespondToMouseClickEvents() override { return true; }
@@ -260,6 +273,7 @@ public:
private:
explicit MediaControlReturnToRealtimeButtonElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
};
@@ -267,7 +281,7 @@ private:
class MediaControlToggleClosedCaptionsButtonElement final : public MediaControlInputElement {
public:
- static Ref<MediaControlToggleClosedCaptionsButtonElement> create(Document&, MediaControls*);
+ static PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> create(Document&, MediaControls*);
#if !PLATFORM(IOS)
virtual bool willRespondToMouseClickEvents() override { return true; }
@@ -278,9 +292,10 @@ public:
private:
explicit MediaControlToggleClosedCaptionsButtonElement(Document&, MediaControls*);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
-#if PLATFORM(COCOA) || PLATFORM(WIN) || PLATFORM(GTK)
+#if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK)
MediaControls* m_controls;
#endif
};
@@ -289,7 +304,7 @@ private:
class MediaControlClosedCaptionsContainerElement final : public MediaControlDivElement {
public:
- static Ref<MediaControlClosedCaptionsContainerElement> create(Document&);
+ static PassRefPtr<MediaControlClosedCaptionsContainerElement> create(Document&);
#if !PLATFORM(IOS)
virtual bool willRespondToMouseClickEvents() override { return true; }
@@ -297,13 +312,14 @@ public:
private:
MediaControlClosedCaptionsContainerElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
};
// ----------------------------
class MediaControlClosedCaptionsTrackListElement final : public MediaControlDivElement {
public:
- static Ref<MediaControlClosedCaptionsTrackListElement> create(Document&, MediaControls*);
+ static PassRefPtr<MediaControlClosedCaptionsTrackListElement> create(Document&, MediaControls*);
#if !PLATFORM(IOS)
virtual bool willRespondToMouseClickEvents() override { return true; }
@@ -316,6 +332,7 @@ private:
void rebuildTrackListMenu();
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
typedef Vector<RefPtr<Element>> TrackMenuItems;
@@ -331,7 +348,7 @@ private:
class MediaControlTimelineElement final : public MediaControlInputElement {
public:
- static Ref<MediaControlTimelineElement> create(Document&, MediaControls*);
+ static PassRefPtr<MediaControlTimelineElement> create(Document&, MediaControls*);
#if !PLATFORM(IOS)
virtual bool willRespondToMouseClickEvents() override;
@@ -343,6 +360,7 @@ public:
private:
explicit MediaControlTimelineElement(Document&, MediaControls*);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
MediaControls* m_controls;
@@ -352,17 +370,18 @@ private:
class MediaControlFullscreenButtonElement final : public MediaControlInputElement {
public:
- static Ref<MediaControlFullscreenButtonElement> create(Document&);
+ static PassRefPtr<MediaControlFullscreenButtonElement> create(Document&);
#if !PLATFORM(IOS)
virtual bool willRespondToMouseClickEvents() override { return true; }
#endif
- void setIsFullscreen(bool);
+ virtual void setIsFullscreen(bool);
private:
explicit MediaControlFullscreenButtonElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
};
@@ -370,26 +389,28 @@ private:
class MediaControlPanelVolumeSliderElement final : public MediaControlVolumeSliderElement {
public:
- static Ref<MediaControlPanelVolumeSliderElement> create(Document&);
+ static PassRefPtr<MediaControlPanelVolumeSliderElement> create(Document&);
private:
explicit MediaControlPanelVolumeSliderElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
};
// ----------------------------
-class MediaControlFullscreenVolumeSliderElement final : public MediaControlVolumeSliderElement {
+class MediaControlFullscreenVolumeSliderElement : public MediaControlVolumeSliderElement {
public:
- static Ref<MediaControlFullscreenVolumeSliderElement> create(Document&);
+ static PassRefPtr<MediaControlFullscreenVolumeSliderElement> create(Document&);
private:
explicit MediaControlFullscreenVolumeSliderElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
};
// ----------------------------
-class MediaControlFullscreenVolumeMinButtonElement final : public MediaControlInputElement {
+class MediaControlFullscreenVolumeMinButtonElement : public MediaControlInputElement {
public:
- static Ref<MediaControlFullscreenVolumeMinButtonElement> create(Document&);
+ static PassRefPtr<MediaControlFullscreenVolumeMinButtonElement> create(Document&);
#if !PLATFORM(IOS)
virtual bool willRespondToMouseClickEvents() override { return true; }
@@ -397,14 +418,15 @@ public:
private:
explicit MediaControlFullscreenVolumeMinButtonElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
};
// ----------------------------
-class MediaControlFullscreenVolumeMaxButtonElement final : public MediaControlInputElement {
+class MediaControlFullscreenVolumeMaxButtonElement : public MediaControlInputElement {
public:
- static Ref<MediaControlFullscreenVolumeMaxButtonElement> create(Document&);
+ static PassRefPtr<MediaControlFullscreenVolumeMaxButtonElement> create(Document&);
#if !PLATFORM(IOS)
virtual bool willRespondToMouseClickEvents() override { return true; }
@@ -413,6 +435,7 @@ public:
private:
explicit MediaControlFullscreenVolumeMaxButtonElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void defaultEventHandler(Event*) override;
};
@@ -421,20 +444,22 @@ private:
class MediaControlTimeRemainingDisplayElement final : public MediaControlTimeDisplayElement {
public:
- static Ref<MediaControlTimeRemainingDisplayElement> create(Document&);
+ static PassRefPtr<MediaControlTimeRemainingDisplayElement> create(Document&);
private:
explicit MediaControlTimeRemainingDisplayElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
};
// ----------------------------
class MediaControlCurrentTimeDisplayElement final : public MediaControlTimeDisplayElement {
public:
- static Ref<MediaControlCurrentTimeDisplayElement> create(Document&);
+ static PassRefPtr<MediaControlCurrentTimeDisplayElement> create(Document&);
private:
explicit MediaControlCurrentTimeDisplayElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
};
// ----------------------------
@@ -443,33 +468,31 @@ private:
class MediaControlTextTrackContainerElement final : public MediaControlDivElement, public TextTrackRepresentationClient {
public:
- static Ref<MediaControlTextTrackContainerElement> create(Document&);
+ static PassRefPtr<MediaControlTextTrackContainerElement> create(Document&);
void updateDisplay();
void updateSizes(bool forceUpdate = false);
void enteredFullscreen();
void exitedFullscreen();
+ static const AtomicString& textTrackContainerElementShadowPseudoId();
private:
- void updateTimerFired();
- void updateActiveCuesFontSize();
+ void updateTimerFired(Timer<MediaControlTextTrackContainerElement>&);
explicit MediaControlTextTrackContainerElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
- virtual RefPtr<Image> createTextTrackRepresentationImage() override;
+ virtual PassRefPtr<Image> createTextTrackRepresentationImage() override;
virtual void textTrackRepresentationBoundsChanged(const IntRect&) override;
- void updateTextTrackRepresentation();
void clearTextTrackRepresentation();
- void updateStyleForTextTrackRepresentation();
- std::unique_ptr<TextTrackRepresentation> m_textTrackRepresentation;
+ OwnPtr<TextTrackRepresentation> m_textTrackRepresentation;
- Timer m_updateTimer;
+ Timer<MediaControlTextTrackContainerElement> m_updateTimer;
IntRect m_videoDisplaySize;
int m_fontSize;
bool m_fontSizeIsImportant;
- bool m_updateTextTrackRepresentationStyle;
};
#endif
diff --git a/Source/WebCore/html/shadow/MediaControls.cpp b/Source/WebCore/html/shadow/MediaControls.cpp
index 3dd6de86d..7bfaf436c 100644
--- a/Source/WebCore/html/shadow/MediaControls.cpp
+++ b/Source/WebCore/html/shadow/MediaControls.cpp
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -48,11 +48,10 @@ MediaControls::MediaControls(Document& document)
, m_volumeSlider(0)
, m_toggleClosedCaptionsButton(0)
, m_fullScreenButton(0)
- , m_hideFullscreenControlsTimer(*this, &MediaControls::hideFullscreenControlsTimerFired)
+ , m_hideFullscreenControlsTimer(this, &MediaControls::hideFullscreenControlsTimerFired)
, m_isFullscreen(false)
, m_isMouseOverControls(false)
{
- setPseudo(AtomicString("-webkit-media-controls", AtomicString::ConstructFromLiteral));
}
void MediaControls::setMediaController(MediaControllerInterface* controller)
@@ -330,7 +329,7 @@ void MediaControls::defaultEventHandler(Event* event)
}
}
-void MediaControls::hideFullscreenControlsTimerFired()
+void MediaControls::hideFullscreenControlsTimerFired(Timer<MediaControls>&)
{
if (m_mediaController->paused())
return;
@@ -364,11 +363,17 @@ void MediaControls::stopHideFullscreenControlsTimer()
m_hideFullscreenControlsTimer.stop();
}
+const AtomicString& MediaControls::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls"));
+ return id;
+}
+
bool MediaControls::containsRelatedTarget(Event* event)
{
- if (!is<MouseEvent>(*event))
+ if (!event->isMouseEvent())
return false;
- EventTarget* relatedTarget = downcast<MouseEvent>(*event).relatedTarget();
+ EventTarget* relatedTarget = static_cast<MouseEvent*>(event)->relatedTarget();
if (!relatedTarget)
return false;
return contains(relatedTarget->toNode());
diff --git a/Source/WebCore/html/shadow/MediaControls.h b/Source/WebCore/html/shadow/MediaControls.h
index 41aee5387..47124cfef 100644
--- a/Source/WebCore/html/shadow/MediaControls.h
+++ b/Source/WebCore/html/shadow/MediaControls.h
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -97,7 +97,7 @@ class MediaControls : public HTMLDivElement {
virtual bool willRespondToMouseMoveEvents() override { return true; }
#endif
- virtual void hideFullscreenControlsTimerFired();
+ virtual void hideFullscreenControlsTimerFired(Timer<MediaControls>&);
virtual void startHideFullscreenControlsTimer();
virtual void stopHideFullscreenControlsTimer();
@@ -137,12 +137,14 @@ protected:
MediaControlToggleClosedCaptionsButtonElement* m_toggleClosedCaptionsButton;
MediaControlFullscreenButtonElement* m_fullScreenButton;
- Timer m_hideFullscreenControlsTimer;
+ Timer<MediaControls> m_hideFullscreenControlsTimer;
bool m_isFullscreen;
bool m_isMouseOverControls;
private:
- virtual bool isMediaControls() const override final { return true; }
+ virtual bool isMediaControls() const override { return true; }
+
+ virtual const AtomicString& shadowPseudoId() const override;
};
inline MediaControls* toMediaControls(Node* node)
diff --git a/Source/WebCore/html/shadow/MediaControlsApple.cpp b/Source/WebCore/html/shadow/MediaControlsApple.cpp
deleted file mode 100644
index 8fdba0d03..000000000
--- a/Source/WebCore/html/shadow/MediaControlsApple.cpp
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(VIDEO)
-#include "MediaControlsApple.h"
-
-#include "CSSValueKeywords.h"
-#include "ExceptionCodePlaceholder.h"
-#include "HTMLNames.h"
-#include "WheelEvent.h"
-
-namespace WebCore {
-
-MediaControlsApple::MediaControlsApple(Document& document)
- : MediaControls(document)
- , m_rewindButton(0)
- , m_returnToRealTimeButton(0)
- , m_statusDisplay(0)
- , m_timeRemainingDisplay(0)
- , m_timelineContainer(0)
- , m_seekBackButton(0)
- , m_seekForwardButton(0)
- , m_closedCaptionsTrackList(0)
- , m_closedCaptionsContainer(0)
- , m_volumeSliderMuteButton(0)
- , m_volumeSliderContainer(0)
- , m_fullScreenMinVolumeButton(0)
- , m_fullScreenVolumeSlider(0)
- , m_fullScreenMaxVolumeButton(0)
-{
-}
-
-PassRefPtr<MediaControls> MediaControls::create(Document& document)
-{
- return MediaControlsApple::createControls(document);
-}
-
-PassRefPtr<MediaControlsApple> MediaControlsApple::createControls(Document& document)
-{
- if (!document.page())
- return 0;
-
- RefPtr<MediaControlsApple> controls = adoptRef(new MediaControlsApple(document));
-
- RefPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(document);
-
- ExceptionCode ec;
-
- RefPtr<MediaControlRewindButtonElement> rewindButton = MediaControlRewindButtonElement::create(document);
- controls->m_rewindButton = rewindButton.get();
- panel->appendChild(rewindButton.release(), ec);
- if (ec)
- return 0;
-
- RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(document);
- controls->m_playButton = playButton.get();
- panel->appendChild(playButton.release(), ec);
- if (ec)
- return 0;
-
- RefPtr<MediaControlReturnToRealtimeButtonElement> returnToRealtimeButton = MediaControlReturnToRealtimeButtonElement::create(document);
- controls->m_returnToRealTimeButton = returnToRealtimeButton.get();
- panel->appendChild(returnToRealtimeButton.release(), ec);
- if (ec)
- return 0;
-
- if (document.page()->theme().usesMediaControlStatusDisplay()) {
- RefPtr<MediaControlStatusDisplayElement> statusDisplay = MediaControlStatusDisplayElement::create(document);
- controls->m_statusDisplay = statusDisplay.get();
- panel->appendChild(statusDisplay.release(), ec);
- if (ec)
- return 0;
- }
-
- RefPtr<MediaControlTimelineContainerElement> timelineContainer = MediaControlTimelineContainerElement::create(document);
-
- RefPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(document);
- controls->m_currentTimeDisplay = currentTimeDisplay.get();
- timelineContainer->appendChild(currentTimeDisplay.release(), ec);
- if (ec)
- return 0;
-
- RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(document, controls.get());
- controls->m_timeline = timeline.get();
- timelineContainer->appendChild(timeline.release(), ec);
- if (ec)
- return 0;
-
- RefPtr<MediaControlTimeRemainingDisplayElement> timeRemainingDisplay = MediaControlTimeRemainingDisplayElement::create(document);
- controls->m_timeRemainingDisplay = timeRemainingDisplay.get();
- timelineContainer->appendChild(timeRemainingDisplay.release(), ec);
- if (ec)
- return 0;
-
- controls->m_timelineContainer = timelineContainer.get();
- panel->appendChild(timelineContainer.release(), ec);
- if (ec)
- return 0;
-
- // FIXME: Only create when needed <http://webkit.org/b/57163>
- RefPtr<MediaControlSeekBackButtonElement> seekBackButton = MediaControlSeekBackButtonElement::create(document);
- controls->m_seekBackButton = seekBackButton.get();
- panel->appendChild(seekBackButton.release(), ec);
- if (ec)
- return 0;
-
- // FIXME: Only create when needed <http://webkit.org/b/57163>
- RefPtr<MediaControlSeekForwardButtonElement> seekForwardButton = MediaControlSeekForwardButtonElement::create(document);
- controls->m_seekForwardButton = seekForwardButton.get();
- panel->appendChild(seekForwardButton.release(), ec);
- if (ec)
- return 0;
-
- if (document.page()->theme().supportsClosedCaptioning()) {
- RefPtr<MediaControlClosedCaptionsContainerElement> closedCaptionsContainer = MediaControlClosedCaptionsContainerElement::create(document);
-
- RefPtr<MediaControlClosedCaptionsTrackListElement> closedCaptionsTrackList = MediaControlClosedCaptionsTrackListElement::create(document, controls.get());
- controls->m_closedCaptionsTrackList = closedCaptionsTrackList.get();
- closedCaptionsContainer->appendChild(closedCaptionsTrackList.release(), ec);
- if (ec)
- return 0;
-
- RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document, controls.get());
- controls->m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
- panel->appendChild(toggleClosedCaptionsButton.release(), ec);
- if (ec)
- return 0;
-
- controls->m_closedCaptionsContainer = closedCaptionsContainer.get();
- controls->appendChild(closedCaptionsContainer.release(), ec);
- if (ec)
- return 0;
- }
-
- // FIXME: Only create when needed <http://webkit.org/b/57163>
- RefPtr<MediaControlFullscreenButtonElement> fullScreenButton = MediaControlFullscreenButtonElement::create(document);
- controls->m_fullScreenButton = fullScreenButton.get();
- panel->appendChild(fullScreenButton.release(), ec);
-
- // The mute button and the slider element should be in the same div.
- RefPtr<HTMLDivElement> panelVolumeControlContainer = HTMLDivElement::create(document);
-
- if (document.page()->theme().usesMediaControlVolumeSlider()) {
- RefPtr<MediaControlVolumeSliderContainerElement> volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(document);
-
- RefPtr<MediaControlPanelVolumeSliderElement> slider = MediaControlPanelVolumeSliderElement::create(document);
- controls->m_volumeSlider = slider.get();
- volumeSliderContainer->appendChild(slider.release(), ec);
- if (ec)
- return 0;
-
- // This is a duplicate mute button, which is visible in some ports at the bottom of the volume bar.
- // It's important only when the volume bar is displayed below the controls.
- RefPtr<MediaControlVolumeSliderMuteButtonElement> volumeSliderMuteButton = MediaControlVolumeSliderMuteButtonElement::create(document);
- controls->m_volumeSliderMuteButton = volumeSliderMuteButton.get();
- volumeSliderContainer->appendChild(volumeSliderMuteButton.release(), ec);
-
- if (ec)
- return 0;
-
- controls->m_volumeSliderContainer = volumeSliderContainer.get();
- panelVolumeControlContainer->appendChild(volumeSliderContainer.release(), ec);
- if (ec)
- return 0;
- }
-
- RefPtr<MediaControlPanelMuteButtonElement> panelMuteButton = MediaControlPanelMuteButtonElement::create(document, controls.get());
- controls->m_panelMuteButton = panelMuteButton.get();
- panelVolumeControlContainer->appendChild(panelMuteButton.release(), ec);
- if (ec)
- return 0;
-
- panel->appendChild(panelVolumeControlContainer, ec);
- if (ec)
- return 0;
-
- // FIXME: Only create when needed <http://webkit.org/b/57163>
- RefPtr<MediaControlFullscreenVolumeMinButtonElement> fullScreenMinVolumeButton = MediaControlFullscreenVolumeMinButtonElement::create(document);
- controls->m_fullScreenMinVolumeButton = fullScreenMinVolumeButton.get();
- panel->appendChild(fullScreenMinVolumeButton.release(), ec);
- if (ec)
- return 0;
-
- RefPtr<MediaControlFullscreenVolumeSliderElement> fullScreenVolumeSlider = MediaControlFullscreenVolumeSliderElement::create(document);
- controls->m_fullScreenVolumeSlider = fullScreenVolumeSlider.get();
- panel->appendChild(fullScreenVolumeSlider.release(), ec);
- if (ec)
- return 0;
-
- RefPtr<MediaControlFullscreenVolumeMaxButtonElement> fullScreenMaxVolumeButton = MediaControlFullscreenVolumeMaxButtonElement::create(document);
- controls->m_fullScreenMaxVolumeButton = fullScreenMaxVolumeButton.get();
- panel->appendChild(fullScreenMaxVolumeButton.release(), ec);
- if (ec)
- return 0;
-
- controls->m_panel = panel.get();
- controls->appendChild(panel.release(), ec);
- if (ec)
- return 0;
-
- return controls.release();
-}
-
-void MediaControlsApple::setMediaController(MediaControllerInterface* controller)
-{
- if (m_mediaController == controller)
- return;
-
- MediaControls::setMediaController(controller);
-
- if (m_rewindButton)
- m_rewindButton->setMediaController(controller);
- if (m_returnToRealTimeButton)
- m_returnToRealTimeButton->setMediaController(controller);
- if (m_statusDisplay)
- m_statusDisplay->setMediaController(controller);
- if (m_timeRemainingDisplay)
- m_timeRemainingDisplay->setMediaController(controller);
- if (m_timelineContainer)
- m_timelineContainer->setMediaController(controller);
- if (m_seekBackButton)
- m_seekBackButton->setMediaController(controller);
- if (m_seekForwardButton)
- m_seekForwardButton->setMediaController(controller);
- if (m_volumeSliderMuteButton)
- m_volumeSliderMuteButton->setMediaController(controller);
- if (m_volumeSliderContainer)
- m_volumeSliderContainer->setMediaController(controller);
- if (m_fullScreenMinVolumeButton)
- m_fullScreenMinVolumeButton->setMediaController(controller);
- if (m_fullScreenVolumeSlider)
- m_fullScreenVolumeSlider->setMediaController(controller);
- if (m_fullScreenMaxVolumeButton)
- m_fullScreenMaxVolumeButton->setMediaController(controller);
- if (m_closedCaptionsTrackList)
- m_closedCaptionsTrackList->setMediaController(controller);
- if (m_closedCaptionsContainer)
- m_closedCaptionsContainer->setMediaController(controller);
-}
-
-void MediaControlsApple::defaultEventHandler(Event* event)
-{
- if (event->type() == eventNames().clickEvent) {
- if (m_closedCaptionsContainer && m_closedCaptionsContainer->isShowing()) {
- hideClosedCaptionTrackList();
- event->setDefaultHandled();
- }
- }
-
- MediaControls::defaultEventHandler(event);
-}
-
-void MediaControlsApple::hide()
-{
- MediaControls::hide();
- m_volumeSliderContainer->hide();
- if (m_closedCaptionsContainer)
- hideClosedCaptionTrackList();
-}
-
-void MediaControlsApple::makeTransparent()
-{
- MediaControls::makeTransparent();
- m_volumeSliderContainer->hide();
- if (m_closedCaptionsContainer)
- hideClosedCaptionTrackList();
-}
-
-void MediaControlsApple::changedClosedCaptionsVisibility()
-{
- MediaControls::changedClosedCaptionsVisibility();
- if (m_closedCaptionsContainer && m_closedCaptionsContainer->isShowing())
- hideClosedCaptionTrackList();
-
-}
-
-void MediaControlsApple::reset()
-{
- Page* page = document().page();
- if (!page)
- return;
-
- updateStatusDisplay();
-
- if (m_mediaController->supportsFullscreen())
- m_fullScreenButton->show();
- else
- m_fullScreenButton->hide();
-
- double duration = m_mediaController->duration();
- if (std::isfinite(duration) || page->theme().hasOwnDisabledStateHandlingFor(MediaSliderPart)) {
- m_timeline->setDuration(duration);
- m_timelineContainer->show();
- m_timeline->setPosition(m_mediaController->currentTime());
- updateCurrentTimeDisplay();
- } else
- m_timelineContainer->hide();
-
- if (m_mediaController->hasAudio() || page->theme().hasOwnDisabledStateHandlingFor(MediaMuteButtonPart))
- m_panelMuteButton->show();
- else
- m_panelMuteButton->hide();
-
- if (m_volumeSlider)
- setSliderVolume();
-
- if (m_toggleClosedCaptionsButton) {
- if (m_mediaController->hasClosedCaptions())
- m_toggleClosedCaptionsButton->show();
- else
- m_toggleClosedCaptionsButton->hide();
- }
-
- if (m_playButton)
- m_playButton->updateDisplayType();
-
-#if ENABLE(FULLSCREEN_API)
- if (m_fullScreenVolumeSlider)
- setFullscreenSliderVolume();
-
- if (m_isFullscreen) {
- if (m_mediaController->isLiveStream()) {
- m_seekBackButton->hide();
- m_seekForwardButton->hide();
- m_rewindButton->show();
- m_returnToRealTimeButton->show();
- } else {
- m_seekBackButton->show();
- m_seekForwardButton->show();
- m_rewindButton->hide();
- m_returnToRealTimeButton->hide();
- }
- } else
-#endif
- if (!m_mediaController->isLiveStream()) {
- m_returnToRealTimeButton->hide();
- m_rewindButton->show();
- } else {
- m_returnToRealTimeButton->show();
- m_rewindButton->hide();
- }
-
- makeOpaque();
-}
-
-void MediaControlsApple::updateCurrentTimeDisplay()
-{
- double now = m_mediaController->currentTime();
- double duration = m_mediaController->duration();
-
- Page* page = document().page();
- if (!page)
- return;
-
- // Allow the theme to format the time.
- m_currentTimeDisplay->setInnerText(page->theme().formatMediaControlsCurrentTime(now, duration), IGNORE_EXCEPTION);
- m_currentTimeDisplay->setCurrentValue(now);
- m_timeRemainingDisplay->setInnerText(page->theme().formatMediaControlsRemainingTime(now, duration), IGNORE_EXCEPTION);
- m_timeRemainingDisplay->setCurrentValue(now - duration);
-}
-
-void MediaControlsApple::reportedError()
-{
- Page* page = document().page();
- if (!page)
- return;
-
- if (!page->theme().hasOwnDisabledStateHandlingFor(MediaSliderPart))
- m_timelineContainer->hide();
-
- if (!page->theme().hasOwnDisabledStateHandlingFor(MediaMuteButtonPart))
- m_panelMuteButton->hide();
-
- m_fullScreenButton->hide();
-
- if (m_volumeSliderContainer)
- m_volumeSliderContainer->hide();
- if (m_toggleClosedCaptionsButton && !page->theme().hasOwnDisabledStateHandlingFor(MediaToggleClosedCaptionsButtonPart))
- m_toggleClosedCaptionsButton->hide();
- if (m_closedCaptionsContainer)
- hideClosedCaptionTrackList();
-}
-
-void MediaControlsApple::updateStatusDisplay()
-{
- if (m_statusDisplay)
- m_statusDisplay->update();
-}
-
-void MediaControlsApple::loadedMetadata()
-{
- if (m_statusDisplay && !m_mediaController->isLiveStream())
- m_statusDisplay->hide();
-
- MediaControls::loadedMetadata();
-}
-
-void MediaControlsApple::changedMute()
-{
- MediaControls::changedMute();
-
- if (m_volumeSliderMuteButton)
- m_volumeSliderMuteButton->changedMute();
-}
-
-void MediaControlsApple::changedVolume()
-{
- MediaControls::changedVolume();
-
- if (m_fullScreenVolumeSlider)
- setFullscreenSliderVolume();
-}
-
-void MediaControlsApple::enteredFullscreen()
-{
- MediaControls::enteredFullscreen();
- m_panel->setCanBeDragged(true);
-
- if (m_mediaController->isLiveStream()) {
- m_seekBackButton->hide();
- m_seekForwardButton->hide();
- m_rewindButton->show();
- m_returnToRealTimeButton->show();
- } else {
- m_seekBackButton->show();
- m_seekForwardButton->show();
- m_rewindButton->hide();
- m_returnToRealTimeButton->hide();
- }
-}
-
-void MediaControlsApple::exitedFullscreen()
-{
- m_rewindButton->show();
- m_seekBackButton->show();
- m_seekForwardButton->show();
- m_returnToRealTimeButton->show();
-
- m_panel->setCanBeDragged(false);
-
- // We will keep using the panel, but we want it to go back to the standard position.
- // This will matter right away because we use the panel even when not fullscreen.
- // And if we reenter fullscreen we also want the panel in the standard position.
- m_panel->resetPosition();
-
- MediaControls::exitedFullscreen();
-}
-
-void MediaControlsApple::showVolumeSlider()
-{
- if (!m_mediaController->hasAudio())
- return;
-
- if (m_volumeSliderContainer)
- m_volumeSliderContainer->show();
-}
-
-void MediaControlsApple::toggleClosedCaptionTrackList()
-{
- if (!m_mediaController->hasClosedCaptions())
- return;
-
- if (m_closedCaptionsContainer) {
- if (m_closedCaptionsContainer->isShowing())
- hideClosedCaptionTrackList();
- else {
- if (m_closedCaptionsTrackList)
- m_closedCaptionsTrackList->updateDisplay();
- showClosedCaptionTrackList();
- }
- }
-}
-
-void MediaControlsApple::showClosedCaptionTrackList()
-{
- if (!m_closedCaptionsContainer || m_closedCaptionsContainer->isShowing())
- return;
-
- m_closedCaptionsContainer->show();
-
- // Ensure the controls panel does not receive any events while the captions
- // track list is visible as all events now need to be captured by the
- // track list.
- m_panel->setInlineStyleProperty(CSSPropertyPointerEvents, CSSValueNone);
-
- RefPtr<EventListener> listener = eventListener();
- m_closedCaptionsContainer->addEventListener(eventNames().wheelEvent, listener, true);
-
- // Track click events in the capture phase at two levels, first at the document level
- // such that a click outside of the <video> may dismiss the track list, second at the
- // media controls level such that a click anywhere outside of the track list hides the
- // track list. These two levels are necessary since it would not be possible to get a
- // reference to the track list when handling the event outside of the shadow tree.
- document().addEventListener(eventNames().clickEvent, listener, true);
- addEventListener(eventNames().clickEvent, listener, true);
-}
-
-void MediaControlsApple::hideClosedCaptionTrackList()
-{
- if (!m_closedCaptionsContainer || !m_closedCaptionsContainer->isShowing())
- return;
-
- m_closedCaptionsContainer->hide();
-
- // Buttons in the controls panel may now be interactive.
- m_panel->removeInlineStyleProperty(CSSPropertyPointerEvents);
-
- EventListener* listener = eventListener().get();
- m_closedCaptionsContainer->removeEventListener(eventNames().wheelEvent, listener, true);
- document().removeEventListener(eventNames().clickEvent, listener, true);
- removeEventListener(eventNames().clickEvent, listener, true);
-}
-
-void MediaControlsApple::setFullscreenSliderVolume()
-{
- m_fullScreenVolumeSlider->setVolume(m_mediaController->muted() ? 0.0 : m_mediaController->volume());
-}
-
-bool MediaControlsApple::shouldClosedCaptionsContainerPreventPageScrolling(int wheelDeltaY)
-{
- int scrollTop = m_closedCaptionsContainer->scrollTop();
- // Scrolling down.
- if (wheelDeltaY < 0 && (scrollTop + m_closedCaptionsContainer->offsetHeight()) >= m_closedCaptionsContainer->scrollHeight())
- return true;
- // Scrolling up.
- if (wheelDeltaY > 0 && scrollTop <= 0)
- return true;
- return false;
-}
-
-void MediaControlsApple::handleClickEvent(Event* event)
-{
- Node* currentTarget = event->currentTarget()->toNode();
- Node* target = event->target()->toNode();
-
- if ((currentTarget == &document() && !shadowHost()->contains(target)) || (currentTarget == this && !m_closedCaptionsContainer->contains(target))) {
- hideClosedCaptionTrackList();
- event->stopImmediatePropagation();
- event->setDefaultHandled();
- }
-}
-
-void MediaControlsApple::closedCaptionTracksChanged()
-{
- if (m_toggleClosedCaptionsButton) {
- if (m_mediaController->hasClosedCaptions())
- m_toggleClosedCaptionsButton->show();
- else
- m_toggleClosedCaptionsButton->hide();
- }
-}
-
-PassRefPtr<MediaControlsAppleEventListener> MediaControlsApple::eventListener()
-{
- if (!m_eventListener)
- m_eventListener = MediaControlsAppleEventListener::create(this);
- return m_eventListener;
-}
-
-// --------
-
-void MediaControlsAppleEventListener::handleEvent(ScriptExecutionContext*, Event* event)
-{
- if (event->type() == eventNames().clickEvent)
- m_mediaControls->handleClickEvent(event);
- else if (eventNames().isWheelEventType(event->type()) && is<WheelEvent>(*event)) {
- WheelEvent& wheelEvent = downcast<WheelEvent>(*event);
- if (m_mediaControls->shouldClosedCaptionsContainerPreventPageScrolling(wheelEvent.wheelDeltaY()))
- wheelEvent.preventDefault();
- }
-}
-
-bool MediaControlsAppleEventListener::operator==(const EventListener& listener)
-{
- if (const MediaControlsAppleEventListener* mediaControlsAppleEventListener = MediaControlsAppleEventListener::cast(&listener))
- return m_mediaControls == mediaControlsAppleEventListener->m_mediaControls;
- return false;
-}
-
-}
-
-#endif
diff --git a/Source/WebCore/html/shadow/MediaControlsApple.h b/Source/WebCore/html/shadow/MediaControlsApple.h
deleted file mode 100644
index 2f84759ec..000000000
--- a/Source/WebCore/html/shadow/MediaControlsApple.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaControlsApple_h
-#define MediaControlsApple_h
-
-#if ENABLE(VIDEO)
-
-#include "MediaControls.h"
-
-namespace WebCore {
-
-class MediaControlsApple;
-
-class MediaControlsAppleEventListener : public EventListener {
-public:
- static Ref<MediaControlsAppleEventListener> create(MediaControlsApple* mediaControls) { return adoptRef(*new MediaControlsAppleEventListener(mediaControls)); }
- static const MediaControlsAppleEventListener* cast(const EventListener* listener)
- {
- return listener->type() == MediaControlsAppleEventListenerType
- ? static_cast<const MediaControlsAppleEventListener*>(listener)
- : 0;
- }
-
- virtual bool operator==(const EventListener& other) override;
-
-private:
- MediaControlsAppleEventListener(MediaControlsApple* mediaControls)
- : EventListener(MediaControlsAppleEventListenerType)
- , m_mediaControls(mediaControls)
- {
- }
-
- virtual void handleEvent(ScriptExecutionContext*, Event*) override;
-
- MediaControlsApple* m_mediaControls;
-};
-
-class MediaControlsApple final : public MediaControls {
-public:
- static PassRefPtr<MediaControlsApple> createControls(Document&);
-
- // MediaControls implementation.
- virtual void setMediaController(MediaControllerInterface*) override;
-
- virtual void hide() override;
- virtual void makeTransparent() override;
-
- virtual void reset() override;
-
- virtual void changedMute() override;
- virtual void changedVolume() override;
-
- virtual void enteredFullscreen() override;
- virtual void exitedFullscreen() override;
-
- virtual void reportedError() override;
- virtual void loadedMetadata() override;
-
- virtual void showVolumeSlider() override;
- virtual void updateCurrentTimeDisplay() override;
- virtual void updateStatusDisplay() override;
-
- virtual void changedClosedCaptionsVisibility() override;
- virtual void toggleClosedCaptionTrackList() override;
- virtual void closedCaptionTracksChanged() override;
-
- bool shouldClosedCaptionsContainerPreventPageScrolling(int wheelDeltaY);
- void handleClickEvent(Event*);
-
-private:
- MediaControlsApple(Document&);
-
- virtual void defaultEventHandler(Event*) override;
- PassRefPtr<MediaControlsAppleEventListener> eventListener();
-
- void showClosedCaptionTrackList();
- void hideClosedCaptionTrackList();
- void setFullscreenSliderVolume();
-
- MediaControlRewindButtonElement* m_rewindButton;
- MediaControlReturnToRealtimeButtonElement* m_returnToRealTimeButton;
- MediaControlStatusDisplayElement* m_statusDisplay;
- MediaControlTimeRemainingDisplayElement* m_timeRemainingDisplay;
- MediaControlTimelineContainerElement* m_timelineContainer;
- MediaControlSeekBackButtonElement* m_seekBackButton;
- MediaControlSeekForwardButtonElement* m_seekForwardButton;
- MediaControlClosedCaptionsTrackListElement* m_closedCaptionsTrackList;
- MediaControlClosedCaptionsContainerElement* m_closedCaptionsContainer;
- MediaControlVolumeSliderMuteButtonElement* m_volumeSliderMuteButton;
- MediaControlVolumeSliderContainerElement* m_volumeSliderContainer;
- MediaControlFullscreenVolumeMinButtonElement* m_fullScreenMinVolumeButton;
- MediaControlFullscreenVolumeSliderElement* m_fullScreenVolumeSlider;
- MediaControlFullscreenVolumeMaxButtonElement* m_fullScreenMaxVolumeButton;
- RefPtr<MediaControlsAppleEventListener> m_eventListener;
-};
-
-}
-
-#endif
-#endif
diff --git a/Source/WebCore/html/shadow/MediaControlsGtk.cpp b/Source/WebCore/html/shadow/MediaControlsGtk.cpp
new file mode 100644
index 000000000..7382d434e
--- /dev/null
+++ b/Source/WebCore/html/shadow/MediaControlsGtk.cpp
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Zan Dobersek <zandobersek@gmail.com>
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(VIDEO)
+#include "MediaControlsGtk.h"
+
+namespace WebCore {
+
+class MediaControlsGtkEventListener : public EventListener {
+public:
+ static PassRefPtr<MediaControlsGtkEventListener> create(MediaControlsGtk* mediaControls) { return adoptRef(new MediaControlsGtkEventListener(mediaControls)); }
+ static const MediaControlsGtkEventListener* cast(const EventListener* listener)
+ {
+ return listener->type() == GObjectEventListenerType
+ ? static_cast<const MediaControlsGtkEventListener*>(listener)
+ : 0;
+ }
+
+ virtual bool operator==(const EventListener& other);
+
+private:
+ MediaControlsGtkEventListener(MediaControlsGtk* mediaControls)
+ : EventListener(GObjectEventListenerType)
+ , m_mediaControls(mediaControls)
+ {
+ }
+
+ virtual void handleEvent(ScriptExecutionContext*, Event*);
+
+ MediaControlsGtk* m_mediaControls;
+};
+
+MediaControlsGtk::MediaControlsGtk(Document& document)
+ : MediaControls(document)
+ , m_durationDisplay(0)
+ , m_enclosure(0)
+ , m_closedCaptionsTrackList(0)
+ , m_closedCaptionsContainer(0)
+ , m_eventListener(0)
+{
+}
+
+PassRefPtr<MediaControls> MediaControls::create(Document& document)
+{
+ return MediaControlsGtk::createControls(document);
+}
+
+PassRefPtr<MediaControlsGtk> MediaControlsGtk::createControls(Document& document)
+{
+ if (!document.page())
+ return 0;
+
+ RefPtr<MediaControlsGtk> controls = adoptRef(new MediaControlsGtk(document));
+
+ if (controls->initializeControls(document))
+ return controls.release();
+
+ return 0;
+}
+
+bool MediaControlsGtk::initializeControls(Document& document)
+{
+ // Create an enclosing element for the panel so we can visually offset the controls correctly.
+ RefPtr<MediaControlPanelEnclosureElement> enclosure = MediaControlPanelEnclosureElement::create(document);
+ RefPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(document);
+ ExceptionCode exceptionCode;
+
+ RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(document);
+ m_playButton = playButton.get();
+ panel->appendChild(playButton.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+
+ RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(document, this);
+ m_timeline = timeline.get();
+ panel->appendChild(timeline.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+
+ RefPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(document);
+ m_currentTimeDisplay = currentTimeDisplay.get();
+ m_currentTimeDisplay->hide();
+ panel->appendChild(currentTimeDisplay.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+
+ RefPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(document);
+ m_durationDisplay = durationDisplay.get();
+ panel->appendChild(durationDisplay.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+
+ if (document.page()->theme().supportsClosedCaptioning()) {
+ RefPtr<MediaControlClosedCaptionsContainerElement> closedCaptionsContainer = MediaControlClosedCaptionsContainerElement::create(document);
+
+ RefPtr<MediaControlClosedCaptionsTrackListElement> closedCaptionsTrackList = MediaControlClosedCaptionsTrackListElement::create(document, this);
+ m_closedCaptionsTrackList = closedCaptionsTrackList.get();
+ closedCaptionsContainer->appendChild(closedCaptionsTrackList.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+
+ RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document, this);
+ m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
+ panel->appendChild(toggleClosedCaptionsButton.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+
+ m_closedCaptionsContainer = closedCaptionsContainer.get();
+ appendChild(closedCaptionsContainer.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+ }
+
+ RefPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(document);
+ m_fullScreenButton = fullscreenButton.get();
+ panel->appendChild(fullscreenButton.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+
+ RefPtr<MediaControlPanelMuteButtonElement> panelMuteButton = MediaControlPanelMuteButtonElement::create(document, this);
+ m_panelMuteButton = panelMuteButton.get();
+ panel->appendChild(panelMuteButton.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+
+ RefPtr<MediaControlVolumeSliderContainerElement> sliderContainer = MediaControlVolumeSliderContainerElement::create(document);
+ m_volumeSliderContainer = sliderContainer.get();
+ panel->appendChild(sliderContainer.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+
+ RefPtr<MediaControlPanelVolumeSliderElement> slider = MediaControlPanelVolumeSliderElement::create(document);
+ m_volumeSlider = slider.get();
+ m_volumeSlider->setClearMutedOnUserInteraction(true);
+ m_volumeSliderContainer->appendChild(slider.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+
+ m_panel = panel.get();
+ enclosure->appendChild(panel.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+
+ m_enclosure = enclosure.get();
+ appendChild(enclosure.release(), exceptionCode);
+ if (exceptionCode)
+ return false;
+
+ return true;
+}
+
+void MediaControlsGtk::setMediaController(MediaControllerInterface* controller)
+{
+ if (m_mediaController == controller)
+ return;
+
+ MediaControls::setMediaController(controller);
+
+ if (m_durationDisplay)
+ m_durationDisplay->setMediaController(controller);
+ if (m_enclosure)
+ m_enclosure->setMediaController(controller);
+ if (m_closedCaptionsContainer)
+ m_closedCaptionsContainer->setMediaController(controller);
+ if (m_closedCaptionsTrackList)
+ m_closedCaptionsTrackList->setMediaController(controller);
+}
+
+void MediaControlsGtk::reset()
+{
+ Page* page = document().page();
+ if (!page)
+ return;
+
+ double duration = m_mediaController->duration();
+ m_durationDisplay->setInnerText(page->theme().formatMediaControlsTime(duration), ASSERT_NO_EXCEPTION);
+ m_durationDisplay->setCurrentValue(duration);
+
+ if (m_toggleClosedCaptionsButton) {
+ if (m_mediaController->hasClosedCaptions())
+ m_toggleClosedCaptionsButton->show();
+ else
+ m_toggleClosedCaptionsButton->hide();
+ }
+
+ MediaControls::reset();
+}
+
+void MediaControlsGtk::playbackStarted()
+{
+ m_currentTimeDisplay->show();
+ m_durationDisplay->hide();
+
+ MediaControls::playbackStarted();
+}
+
+void MediaControlsGtk::updateCurrentTimeDisplay()
+{
+ double now = m_mediaController->currentTime();
+ double duration = m_mediaController->duration();
+
+ Page* page = document().page();
+ if (!page)
+ return;
+
+ // After seek, hide duration display and show current time.
+ if (now > 0) {
+ m_currentTimeDisplay->show();
+ m_durationDisplay->hide();
+ }
+
+ // Allow the theme to format the time.
+ ExceptionCode exceptionCode;
+ m_currentTimeDisplay->setInnerText(page->theme().formatMediaControlsCurrentTime(now, duration), exceptionCode);
+ m_currentTimeDisplay->setCurrentValue(now);
+}
+
+void MediaControlsGtk::changedMute()
+{
+ MediaControls::changedMute();
+
+ if (m_mediaController->muted())
+ m_volumeSlider->setVolume(0);
+ else
+ m_volumeSlider->setVolume(m_mediaController->volume());
+}
+
+
+void MediaControlsGtk::makeTransparent()
+{
+ MediaControls::makeTransparent();
+
+ if (m_volumeSliderContainer)
+ m_volumeSliderContainer->hide();
+
+ hideClosedCaptionTrackList();
+}
+
+void MediaControlsGtk::showVolumeSlider()
+{
+ if (!m_mediaController->hasAudio())
+ return;
+
+ if (m_volumeSliderContainer)
+ m_volumeSliderContainer->show();
+}
+
+#if ENABLE(VIDEO_TRACK)
+void MediaControlsGtk::createTextTrackDisplay()
+{
+ if (m_textDisplayContainer)
+ return;
+
+ RefPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(document());
+ m_textDisplayContainer = textDisplayContainer.get();
+
+ if (m_mediaController)
+ m_textDisplayContainer->setMediaController(m_mediaController);
+
+ // Insert it before the first controller element so it always displays behind the controls.
+ insertBefore(textDisplayContainer.release(), m_enclosure, ASSERT_NO_EXCEPTION);
+}
+#endif
+
+void MediaControlsGtk::toggleClosedCaptionTrackList()
+{
+ if (!m_mediaController->hasClosedCaptions())
+ return;
+
+ if (!m_closedCaptionsContainer || !m_closedCaptionsTrackList)
+ return;
+
+ if (m_closedCaptionsContainer->isShowing()) {
+ hideClosedCaptionTrackList();
+ return;
+ }
+
+ m_closedCaptionsTrackList->updateDisplay();
+ showClosedCaptionTrackList();
+}
+
+void MediaControlsGtk::showClosedCaptionTrackList()
+{
+ m_volumeSliderContainer->hide();
+
+ if (!m_closedCaptionsContainer || m_closedCaptionsContainer->isShowing())
+ return;
+
+ m_closedCaptionsContainer->show();
+ m_panel->setInlineStyleProperty(CSSPropertyPointerEvents, CSSValueNone);
+
+ RefPtr<EventListener> listener = eventListener();
+
+ // Check for clicks outside the media-control
+ document().addEventListener(eventNames().clickEvent, listener, true);
+ // Check for clicks inside the media-control box
+ addEventListener(eventNames().clickEvent, listener, true);
+}
+
+void MediaControlsGtk::hideClosedCaptionTrackList()
+{
+ if (!m_closedCaptionsContainer || !m_closedCaptionsContainer->isShowing())
+ return;
+
+ m_closedCaptionsContainer->hide();
+ m_panel->removeInlineStyleProperty(CSSPropertyPointerEvents);
+
+ EventListener* listener = eventListener().get();
+
+ document().removeEventListener(eventNames().clickEvent, listener, true);
+ removeEventListener(eventNames().clickEvent, listener, true);
+}
+
+void MediaControlsGtk::handleClickEvent(Event *event)
+{
+ Node* currentTarget = event->currentTarget()->toNode();
+ Node* target = event->target()->toNode();
+
+ if ((currentTarget == &document() && !shadowHost()->contains(target))
+ || (currentTarget == this && !m_closedCaptionsContainer->contains(target))) {
+ hideClosedCaptionTrackList();
+ event->stopImmediatePropagation();
+ event->setDefaultHandled();
+ }
+}
+
+PassRefPtr<MediaControlsGtkEventListener> MediaControlsGtk::eventListener()
+{
+ if (!m_eventListener)
+ m_eventListener = MediaControlsGtkEventListener::create(this);
+
+ return m_eventListener;
+}
+
+void MediaControlsGtkEventListener::handleEvent(ScriptExecutionContext*, Event* event)
+{
+ if (event->type() == eventNames().clickEvent)
+ m_mediaControls->handleClickEvent(event);
+
+ return;
+}
+
+bool MediaControlsGtkEventListener::operator==(const EventListener& listener)
+{
+ if (const MediaControlsGtkEventListener* mediaControlsGtkEventListener = MediaControlsGtkEventListener::cast(&listener))
+ return m_mediaControls == mediaControlsGtkEventListener->m_mediaControls;
+ return false;
+}
+
+}
+#endif
diff --git a/Source/WebCore/html/shadow/MediaControlsGtk.h b/Source/WebCore/html/shadow/MediaControlsGtk.h
new file mode 100644
index 000000000..b444ca33e
--- /dev/null
+++ b/Source/WebCore/html/shadow/MediaControlsGtk.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Zan Dobersek <zandobersek@gmail.com>
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MediaControlsGtk_h
+#define MediaControlsGtk_h
+
+#if ENABLE(VIDEO)
+
+#include "MediaControls.h"
+
+namespace WebCore {
+
+class MediaControlsGtkEventListener;
+
+class MediaControlsGtk : public MediaControls {
+public:
+ // Called from port-specific parent create function to create custom controls.
+ static PassRefPtr<MediaControlsGtk> createControls(Document&);
+
+ virtual void setMediaController(MediaControllerInterface*) override;
+ virtual void reset() override;
+ virtual void playbackStarted() override;
+ void changedMute() override;
+ virtual void updateCurrentTimeDisplay() override;
+ virtual void showVolumeSlider() override;
+ virtual void makeTransparent() override;
+ virtual void toggleClosedCaptionTrackList() override;
+
+ void handleClickEvent(Event*);
+
+#if ENABLE(VIDEO_TRACK)
+ void createTextTrackDisplay() override;
+#endif
+
+protected:
+ explicit MediaControlsGtk(Document&);
+ bool initializeControls(Document&);
+
+private:
+ void showClosedCaptionTrackList();
+ void hideClosedCaptionTrackList();
+
+ PassRefPtr<MediaControlsGtkEventListener> eventListener();
+
+ MediaControlTimeRemainingDisplayElement* m_durationDisplay;
+ MediaControlPanelEnclosureElement* m_enclosure;
+ MediaControlVolumeSliderContainerElement* m_volumeSliderContainer;
+ MediaControlClosedCaptionsTrackListElement* m_closedCaptionsTrackList;
+ MediaControlClosedCaptionsContainerElement* m_closedCaptionsContainer;
+
+ RefPtr<MediaControlsGtkEventListener> m_eventListener;
+};
+
+}
+
+#endif
+
+#endif
diff --git a/Source/WebCore/html/shadow/MeterShadowElement.cpp b/Source/WebCore/html/shadow/MeterShadowElement.cpp
index 4311a7059..f34a9c496 100644
--- a/Source/WebCore/html/shadow/MeterShadowElement.cpp
+++ b/Source/WebCore/html/shadow/MeterShadowElement.cpp
@@ -51,7 +51,7 @@ MeterShadowElement::MeterShadowElement(Document& document)
HTMLMeterElement* MeterShadowElement::meterElement() const
{
- return downcast<HTMLMeterElement>(shadowHost());
+ return toHTMLMeterElement(shadowHost());
}
bool MeterShadowElement::rendererIsNeeded(const RenderStyle& style)
@@ -63,26 +63,29 @@ bool MeterShadowElement::rendererIsNeeded(const RenderStyle& style)
MeterInnerElement::MeterInnerElement(Document& document)
: MeterShadowElement(document)
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-meter-inner-element", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-meter-inner-element", AtomicString::ConstructFromLiteral));
setPseudo(pseudoId);
}
bool MeterInnerElement::rendererIsNeeded(const RenderStyle& style)
{
+ if (meterElement()->hasAuthorShadowRoot())
+ return HTMLDivElement::rendererIsNeeded(style);
+
auto render = meterElement()->renderer();
return render && !render->theme().supportsMeter(render->style().appearance()) && HTMLDivElement::rendererIsNeeded(style);
}
-RenderPtr<RenderElement> MeterInnerElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> MeterInnerElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderMeter>(*this, WTF::move(style));
+ return createRenderer<RenderMeter>(*this, std::move(style));
}
const AtomicString& MeterValueElement::valuePseudoId() const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, optimumPseudoId, ("-webkit-meter-optimum-value", AtomicString::ConstructFromLiteral));
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, suboptimumPseudoId, ("-webkit-meter-suboptimum-value", AtomicString::ConstructFromLiteral));
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, evenLessGoodPseudoId, ("-webkit-meter-even-less-good-value", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, optimumPseudoId, ("-webkit-meter-optimum-value", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, suboptimumPseudoId, ("-webkit-meter-suboptimum-value", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, evenLessGoodPseudoId, ("-webkit-meter-even-less-good-value", AtomicString::ConstructFromLiteral));
HTMLMeterElement* meter = meterElement();
if (!meter)
diff --git a/Source/WebCore/html/shadow/MeterShadowElement.h b/Source/WebCore/html/shadow/MeterShadowElement.h
index 4f9b304d7..a3cf162d9 100644
--- a/Source/WebCore/html/shadow/MeterShadowElement.h
+++ b/Source/WebCore/html/shadow/MeterShadowElement.h
@@ -53,41 +53,41 @@ private:
class MeterInnerElement final : public MeterShadowElement {
public:
- static Ref<MeterInnerElement> create(Document&);
+ static PassRefPtr<MeterInnerElement> create(Document&);
private:
MeterInnerElement(Document&);
virtual bool rendererIsNeeded(const RenderStyle&) override;
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
};
-inline Ref<MeterInnerElement> MeterInnerElement::create(Document& document)
+inline PassRefPtr<MeterInnerElement> MeterInnerElement::create(Document& document)
{
- return adoptRef(*new MeterInnerElement(document));
+ return adoptRef(new MeterInnerElement(document));
}
class MeterBarElement final : public MeterShadowElement {
public:
- static Ref<MeterBarElement> create(Document&);
+ static PassRefPtr<MeterBarElement> create(Document&);
private:
MeterBarElement(Document& document)
: MeterShadowElement(document)
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-meter-bar", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-meter-bar", AtomicString::ConstructFromLiteral));
setPseudo(pseudoId);
}
};
-inline Ref<MeterBarElement> MeterBarElement::create(Document& document)
+inline PassRefPtr<MeterBarElement> MeterBarElement::create(Document& document)
{
- return adoptRef(*new MeterBarElement(document));
+ return adoptRef(new MeterBarElement(document));
}
class MeterValueElement final : public MeterShadowElement {
public:
- static Ref<MeterValueElement> create(Document&);
+ static PassRefPtr<MeterValueElement> create(Document&);
void setWidthPercentage(double);
void updatePseudo() { setPseudo(valuePseudoId()); }
@@ -101,9 +101,9 @@ private:
const AtomicString& valuePseudoId() const;
};
-inline Ref<MeterValueElement> MeterValueElement::create(Document& document)
+inline PassRefPtr<MeterValueElement> MeterValueElement::create(Document& document)
{
- return adoptRef(*new MeterValueElement(document));
+ return adoptRef(new MeterValueElement(document));
}
}
diff --git a/Source/WebCore/html/shadow/ProgressShadowElement.cpp b/Source/WebCore/html/shadow/ProgressShadowElement.cpp
index 6927b4a70..112e77814 100644
--- a/Source/WebCore/html/shadow/ProgressShadowElement.cpp
+++ b/Source/WebCore/html/shadow/ProgressShadowElement.cpp
@@ -29,6 +29,7 @@
*/
#include "config.h"
+#if ENABLE(PROGRESS_ELEMENT)
#include "ProgressShadowElement.h"
#include "HTMLNames.h"
@@ -46,7 +47,7 @@ ProgressShadowElement::ProgressShadowElement(Document& document)
HTMLProgressElement* ProgressShadowElement::progressElement() const
{
- return downcast<HTMLProgressElement>(shadowHost());
+ return toHTMLProgressElement(shadowHost());
}
bool ProgressShadowElement::rendererIsNeeded(const RenderStyle& style)
@@ -60,13 +61,16 @@ ProgressInnerElement::ProgressInnerElement(Document& document)
{
}
-RenderPtr<RenderElement> ProgressInnerElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> ProgressInnerElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderProgress>(*this, WTF::move(style));
+ return createRenderer<RenderProgress>(*this, std::move(style));
}
bool ProgressInnerElement::rendererIsNeeded(const RenderStyle& style)
{
+ if (progressElement()->hasAuthorShadowRoot())
+ return HTMLDivElement::rendererIsNeeded(style);
+
RenderObject* progressRenderer = progressElement()->renderer();
return progressRenderer && !progressRenderer->style().hasAppearance() && HTMLDivElement::rendererIsNeeded(style);
}
@@ -87,3 +91,4 @@ void ProgressValueElement::setWidthPercentage(double width)
}
}
+#endif
diff --git a/Source/WebCore/html/shadow/ProgressShadowElement.h b/Source/WebCore/html/shadow/ProgressShadowElement.h
index 97f824fdf..78bc49ec4 100644
--- a/Source/WebCore/html/shadow/ProgressShadowElement.h
+++ b/Source/WebCore/html/shadow/ProgressShadowElement.h
@@ -32,6 +32,7 @@
#ifndef ProgressShadowElement_h
#define ProgressShadowElement_h
+#if ENABLE(PROGRESS_ELEMENT)
#include "HTMLDivElement.h"
#include <wtf/Forward.h>
@@ -52,52 +53,53 @@ private:
class ProgressInnerElement final : public ProgressShadowElement {
public:
- static Ref<ProgressInnerElement> create(Document&);
+ static PassRefPtr<ProgressInnerElement> create(Document&);
private:
ProgressInnerElement(Document&);
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual bool rendererIsNeeded(const RenderStyle&) override;
};
-inline Ref<ProgressInnerElement> ProgressInnerElement::create(Document& document)
+inline PassRefPtr<ProgressInnerElement> ProgressInnerElement::create(Document& document)
{
- Ref<ProgressInnerElement> result = adoptRef(*new ProgressInnerElement(document));
+ RefPtr<ProgressInnerElement> result = adoptRef(new ProgressInnerElement(document));
result->setPseudo(AtomicString("-webkit-progress-inner-element", AtomicString::ConstructFromLiteral));
return result;
}
class ProgressBarElement final : public ProgressShadowElement {
public:
- static Ref<ProgressBarElement> create(Document&);
+ static PassRefPtr<ProgressBarElement> create(Document&);
private:
ProgressBarElement(Document&);
};
-inline Ref<ProgressBarElement> ProgressBarElement::create(Document& document)
+inline PassRefPtr<ProgressBarElement> ProgressBarElement::create(Document& document)
{
- Ref<ProgressBarElement> result = adoptRef(*new ProgressBarElement(document));
+ RefPtr<ProgressBarElement> result = adoptRef(new ProgressBarElement(document));
result->setPseudo(AtomicString("-webkit-progress-bar", AtomicString::ConstructFromLiteral));
return result;
}
class ProgressValueElement final : public ProgressShadowElement {
public:
- static Ref<ProgressValueElement> create(Document&);
+ static PassRefPtr<ProgressValueElement> create(Document&);
void setWidthPercentage(double);
private:
ProgressValueElement(Document&);
};
-inline Ref<ProgressValueElement> ProgressValueElement::create(Document& document)
+inline PassRefPtr<ProgressValueElement> ProgressValueElement::create(Document& document)
{
- Ref<ProgressValueElement> result = adoptRef(*new ProgressValueElement(document));
+ RefPtr<ProgressValueElement> result = adoptRef(new ProgressValueElement(document));
result->setPseudo(AtomicString("-webkit-progress-value", AtomicString::ConstructFromLiteral));
return result;
}
}
+#endif // ENABLE(PROGRESS_ELEMENT)
#endif // ProgressShadowElement_h
diff --git a/Source/WebCore/html/shadow/SliderThumbElement.cpp b/Source/WebCore/html/shadow/SliderThumbElement.cpp
index 0a1bb83fb..33dbf2e52 100644
--- a/Source/WebCore/html/shadow/SliderThumbElement.cpp
+++ b/Source/WebCore/html/shadow/SliderThumbElement.cpp
@@ -45,7 +45,7 @@
#include "RenderTheme.h"
#include "ShadowRoot.h"
-#if ENABLE(IOS_TOUCH_EVENTS)
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
#include "Document.h"
#include "Page.h"
#include "TouchEvent.h"
@@ -77,8 +77,8 @@ inline static bool hasVerticalAppearance(HTMLInputElement* input)
// --------------------------------
-RenderSliderThumb::RenderSliderThumb(SliderThumbElement& element, Ref<RenderStyle>&& style)
- : RenderBlockFlow(element, WTF::move(style))
+RenderSliderThumb::RenderSliderThumb(SliderThumbElement& element, PassRef<RenderStyle> style)
+ : RenderBlockFlow(element, std::move(style))
{
}
@@ -94,10 +94,8 @@ void RenderSliderThumb::updateAppearance(RenderStyle* parentStyle)
style().setAppearance(MediaVolumeSliderThumbPart);
else if (parentStyle->appearance() == MediaFullScreenVolumeSliderPart)
style().setAppearance(MediaFullScreenVolumeSliderThumbPart);
- if (style().hasAppearance()) {
- ASSERT(element());
- theme().adjustSliderThumbSize(style(), element());
- }
+ if (style().hasAppearance())
+ theme().adjustSliderThumbSize(&style(), element());
}
bool RenderSliderThumb::isSliderThumb() const
@@ -109,10 +107,10 @@ bool RenderSliderThumb::isSliderThumb() const
// FIXME: Find a way to cascade appearance and adjust heights, and get rid of this class.
// http://webkit.org/b/62535
-class RenderSliderContainer final : public RenderFlexibleBox {
+class RenderSliderContainer : public RenderFlexibleBox {
public:
- RenderSliderContainer(SliderContainerElement& element, Ref<RenderStyle>&& style)
- : RenderFlexibleBox(element, WTF::move(style))
+ RenderSliderContainer(SliderContainerElement& element, PassRef<RenderStyle> style)
+ : RenderFlexibleBox(element, std::move(style))
{
}
@@ -190,7 +188,6 @@ void RenderSliderContainer::layout()
else
thumbLocation.setX(thumbLocation.x() - offset);
thumb->setLocation(thumbLocation);
- thumb->repaint();
}
// --------------------------------
@@ -198,7 +195,7 @@ void RenderSliderContainer::layout()
SliderThumbElement::SliderThumbElement(Document& document)
: HTMLDivElement(HTMLNames::divTag, document)
, m_inDragMode(false)
-#if ENABLE(IOS_TOUCH_EVENTS)
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
, m_exclusiveTouchIdentifier(NoIdentifier)
, m_isRegisteredAsTouchEventListener(false)
#endif
@@ -215,9 +212,9 @@ void SliderThumbElement::setPositionFromValue()
renderer()->setNeedsLayout();
}
-RenderPtr<RenderElement> SliderThumbElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> SliderThumbElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderSliderThumb>(*this, WTF::move(style));
+ return createRenderer<RenderSliderThumb>(*this, std::move(style));
}
bool SliderThumbElement::isDisabledFormControl() const
@@ -226,6 +223,12 @@ bool SliderThumbElement::isDisabledFormControl() const
return !input || input->isDisabledFormControl();
}
+bool SliderThumbElement::matchesReadOnlyPseudoClass() const
+{
+ HTMLInputElement* input = hostInput();
+ return input && input->matchesReadOnlyPseudoClass();
+}
+
bool SliderThumbElement::matchesReadWritePseudoClass() const
{
HTMLInputElement* input = hostInput();
@@ -256,14 +259,16 @@ void SliderThumbElement::setPositionFromPoint(const LayoutPoint& absolutePoint)
if (!trackElement->renderBox())
return;
+ input->setTextAsOfLastFormControlChangeEvent(input->value());
+
// Do all the tracking math relative to the input's renderer's box.
- RenderBox& inputRenderer = downcast<RenderBox>(*input->renderer());
+ RenderBox& inputRenderer = *toRenderBox(input->renderer());
RenderBox& trackRenderer = *trackElement->renderBox();
bool isVertical = hasVerticalAppearance(input.get());
bool isLeftToRightDirection = renderBox()->style().isLeftToRightDirection();
- LayoutPoint offset(inputRenderer.absoluteToLocal(absolutePoint, UseTransforms));
+ LayoutPoint offset = roundedLayoutPoint(inputRenderer.absoluteToLocal(absolutePoint, UseTransforms));
FloatRect trackBoundingBox = trackRenderer.localToContainerQuad(FloatRect(0, 0, trackRenderer.width(), trackRenderer.height()), &inputRenderer).enclosingBoundingBox();
LayoutUnit trackLength;
@@ -305,6 +310,7 @@ void SliderThumbElement::setPositionFromPoint(const LayoutPoint& absolutePoint)
input->setValueFromRenderer(valueString);
if (renderer())
renderer()->setNeedsLayout();
+ input->dispatchFormControlChangeEvent();
}
void SliderThumbElement::startDragging()
@@ -325,16 +331,12 @@ void SliderThumbElement::stopDragging()
m_inDragMode = false;
if (renderer())
renderer()->setNeedsLayout();
-
- RefPtr<HTMLInputElement> input = hostInput();
- if (input)
- input->dispatchFormControlChangeEvent();
}
#if !PLATFORM(IOS)
void SliderThumbElement::defaultEventHandler(Event* event)
{
- if (!is<MouseEvent>(*event)) {
+ if (!event->isMouseEvent()) {
HTMLDivElement::defaultEventHandler(event);
return;
}
@@ -348,9 +350,9 @@ void SliderThumbElement::defaultEventHandler(Event* event)
return;
}
- MouseEvent& mouseEvent = downcast<MouseEvent>(*event);
- bool isLeftButton = mouseEvent.button() == LeftButton;
- const AtomicString& eventType = mouseEvent.type();
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ bool isLeftButton = mouseEvent->button() == LeftButton;
+ const AtomicString& eventType = event->type();
// We intentionally do not call event->setDefaultHandled() here because
// MediaControlTimelineElement::defaultEventHandler() wants to handle these
@@ -363,11 +365,11 @@ void SliderThumbElement::defaultEventHandler(Event* event)
return;
} else if (eventType == eventNames().mousemoveEvent) {
if (m_inDragMode)
- setPositionFromPoint(mouseEvent.absoluteLocation());
+ setPositionFromPoint(mouseEvent->absoluteLocation());
return;
}
- HTMLDivElement::defaultEventHandler(&mouseEvent);
+ HTMLDivElement::defaultEventHandler(event);
}
#endif
@@ -397,12 +399,12 @@ void SliderThumbElement::willDetachRenderers()
if (Frame* frame = document().frame())
frame->eventHandler().setCapturingMouseEventsElement(nullptr);
}
-#if ENABLE(IOS_TOUCH_EVENTS)
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
unregisterForTouchEvents();
#endif
}
-#if ENABLE(IOS_TOUCH_EVENTS)
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
unsigned SliderThumbElement::exclusiveTouchIdentifier() const
{
return m_exclusiveTouchIdentifier;
@@ -419,11 +421,11 @@ void SliderThumbElement::clearExclusiveTouchIdentifier()
m_exclusiveTouchIdentifier = NoIdentifier;
}
-static Touch* findTouchWithIdentifier(TouchList& list, unsigned identifier)
+static Touch* findTouchWithIdentifier(TouchList* list, unsigned identifier)
{
- unsigned length = list.length();
+ unsigned length = list->length();
for (unsigned i = 0; i < length; ++i) {
- Touch* touch = list.item(i);
+ Touch* touch = list->item(i);
if (touch->identifier() == identifier)
return touch;
}
@@ -433,17 +435,12 @@ static Touch* findTouchWithIdentifier(TouchList& list, unsigned identifier)
void SliderThumbElement::handleTouchStart(TouchEvent* touchEvent)
{
TouchList* targetTouches = touchEvent->targetTouches();
- if (!targetTouches)
- return;
-
if (targetTouches->length() != 1)
return;
+ // Ignore the touch if it is not really inside the thumb.
Touch* touch = targetTouches->item(0);
- if (!renderer())
- return;
IntRect boundingBox = renderer()->absoluteBoundingBoxRect();
- // Ignore the touch if it is not really inside the thumb.
if (!boundingBox.contains(touch->pageX(), touch->pageY()))
return;
@@ -459,11 +456,7 @@ void SliderThumbElement::handleTouchMove(TouchEvent* touchEvent)
if (identifier == NoIdentifier)
return;
- TouchList* targetTouches = touchEvent->targetTouches();
- if (!targetTouches)
- return;
-
- Touch* touch = findTouchWithIdentifier(*targetTouches, identifier);
+ Touch* touch = findTouchWithIdentifier(touchEvent->targetTouches(), identifier);
if (!touch)
return;
@@ -478,12 +471,9 @@ void SliderThumbElement::handleTouchEndAndCancel(TouchEvent* touchEvent)
if (identifier == NoIdentifier)
return;
- TouchList* targetTouches = touchEvent->targetTouches();
- if (!targetTouches)
- return;
// If our exclusive touch still exists, it was not the touch
// that ended, so we should not stop dragging.
- Touch* exclusiveTouch = findTouchWithIdentifier(*targetTouches, identifier);
+ Touch* exclusiveTouch = findTouchWithIdentifier(touchEvent->targetTouches(), identifier);
if (exclusiveTouch)
return;
@@ -562,7 +552,7 @@ void SliderThumbElement::disabledAttributeChanged()
else
unregisterForTouchEvents();
}
-#endif // ENABLE(IOS_TOUCH_EVENTS)
+#endif // ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
HTMLInputElement* SliderThumbElement::hostInput() const
{
@@ -574,23 +564,18 @@ HTMLInputElement* SliderThumbElement::hostInput() const
static const AtomicString& sliderThumbShadowPseudoId()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, sliderThumb, ("-webkit-slider-thumb", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, sliderThumb, ("-webkit-slider-thumb", AtomicString::ConstructFromLiteral));
return sliderThumb;
}
static const AtomicString& mediaSliderThumbShadowPseudoId()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderThumb, ("-webkit-media-slider-thumb", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderThumb, ("-webkit-media-slider-thumb", AtomicString::ConstructFromLiteral));
return mediaSliderThumb;
}
const AtomicString& SliderThumbElement::shadowPseudoId() const
{
- // FIXME: this code needs to go away, it is very very wrong.
- // The value of shadowPseudoId() is needed to resolve the style of the shadow tree. In this case,
- // that value depends on the style, which means the style needs to be computed twice to get
- // a correct value: once to get the Input's appearance, then a second time to style the shadow tree correctly.
-
HTMLInputElement* input = hostInput();
if (!input)
return sliderThumbShadowPseudoId();
@@ -611,9 +596,9 @@ const AtomicString& SliderThumbElement::shadowPseudoId() const
}
}
-RefPtr<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren(Document& targetDocument)
+PassRefPtr<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren()
{
- return create(targetDocument);
+ return create(document());
}
// --------------------------------
@@ -623,25 +608,20 @@ inline SliderContainerElement::SliderContainerElement(Document& document)
{
}
-Ref<SliderContainerElement> SliderContainerElement::create(Document& document)
+PassRefPtr<SliderContainerElement> SliderContainerElement::create(Document& document)
{
- return adoptRef(*new SliderContainerElement(document));
+ return adoptRef(new SliderContainerElement(document));
}
-RenderPtr<RenderElement> SliderContainerElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> SliderContainerElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderSliderContainer>(*this, WTF::move(style));
+ return createRenderer<RenderSliderContainer>(*this, std::move(style));
}
const AtomicString& SliderContainerElement::shadowPseudoId() const
{
- // FIXME: this code needs to go away, it is very very wrong.
- // The value of shadowPseudoId() is needed to resolve the style of the shadow tree. In this case,
- // that value depends on the style, which means the style needs to be computed twice to get
- // a correct value: once to get the Input's appearance, then a second time to style the shadow tree correctly.
-
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderContainer, ("-webkit-media-slider-container", AtomicString::ConstructFromLiteral));
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, sliderContainer, ("-webkit-slider-container", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderContainer, ("-webkit-media-slider-container", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, sliderContainer, ("-webkit-slider-container", AtomicString::ConstructFromLiteral));
HTMLInputElement* input = shadowHost()->toInputElement();
if (!input)
diff --git a/Source/WebCore/html/shadow/SliderThumbElement.h b/Source/WebCore/html/shadow/SliderThumbElement.h
index 48ecd5526..a061d63b8 100644
--- a/Source/WebCore/html/shadow/SliderThumbElement.h
+++ b/Source/WebCore/html/shadow/SliderThumbElement.h
@@ -45,14 +45,14 @@ class TouchEvent;
class SliderThumbElement final : public HTMLDivElement {
public:
- static Ref<SliderThumbElement> create(Document&);
+ static PassRefPtr<SliderThumbElement> create(Document&);
void setPositionFromValue();
void dragFrom(const LayoutPoint&);
HTMLInputElement* hostInput() const;
void setPositionFromPoint(const LayoutPoint&);
-#if ENABLE(IOS_TOUCH_EVENTS)
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
void handleTouchEvent(TouchEvent*);
void disabledAttributeChanged();
@@ -61,9 +61,10 @@ public:
private:
SliderThumbElement(Document&);
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
- virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren(Document&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
+ virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() override;
virtual bool isDisabledFormControl() const override;
+ virtual bool matchesReadOnlyPseudoClass() const override;
virtual bool matchesReadWritePseudoClass() const override;
virtual Element* focusDelegate() override;
#if !PLATFORM(IOS)
@@ -72,7 +73,7 @@ private:
virtual bool willRespondToMouseClickEvents() override;
#endif
-#if ENABLE(IOS_TOUCH_EVENTS)
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
virtual void didAttachRenderers() override;
#endif
virtual void willDetachRenderers() override;
@@ -82,7 +83,7 @@ private:
void startDragging();
void stopDragging();
-#if ENABLE(IOS_TOUCH_EVENTS)
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
unsigned exclusiveTouchIdentifier() const;
void setExclusiveTouchIdentifier(unsigned);
void clearExclusiveTouchIdentifier();
@@ -98,25 +99,25 @@ private:
bool m_inDragMode;
-#if ENABLE(IOS_TOUCH_EVENTS)
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
// FIXME: Currently it is safe to use 0, but this may need to change
- // if touch identifiers change in the future and can be 0.
+ // if touch identifers change in the future and can be 0.
static const unsigned NoIdentifier = 0;
unsigned m_exclusiveTouchIdentifier;
bool m_isRegisteredAsTouchEventListener;
#endif
};
-inline Ref<SliderThumbElement> SliderThumbElement::create(Document& document)
+inline PassRefPtr<SliderThumbElement> SliderThumbElement::create(Document& document)
{
- return adoptRef(*new SliderThumbElement(document));
+ return adoptRef(new SliderThumbElement(document));
}
// --------------------------------
class RenderSliderThumb final : public RenderBlockFlow {
public:
- RenderSliderThumb(SliderThumbElement&, Ref<RenderStyle>&&);
+ RenderSliderThumb(SliderThumbElement&, PassRef<RenderStyle>);
void updateAppearance(RenderStyle* parentStyle);
private:
@@ -127,11 +128,11 @@ private:
class SliderContainerElement final : public HTMLDivElement {
public:
- static Ref<SliderContainerElement> create(Document&);
+ static PassRefPtr<SliderContainerElement> create(Document&);
private:
SliderContainerElement(Document&);
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
virtual const AtomicString& shadowPseudoId() const override;
};
diff --git a/Source/WebCore/html/shadow/SpinButtonElement.cpp b/Source/WebCore/html/shadow/SpinButtonElement.cpp
index c00b61937..5e4711a68 100644
--- a/Source/WebCore/html/shadow/SpinButtonElement.cpp
+++ b/Source/WebCore/html/shadow/SpinButtonElement.cpp
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -49,15 +49,20 @@ inline SpinButtonElement::SpinButtonElement(Document& document, SpinButtonOwner&
, m_capturing(false)
, m_upDownState(Indeterminate)
, m_pressStartingState(Indeterminate)
- , m_repeatingTimer(*this, &SpinButtonElement::repeatingTimerFired)
+ , m_repeatingTimer(this, &SpinButtonElement::repeatingTimerFired)
{
setHasCustomStyleResolveCallbacks();
- setPseudo(AtomicString("-webkit-inner-spin-button", AtomicString::ConstructFromLiteral));
}
-Ref<SpinButtonElement> SpinButtonElement::create(Document& document, SpinButtonOwner& spinButtonOwner)
+PassRefPtr<SpinButtonElement> SpinButtonElement::create(Document& document, SpinButtonOwner& spinButtonOwner)
{
- return adoptRef(*new SpinButtonElement(document, spinButtonOwner));
+ return adoptRef(new SpinButtonElement(document, spinButtonOwner));
+}
+
+const AtomicString& SpinButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, innerPseudoId, ("-webkit-inner-spin-button", AtomicString::ConstructFromLiteral));
+ return innerPseudoId;
}
void SpinButtonElement::willDetachRenderers()
@@ -67,7 +72,7 @@ void SpinButtonElement::willDetachRenderers()
void SpinButtonElement::defaultEventHandler(Event* event)
{
- if (!is<MouseEvent>(*event)) {
+ if (!event->isMouseEvent()) {
if (!event->defaultHandled())
HTMLDivElement::defaultEventHandler(event);
return;
@@ -86,9 +91,9 @@ void SpinButtonElement::defaultEventHandler(Event* event)
return;
}
- MouseEvent& mouseEvent = downcast<MouseEvent>(*event);
- IntPoint local = roundedIntPoint(box->absoluteToLocal(mouseEvent.absoluteLocation(), UseTransforms));
- if (mouseEvent.type() == eventNames().mousedownEvent && mouseEvent.button() == LeftButton) {
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ IntPoint local = roundedIntPoint(box->absoluteToLocal(mouseEvent->absoluteLocation(), UseTransforms));
+ if (mouseEvent->type() == eventNames().mousedownEvent && mouseEvent->button() == LeftButton) {
if (box->pixelSnappedBorderBoxRect().contains(local)) {
// The following functions of HTMLInputElement may run JavaScript
// code which detaches this shadow node. We need to take a reference
@@ -107,11 +112,11 @@ void SpinButtonElement::defaultEventHandler(Event* event)
doStepAction(m_upDownState == Up ? 1 : -1);
}
}
- mouseEvent.setDefaultHandled();
+ event->setDefaultHandled();
}
- } else if (mouseEvent.type() == eventNames().mouseupEvent && mouseEvent.button() == LeftButton)
+ } else if (mouseEvent->type() == eventNames().mouseupEvent && mouseEvent->button() == LeftButton)
stopRepeatingTimer();
- else if (mouseEvent.type() == eventNames().mousemoveEvent) {
+ else if (event->type() == eventNames().mousemoveEvent) {
if (box->pixelSnappedBorderBoxRect().contains(local)) {
if (!m_capturing) {
if (Frame* frame = document().frame()) {
@@ -131,8 +136,8 @@ void SpinButtonElement::defaultEventHandler(Event* event)
}
}
- if (!mouseEvent.defaultHandled())
- HTMLDivElement::defaultEventHandler(&mouseEvent);
+ if (!event->defaultHandled())
+ HTMLDivElement::defaultEventHandler(event);
}
void SpinButtonElement::willOpenPopup()
@@ -146,7 +151,7 @@ void SpinButtonElement::forwardEvent(Event* event)
if (!renderBox())
return;
- if (!is<WheelEvent>(*event))
+ if (event->eventInterface() != WheelEventInterfaceType)
return;
if (!m_spinButtonOwner)
@@ -155,7 +160,7 @@ void SpinButtonElement::forwardEvent(Event* event)
if (!m_spinButtonOwner->shouldSpinButtonRespondToWheelEvents())
return;
- doStepAction(downcast<WheelEvent>(*event).wheelDeltaY());
+ doStepAction(static_cast<WheelEvent*>(event)->wheelDeltaY());
event->setDefaultHandled();
}
@@ -199,6 +204,11 @@ void SpinButtonElement::releaseCapture()
}
}
+bool SpinButtonElement::matchesReadOnlyPseudoClass() const
+{
+ return shadowHost()->matchesReadOnlyPseudoClass();
+}
+
bool SpinButtonElement::matchesReadWritePseudoClass() const
{
return shadowHost()->matchesReadWritePseudoClass();
@@ -230,7 +240,7 @@ void SpinButtonElement::step(int amount)
doStepAction(amount);
}
-void SpinButtonElement::repeatingTimerFired()
+void SpinButtonElement::repeatingTimerFired(Timer<SpinButtonElement>*)
{
if (m_upDownState != Indeterminate)
step(m_upDownState == Up ? 1 : -1);
diff --git a/Source/WebCore/html/shadow/SpinButtonElement.h b/Source/WebCore/html/shadow/SpinButtonElement.h
index 72995f605..eb8bb3d8e 100644
--- a/Source/WebCore/html/shadow/SpinButtonElement.h
+++ b/Source/WebCore/html/shadow/SpinButtonElement.h
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -54,9 +54,9 @@ public:
// The owner of SpinButtonElement must call removeSpinButtonOwner
// because SpinButtonElement can be outlive SpinButtonOwner
// implementation, e.g. during event handling.
- static Ref<SpinButtonElement> create(Document&, SpinButtonOwner&);
+ static PassRefPtr<SpinButtonElement> create(Document&, SpinButtonOwner&);
UpDownState upDownState() const { return m_upDownState; }
- void releaseCapture();
+ virtual void releaseCapture();
void removeSpinButtonOwner() { m_spinButtonOwner = 0; }
void step(int amount);
@@ -69,16 +69,18 @@ public:
private:
SpinButtonElement(Document&, SpinButtonOwner&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual void willDetachRenderers() override;
virtual bool isSpinButtonElement() const override { return true; }
virtual bool isDisabledFormControl() const override { return shadowHost() && shadowHost()->isDisabledFormControl(); }
+ virtual bool matchesReadOnlyPseudoClass() const override;
virtual bool matchesReadWritePseudoClass() const override;
virtual void defaultEventHandler(Event*) override;
virtual void willOpenPopup() override;
void doStepAction(int);
void startRepeatingTimer();
void stopRepeatingTimer();
- void repeatingTimerFired();
+ void repeatingTimerFired(Timer<SpinButtonElement>*);
virtual void setHovered(bool = true) override;
bool shouldRespondToMouseEvents();
virtual bool isMouseFocusable() const override { return false; }
@@ -87,14 +89,9 @@ private:
bool m_capturing;
UpDownState m_upDownState;
UpDownState m_pressStartingState;
- Timer m_repeatingTimer;
+ Timer<SpinButtonElement> m_repeatingTimer;
};
-} // namespace WebCore
+} // namespace
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SpinButtonElement)
- static bool isType(const WebCore::Element& element) { return element.isSpinButtonElement(); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
-
-#endif // SpinButtonElement_h
+#endif
diff --git a/Source/WebCore/html/shadow/TextControlInnerElements.cpp b/Source/WebCore/html/shadow/TextControlInnerElements.cpp
index 9916b8e05..ac35831f3 100644
--- a/Source/WebCore/html/shadow/TextControlInnerElements.cpp
+++ b/Source/WebCore/html/shadow/TextControlInnerElements.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2008, 2010, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2008, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,17 +28,18 @@
#include "TextControlInnerElements.h"
#include "Document.h"
+#include "EventHandler.h"
#include "EventNames.h"
#include "Frame.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
-#include "LocalizedStrings.h"
#include "MouseEvent.h"
-#include "PlatformMouseEvent.h"
#include "RenderSearchField.h"
#include "RenderTextControl.h"
#include "RenderView.h"
#include "ScriptController.h"
+#include "SpeechInput.h"
+#include "SpeechInputEvent.h"
#include "TextEvent.h"
#include "TextEventInputType.h"
#include <wtf/Ref.h>
@@ -52,14 +53,14 @@ TextControlInnerContainer::TextControlInnerContainer(Document& document)
{
}
-Ref<TextControlInnerContainer> TextControlInnerContainer::create(Document& document)
+PassRefPtr<TextControlInnerContainer> TextControlInnerContainer::create(Document& document)
{
- return adoptRef(*new TextControlInnerContainer(document));
+ return adoptRef(new TextControlInnerContainer(document));
}
-RenderPtr<RenderElement> TextControlInnerContainer::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> TextControlInnerContainer::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderTextControlInnerContainer>(*this, WTF::move(style));
+ return createRenderer<RenderTextControlInnerContainer>(*this, std::move(style));
}
TextControlInnerElement::TextControlInnerElement(Document& document)
@@ -68,15 +69,15 @@ TextControlInnerElement::TextControlInnerElement(Document& document)
setHasCustomStyleResolveCallbacks();
}
-Ref<TextControlInnerElement> TextControlInnerElement::create(Document& document)
+PassRefPtr<TextControlInnerElement> TextControlInnerElement::create(Document& document)
{
- return adoptRef(*new TextControlInnerElement(document));
+ return adoptRef(new TextControlInnerElement(document));
}
-RefPtr<RenderStyle> TextControlInnerElement::customStyleForRenderer(RenderStyle&)
+PassRefPtr<RenderStyle> TextControlInnerElement::customStyleForRenderer()
{
- RenderTextControlSingleLine& parentRenderer = downcast<RenderTextControlSingleLine>(*shadowHost()->renderer());
- return parentRenderer.createInnerBlockStyle(&parentRenderer.style());
+ RenderTextControlSingleLine* parentRenderer = toRenderTextControlSingleLine(shadowHost()->renderer());
+ return parentRenderer->createInnerBlockStyle(&parentRenderer->style());
}
// ---------------------------
@@ -87,9 +88,9 @@ inline TextControlInnerTextElement::TextControlInnerTextElement(Document& docume
setHasCustomStyleResolveCallbacks();
}
-Ref<TextControlInnerTextElement> TextControlInnerTextElement::create(Document& document)
+PassRefPtr<TextControlInnerTextElement> TextControlInnerTextElement::create(Document& document)
{
- return adoptRef(*new TextControlInnerTextElement(document));
+ return adoptRef(new TextControlInnerTextElement(document));
}
void TextControlInnerTextElement::defaultEventHandler(Event* event)
@@ -111,20 +112,20 @@ void TextControlInnerTextElement::defaultEventHandler(Event* event)
HTMLDivElement::defaultEventHandler(event);
}
-RenderPtr<RenderElement> TextControlInnerTextElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
+RenderPtr<RenderElement> TextControlInnerTextElement::createElementRenderer(PassRef<RenderStyle> style)
{
- return createRenderer<RenderTextControlInnerBlock>(*this, WTF::move(style));
+ return createRenderer<RenderTextControlInnerBlock>(*this, std::move(style));
}
RenderTextControlInnerBlock* TextControlInnerTextElement::renderer() const
{
- return downcast<RenderTextControlInnerBlock>(HTMLDivElement::renderer());
+ return toRenderTextControlInnerBlock(HTMLDivElement::renderer());
}
-RefPtr<RenderStyle> TextControlInnerTextElement::customStyleForRenderer(RenderStyle&)
+PassRefPtr<RenderStyle> TextControlInnerTextElement::customStyleForRenderer()
{
- RenderTextControl& parentRenderer = downcast<RenderTextControl>(*shadowHost()->renderer());
- return parentRenderer.createInnerTextStyle(&parentRenderer.style());
+ RenderTextControl* parentRenderer = toRenderTextControl(shadowHost()->renderer());
+ return parentRenderer->createInnerTextStyle(&parentRenderer->style());
}
// ----------------------------
@@ -134,26 +135,42 @@ inline SearchFieldResultsButtonElement::SearchFieldResultsButtonElement(Document
{
}
-Ref<SearchFieldResultsButtonElement> SearchFieldResultsButtonElement::create(Document& document)
+PassRefPtr<SearchFieldResultsButtonElement> SearchFieldResultsButtonElement::create(Document& document)
{
- return adoptRef(*new SearchFieldResultsButtonElement(document));
+ return adoptRef(new SearchFieldResultsButtonElement(document));
+}
+
+const AtomicString& SearchFieldResultsButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, resultsId, ("-webkit-search-results-button", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, resultsDecorationId, ("-webkit-search-results-decoration", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, decorationId, ("-webkit-search-decoration", AtomicString::ConstructFromLiteral));
+ Element* host = shadowHost();
+ if (!host)
+ return resultsId;
+ if (HTMLInputElement* input = host->toInputElement()) {
+ if (input->maxResults() < 0)
+ return decorationId;
+ if (input->maxResults() > 0)
+ return resultsId;
+ return resultsDecorationId;
+ }
+ return resultsId;
}
void SearchFieldResultsButtonElement::defaultEventHandler(Event* event)
{
// On mousedown, bring up a menu, if needed
- HTMLInputElement* input = downcast<HTMLInputElement>(shadowHost());
- if (input && event->type() == eventNames().mousedownEvent && is<MouseEvent>(*event) && downcast<MouseEvent>(*event).button() == LeftButton) {
+ HTMLInputElement* input = toHTMLInputElement(shadowHost());
+ if (input && event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
input->focus();
input->select();
#if !PLATFORM(IOS)
- if (RenderObject* renderer = input->renderer()) {
- RenderSearchField& searchFieldRenderer = downcast<RenderSearchField>(*renderer);
- if (searchFieldRenderer.popupIsVisible())
- searchFieldRenderer.hidePopup();
- else if (input->maxResults() > 0)
- searchFieldRenderer.showPopup();
- }
+ RenderSearchField* renderer = toRenderSearchField(input->renderer());
+ if (renderer->popupIsVisible())
+ renderer->hidePopup();
+ else if (input->maxResults() > 0)
+ renderer->showPopup();
#endif
event->setDefaultHandled();
}
@@ -173,37 +190,163 @@ bool SearchFieldResultsButtonElement::willRespondToMouseClickEvents()
inline SearchFieldCancelButtonElement::SearchFieldCancelButtonElement(Document& document)
: HTMLDivElement(divTag, document)
+ , m_capturing(false)
+{
+ setHasCustomStyleResolveCallbacks();
+}
+
+PassRefPtr<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::create(Document& document)
+{
+ return adoptRef(new SearchFieldCancelButtonElement(document));
+}
+
+const AtomicString& SearchFieldCancelButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-search-cancel-button", AtomicString::ConstructFromLiteral));
+ return pseudoId;
+}
+
+void SearchFieldCancelButtonElement::willDetachRenderers()
{
- setPseudo(AtomicString("-webkit-search-cancel-button", AtomicString::ConstructFromLiteral));
+ if (m_capturing) {
+ if (Frame* frame = document().frame())
+ frame->eventHandler().setCapturingMouseEventsElement(nullptr);
+ }
+}
+
+void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
+{
+ // If the element is visible, on mouseup, clear the value, and set selection
+ RefPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost()));
+ if (!input || input->isDisabledOrReadOnly()) {
+ if (!event->defaultHandled())
+ HTMLDivElement::defaultEventHandler(event);
+ return;
+ }
+
+ if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
+ if (renderer() && renderer()->visibleToHitTesting()) {
+ if (Frame* frame = document().frame()) {
+ frame->eventHandler().setCapturingMouseEventsElement(this);
+ m_capturing = true;
+ }
+ }
+ input->focus();
+ input->select();
+ event->setDefaultHandled();
+ }
+ if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
+ if (m_capturing) {
+ if (Frame* frame = document().frame()) {
+ frame->eventHandler().setCapturingMouseEventsElement(nullptr);
+ m_capturing = false;
+ }
+ if (hovered()) {
+ String oldValue = input->value();
+ input->setValueForUser("");
+ input->onSearch();
+ event->setDefaultHandled();
+ }
+ }
+ }
+
+ if (!event->defaultHandled())
+ HTMLDivElement::defaultEventHandler(event);
+}
+
#if !PLATFORM(IOS)
- setAttribute(aria_labelAttr, AXSearchFieldCancelButtonText());
+bool SearchFieldCancelButtonElement::willRespondToMouseClickEvents()
+{
+ const HTMLInputElement* input = toHTMLInputElement(shadowHost());
+ if (input && !input->isDisabledOrReadOnly())
+ return true;
+
+ return HTMLDivElement::willRespondToMouseClickEvents();
+}
#endif
- setAttribute(roleAttr, AtomicString("button", AtomicString::ConstructFromLiteral));
+
+// ----------------------------
+
+#if ENABLE(INPUT_SPEECH)
+
+inline InputFieldSpeechButtonElement::InputFieldSpeechButtonElement(Document& document)
+ : HTMLDivElement(divTag, document)
+ , m_capturing(false)
+ , m_state(Idle)
+ , m_listenerId(0)
+{
+ setHasCustomStyleResolveCallbacks();
}
-Ref<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::create(Document& document)
+InputFieldSpeechButtonElement::~InputFieldSpeechButtonElement()
{
- return adoptRef(*new SearchFieldCancelButtonElement(document));
+ SpeechInput* speech = speechInput();
+ if (speech && m_listenerId) { // Could be null when page is unloading.
+ if (m_state != Idle)
+ speech->cancelRecognition(m_listenerId);
+ speech->unregisterListener(m_listenerId);
+ }
}
-void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
+PassRefPtr<InputFieldSpeechButtonElement> InputFieldSpeechButtonElement::create(Document& document)
+{
+ return adoptRef(new InputFieldSpeechButtonElement(document));
+}
+
+void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
{
- RefPtr<HTMLInputElement> input(downcast<HTMLInputElement>(shadowHost()));
+ // For privacy reasons, only allow clicks directly coming from the user.
+ if (!ScriptController::processingUserGesture()) {
+ HTMLDivElement::defaultEventHandler(event);
+ return;
+ }
+
+ // The call to focus() below dispatches a focus event, and an event handler in the page might
+ // remove the input element from DOM. To make sure it remains valid until we finish our work
+ // here, we take a temporary reference.
+ RefPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost()));
+
if (!input || input->isDisabledOrReadOnly()) {
if (!event->defaultHandled())
HTMLDivElement::defaultEventHandler(event);
return;
}
- if (event->type() == eventNames().mousedownEvent && is<MouseEvent>(*event) && downcast<MouseEvent>(*event).button() == LeftButton) {
+ // On mouse down, select the text and set focus.
+ if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
+ if (renderer() && renderer()->visibleToHitTesting()) {
+ if (Frame* frame = document().frame()) {
+ frame->eventHandler().setCapturingMouseEventsElement(this);
+ m_capturing = true;
+ }
+ }
+ Ref<InputFieldSpeechButtonElement> protect(*this);
input->focus();
input->select();
event->setDefaultHandled();
}
+ // On mouse up, release capture cleanly.
+ if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
+ if (m_capturing && renderer() && renderer()->visibleToHitTesting()) {
+ if (Frame* frame = document().frame()) {
+ frame->eventHandler().setCapturingMouseEventsElement(nullptr);
+ m_capturing = false;
+ }
+ }
+ }
- if (event->type() == eventNames().clickEvent) {
- input->setValueForUser(emptyString());
- input->onSearch();
+ if (event->type() == eventNames().clickEvent && m_listenerId) {
+ switch (m_state) {
+ case Idle:
+ startSpeechInput();
+ break;
+ case Recording:
+ stopSpeechInput();
+ break;
+ case Recognizing:
+ // Nothing to do here, we will continue to wait for results.
+ break;
+ }
event->setDefaultHandled();
}
@@ -212,9 +355,9 @@ void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
}
#if !PLATFORM(IOS)
-bool SearchFieldCancelButtonElement::willRespondToMouseClickEvents()
+bool InputFieldSpeechButtonElement::willRespondToMouseClickEvents()
{
- const HTMLInputElement* input = downcast<HTMLInputElement>(shadowHost());
+ const HTMLInputElement* input = toHTMLInputElement(shadowHost());
if (input && !input->isDisabledOrReadOnly())
return true;
@@ -222,4 +365,106 @@ bool SearchFieldCancelButtonElement::willRespondToMouseClickEvents()
}
#endif
+void InputFieldSpeechButtonElement::setState(SpeechInputState state)
+{
+ if (m_state != state) {
+ m_state = state;
+ shadowHost()->renderer()->repaint();
+ }
+}
+
+SpeechInput* InputFieldSpeechButtonElement::speechInput()
+{
+ return SpeechInput::from(document().page());
+}
+
+void InputFieldSpeechButtonElement::didCompleteRecording(int)
+{
+ setState(Recognizing);
+}
+
+void InputFieldSpeechButtonElement::didCompleteRecognition(int)
+{
+ setState(Idle);
+}
+
+void InputFieldSpeechButtonElement::setRecognitionResult(int, const SpeechInputResultArray& results)
+{
+ m_results = results;
+
+ // The call to setValue() below dispatches an event, and an event handler in the page might
+ // remove the input element from DOM. To make sure it remains valid until we finish our work
+ // here, we take a temporary reference.
+ RefPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost()));
+ if (!input || input->isDisabledOrReadOnly())
+ return;
+
+ Ref<InputFieldSpeechButtonElement> protect(*this);
+ if (document().domWindow()) {
+ // Call selectionChanged, causing the element to cache the selection,
+ // so that the text event inserts the text in this element even if
+ // focus has moved away from it.
+ input->selectionChanged(false);
+ input->dispatchEvent(TextEvent::create(document().domWindow(), results.isEmpty() ? "" : results[0]->utterance(), TextEventInputOther));
+ }
+
+ // This event is sent after the text event so the website can perform actions using the input field content immediately.
+ // It provides alternative recognition hypotheses and notifies that the results come from speech input.
+ input->dispatchEvent(SpeechInputEvent::create(eventNames().webkitspeechchangeEvent, results));
+
+ // Check before accessing the renderer as the above event could have potentially turned off
+ // speech in the input element, hence removing this button and renderer from the hierarchy.
+ if (renderer())
+ renderer()->repaint();
+}
+
+void InputFieldSpeechButtonElement::willAttachRenderers()
+{
+ ASSERT(!m_listenerId);
+ if (SpeechInput* input = SpeechInput::from(document().page()))
+ m_listenerId = input->registerListener(this);
+}
+
+void InputFieldSpeechButtonElement::willDetachRenderers()
+{
+ if (m_capturing) {
+ if (Frame* frame = document().frame())
+ frame->eventHandler().setCapturingMouseEventsElement(nullptr);
+ }
+
+ if (m_listenerId) {
+ if (m_state != Idle)
+ speechInput()->cancelRecognition(m_listenerId);
+ speechInput()->unregisterListener(m_listenerId);
+ m_listenerId = 0;
+ }
+}
+
+void InputFieldSpeechButtonElement::startSpeechInput()
+{
+ if (m_state != Idle)
+ return;
+
+ RefPtr<HTMLInputElement> input = toHTMLInputElement(shadowHost());
+ AtomicString language = input->computeInheritedLanguage();
+ String grammar = input->getAttribute(webkitgrammarAttr);
+ IntRect rect = document().view()->contentsToRootView(pixelSnappedBoundingBox());
+ if (speechInput()->startRecognition(m_listenerId, rect, language, grammar, document().securityOrigin()))
+ setState(Recording);
+}
+
+void InputFieldSpeechButtonElement::stopSpeechInput()
+{
+ if (m_state == Recording)
+ speechInput()->stopRecording(m_listenerId);
+}
+
+const AtomicString& InputFieldSpeechButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-input-speech-button", AtomicString::ConstructFromLiteral));
+ return pseudoId;
+}
+
+#endif // ENABLE(INPUT_SPEECH)
+
}
diff --git a/Source/WebCore/html/shadow/TextControlInnerElements.h b/Source/WebCore/html/shadow/TextControlInnerElements.h
index 6cfa55065..73e79c230 100644
--- a/Source/WebCore/html/shadow/TextControlInnerElements.h
+++ b/Source/WebCore/html/shadow/TextControlInnerElements.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2008, 2010, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2008, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,27 +28,29 @@
#define TextControlInnerElements_h
#include "HTMLDivElement.h"
+#include "SpeechInputListener.h"
#include <wtf/Forward.h>
namespace WebCore {
class RenderTextControlInnerBlock;
+class SpeechInput;
class TextControlInnerContainer final : public HTMLDivElement {
public:
- static Ref<TextControlInnerContainer> create(Document&);
+ static PassRefPtr<TextControlInnerContainer> create(Document&);
protected:
TextControlInnerContainer(Document&);
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
};
class TextControlInnerElement final : public HTMLDivElement {
public:
- static Ref<TextControlInnerElement> create(Document&);
+ static PassRefPtr<TextControlInnerElement> create(Document&);
protected:
TextControlInnerElement(Document&);
- virtual RefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle) override;
+ virtual PassRefPtr<RenderStyle> customStyleForRenderer() override;
private:
virtual bool isMouseFocusable() const override { return false; }
@@ -56,7 +58,7 @@ private:
class TextControlInnerTextElement final : public HTMLDivElement {
public:
- static Ref<TextControlInnerTextElement> create(Document&);
+ static PassRefPtr<TextControlInnerTextElement> create(Document&);
virtual void defaultEventHandler(Event*) override;
@@ -64,15 +66,19 @@ public:
private:
TextControlInnerTextElement(Document&);
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override;
- virtual RefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle) override;
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
+ virtual PassRefPtr<RenderStyle> customStyleForRenderer() override;
virtual bool isMouseFocusable() const override { return false; }
virtual bool isTextControlInnerTextElement() const override { return true; }
};
+inline bool isTextControlInnerTextElement(const HTMLElement& element) { return element.isTextControlInnerTextElement(); }
+inline bool isTextControlInnerTextElement(const Node& node) { return node.isHTMLElement() && isTextControlInnerTextElement(toHTMLElement(node)); }
+NODE_TYPE_CASTS(TextControlInnerTextElement)
+
class SearchFieldResultsButtonElement final : public HTMLDivElement {
public:
- static Ref<SearchFieldResultsButtonElement> create(Document&);
+ static PassRefPtr<SearchFieldResultsButtonElement> create(Document&);
virtual void defaultEventHandler(Event*) override;
#if !PLATFORM(IOS)
@@ -81,28 +87,82 @@ public:
private:
SearchFieldResultsButtonElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
virtual bool isMouseFocusable() const override { return false; }
};
class SearchFieldCancelButtonElement final : public HTMLDivElement {
public:
- static Ref<SearchFieldCancelButtonElement> create(Document&);
+ static PassRefPtr<SearchFieldCancelButtonElement> create(Document&);
virtual void defaultEventHandler(Event*) override;
+ virtual bool isSearchFieldCancelButtonElement() const override { return true; }
#if !PLATFORM(IOS)
virtual bool willRespondToMouseClickEvents() override;
#endif
private:
SearchFieldCancelButtonElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const override;
+ virtual void willDetachRenderers() override;
virtual bool isMouseFocusable() const override { return false; }
+
+ bool m_capturing;
};
-} // namespace WebCore
+#if ENABLE(INPUT_SPEECH)
+
+class InputFieldSpeechButtonElement final
+ : public HTMLDivElement,
+ public SpeechInputListener {
+public:
+ enum SpeechInputState {
+ Idle,
+ Recording,
+ Recognizing,
+ };
+
+ static PassRefPtr<InputFieldSpeechButtonElement> create(Document&);
+ virtual ~InputFieldSpeechButtonElement();
+
+ virtual void defaultEventHandler(Event*);
+#if !PLATFORM(IOS)
+ virtual bool willRespondToMouseClickEvents();
+#endif
+ virtual bool isInputFieldSpeechButtonElement() const { return true; }
+ SpeechInputState state() const { return m_state; }
+ void startSpeechInput();
+ void stopSpeechInput();
+
+ // SpeechInputListener methods.
+ void didCompleteRecording(int);
+ void didCompleteRecognition(int);
+ void setRecognitionResult(int, const SpeechInputResultArray&);
+
+private:
+ InputFieldSpeechButtonElement(Document&);
+ SpeechInput* speechInput();
+ void setState(SpeechInputState state);
+ virtual const AtomicString& shadowPseudoId() const;
+ virtual bool isMouseFocusable() const override { return false; }
+ virtual void willAttachRenderers() override;
+ virtual void willDetachRenderers() override;
+
+
+ bool m_capturing;
+ SpeechInputState m_state;
+ int m_listenerId;
+ SpeechInputResultArray m_results;
+};
+
+inline InputFieldSpeechButtonElement* toInputFieldSpeechButtonElement(Element* element)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!element || element->isInputFieldSpeechButtonElement());
+ return static_cast<InputFieldSpeechButtonElement*>(element);
+}
+
+#endif // ENABLE(INPUT_SPEECH)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::TextControlInnerTextElement)
- static bool isType(const WebCore::HTMLElement& element) { return element.isTextControlInnerTextElement(); }
- static bool isType(const WebCore::Node& node) { return is<WebCore::HTMLElement>(node) && isType(downcast<WebCore::HTMLElement>(node)); }
-SPECIALIZE_TYPE_TRAITS_END()
+} // namespace
#endif
diff --git a/Source/WebCore/html/shadow/YouTubeEmbedShadowElement.cpp b/Source/WebCore/html/shadow/YouTubeEmbedShadowElement.cpp
deleted file mode 100644
index 695fafd46..000000000
--- a/Source/WebCore/html/shadow/YouTubeEmbedShadowElement.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "YouTubeEmbedShadowElement.h"
-
-#include "HTMLEmbedElement.h"
-
-namespace WebCore {
-
-Ref<YouTubeEmbedShadowElement> YouTubeEmbedShadowElement::create(Document& doc)
-{
- return adoptRef(*new YouTubeEmbedShadowElement(doc));
-}
-
-YouTubeEmbedShadowElement::YouTubeEmbedShadowElement(Document& document)
- : HTMLDivElement(HTMLNames::divTag, document)
-{
- setPseudo(AtomicString("-webkit-plugin-replacement", AtomicString::ConstructFromLiteral));
-
- setInlineStyleProperty(CSSPropertyDisplay, CSSValueInlineBlock);
- setInlineStyleProperty(CSSPropertyPosition, CSSValueRelative);
- setInlineStyleProperty(CSSPropertyWidth, CSSValue100);
- setInlineStyleProperty(CSSPropertyHeight, CSSValue100);
-}
-
-}
diff --git a/Source/WebCore/html/shadow/YouTubeEmbedShadowElement.h b/Source/WebCore/html/shadow/YouTubeEmbedShadowElement.h
deleted file mode 100644
index 54158bc0a..000000000
--- a/Source/WebCore/html/shadow/YouTubeEmbedShadowElement.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef YouTubeEmbedShadowElement_h
-#define YouTubeEmbedShadowElement_h
-
-#include "HTMLDivElement.h"
-#include <wtf/Forward.h>
-
-namespace WebCore {
-
-class YouTubeEmbedShadowElement final : public HTMLDivElement {
-public:
- static Ref<YouTubeEmbedShadowElement> create(Document&);
-
-private:
- YouTubeEmbedShadowElement(Document&);
-};
-
-}
-
-#endif // YouTubeEmbedShadowElement_h
diff --git a/Source/WebCore/html/track/AudioTrack.cpp b/Source/WebCore/html/track/AudioTrack.cpp
index 873292545..aecdb0af6 100644
--- a/Source/WebCore/html/track/AudioTrack.cpp
+++ b/Source/WebCore/html/track/AudioTrack.cpp
@@ -43,37 +43,37 @@ namespace WebCore {
const AtomicString& AudioTrack::alternativeKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, alternative, ("alternative", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, alternative, ("alternative", AtomicString::ConstructFromLiteral));
return alternative;
}
const AtomicString& AudioTrack::descriptionKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, description, ("description", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, description, ("description", AtomicString::ConstructFromLiteral));
return description;
}
const AtomicString& AudioTrack::mainKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, main, ("main", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, main, ("main", AtomicString::ConstructFromLiteral));
return main;
}
const AtomicString& AudioTrack::mainDescKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, mainDesc, ("main-desc", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, mainDesc, ("main-desc", AtomicString::ConstructFromLiteral));
return mainDesc;
}
const AtomicString& AudioTrack::translationKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, translation, ("translation", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, translation, ("translation", AtomicString::ConstructFromLiteral));
return translation;
}
const AtomicString& AudioTrack::commentaryKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, commentary, ("commentary", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, commentary, ("commentary", AtomicString::ConstructFromLiteral));
return commentary;
}
@@ -84,28 +84,38 @@ AudioTrack::AudioTrack(AudioTrackClient* client, PassRefPtr<AudioTrackPrivate> t
, m_private(trackPrivate)
{
m_private->setClient(this);
- updateKindFromPrivate();
-}
-AudioTrack::~AudioTrack()
-{
- m_private->setClient(0);
+ switch (m_private->kind()) {
+ case AudioTrackPrivate::Alternative:
+ setKind(AudioTrack::alternativeKeyword());
+ break;
+ case AudioTrackPrivate::Description:
+ setKind(AudioTrack::descriptionKeyword());
+ break;
+ case AudioTrackPrivate::Main:
+ setKind(AudioTrack::mainKeyword());
+ break;
+ case AudioTrackPrivate::MainDesc:
+ setKind(AudioTrack::mainDescKeyword());
+ break;
+ case AudioTrackPrivate::Translation:
+ setKind(AudioTrack::translationKeyword());
+ break;
+ case AudioTrackPrivate::Commentary:
+ setKind(AudioTrack::commentaryKeyword());
+ break;
+ case AudioTrackPrivate::None:
+ setKind(emptyString());
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
}
-void AudioTrack::setPrivate(PassRefPtr<AudioTrackPrivate> trackPrivate)
+AudioTrack::~AudioTrack()
{
- ASSERT(m_private);
- ASSERT(trackPrivate);
-
- if (m_private == trackPrivate)
- return;
-
m_private->setClient(0);
- m_private = trackPrivate;
- m_private->setClient(this);
-
- m_private->setEnabled(m_enabled);
- updateKindFromPrivate();
}
bool AudioTrack::isValidKind(const AtomicString& value) const
@@ -147,25 +157,22 @@ size_t AudioTrack::inbandTrackIndex()
void AudioTrack::enabledChanged(AudioTrackPrivate* trackPrivate, bool enabled)
{
ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
- m_enabled = enabled;
-
- if (m_client)
- m_client->audioTrackEnabledChanged(this);
+ setEnabled(enabled);
}
-void AudioTrack::idChanged(TrackPrivateBase* trackPrivate, const AtomicString& id)
+void AudioTrack::idChanged(TrackPrivateBase* trackPrivate, const String& id)
{
ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
setId(id);
}
-void AudioTrack::labelChanged(TrackPrivateBase* trackPrivate, const AtomicString& label)
+void AudioTrack::labelChanged(TrackPrivateBase* trackPrivate, const String& label)
{
ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
setLabel(label);
}
-void AudioTrack::languageChanged(TrackPrivateBase* trackPrivate, const AtomicString& language)
+void AudioTrack::languageChanged(TrackPrivateBase* trackPrivate, const String& language)
{
ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
setLanguage(language);
@@ -177,36 +184,6 @@ void AudioTrack::willRemove(TrackPrivateBase* trackPrivate)
mediaElement()->removeAudioTrack(this);
}
-void AudioTrack::updateKindFromPrivate()
-{
- switch (m_private->kind()) {
- case AudioTrackPrivate::Alternative:
- setKind(AudioTrack::alternativeKeyword());
- break;
- case AudioTrackPrivate::Description:
- setKind(AudioTrack::descriptionKeyword());
- break;
- case AudioTrackPrivate::Main:
- setKind(AudioTrack::mainKeyword());
- break;
- case AudioTrackPrivate::MainDesc:
- setKind(AudioTrack::mainDescKeyword());
- break;
- case AudioTrackPrivate::Translation:
- setKind(AudioTrack::translationKeyword());
- break;
- case AudioTrackPrivate::Commentary:
- setKind(AudioTrack::commentaryKeyword());
- break;
- case AudioTrackPrivate::None:
- setKind(emptyString());
- break;
- default:
- ASSERT_NOT_REACHED();
- break;
- }
-}
-
} // namespace WebCore
#endif
diff --git a/Source/WebCore/html/track/AudioTrack.h b/Source/WebCore/html/track/AudioTrack.h
index c99d5481b..29c5bd4c0 100644
--- a/Source/WebCore/html/track/AudioTrack.h
+++ b/Source/WebCore/html/track/AudioTrack.h
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -27,13 +27,12 @@
#ifndef AudioTrack_h
#define AudioTrack_h
-#include "PlatformExportMacros.h"
-
#if ENABLE(VIDEO_TRACK)
#include "AudioTrackPrivate.h"
#include "ExceptionCode.h"
#include "TrackBase.h"
+#include <wtf/PassOwnPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
@@ -47,11 +46,11 @@ public:
virtual void audioTrackEnabledChanged(AudioTrack*) = 0;
};
-class AudioTrack final : public TrackBase, public AudioTrackPrivateClient {
+class AudioTrack : public TrackBase, public AudioTrackPrivateClient {
public:
- static Ref<AudioTrack> create(AudioTrackClient* client, PassRefPtr<AudioTrackPrivate> trackPrivate)
+ static PassRefPtr<AudioTrack> create(AudioTrackClient* client, PassRefPtr<AudioTrackPrivate> trackPrivate)
{
- return adoptRef(*new AudioTrack(client, trackPrivate));
+ return adoptRef(new AudioTrack(client, trackPrivate));
}
virtual ~AudioTrack();
@@ -64,15 +63,13 @@ public:
virtual const AtomicString& defaultKindKeyword() const override { return emptyAtom; }
virtual bool enabled() const override { return m_enabled; }
- void setEnabled(const bool);
+ virtual void setEnabled(const bool);
- virtual void clearClient() override { m_client = nullptr; }
+ virtual void clearClient() override { m_client = 0; }
AudioTrackClient* client() const { return m_client; }
size_t inbandTrackIndex();
- void setPrivate(PassRefPtr<AudioTrackPrivate>);
-
protected:
AudioTrack(AudioTrackClient*, PassRefPtr<AudioTrackPrivate>);
@@ -80,13 +77,11 @@ private:
virtual bool isValidKind(const AtomicString&) const override;
virtual void enabledChanged(AudioTrackPrivate*, bool) override;
- virtual void idChanged(TrackPrivateBase*, const AtomicString&) override;
- virtual void labelChanged(TrackPrivateBase*, const AtomicString&) override;
- virtual void languageChanged(TrackPrivateBase*, const AtomicString&) override;
+ virtual void idChanged(TrackPrivateBase*, const String&) override;
+ virtual void labelChanged(TrackPrivateBase*, const String&) override;
+ virtual void languageChanged(TrackPrivateBase*, const String&) override;
virtual void willRemove(TrackPrivateBase*) override;
- void updateKindFromPrivate();
-
bool m_enabled;
AudioTrackClient* m_client;
diff --git a/Source/WebCore/html/track/AudioTrack.idl b/Source/WebCore/html/track/AudioTrack.idl
index 95f31defe..fefd44ea5 100644
--- a/Source/WebCore/html/track/AudioTrack.idl
+++ b/Source/WebCore/html/track/AudioTrack.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/track/AudioTrackList.cpp b/Source/WebCore/html/track/AudioTrackList.cpp
index 5edad8eaa..eb8c9a73f 100644
--- a/Source/WebCore/html/track/AudioTrackList.cpp
+++ b/Source/WebCore/html/track/AudioTrackList.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -49,14 +49,7 @@ void AudioTrackList::append(PassRefPtr<AudioTrack> prpTrack)
// Insert tracks in the media file order.
size_t index = track->inbandTrackIndex();
- size_t insertionIndex;
- for (insertionIndex = 0; insertionIndex < m_inbandTracks.size(); ++insertionIndex) {
- AudioTrack* otherTrack = static_cast<AudioTrack*>(m_inbandTracks[insertionIndex].get());
- if (otherTrack->inbandTrackIndex() > index)
- break;
- }
- m_inbandTracks.insert(insertionIndex, track);
-
+ m_inbandTracks.insert(index, track);
ASSERT(!track->mediaElement() || track->mediaElement() == mediaElement());
track->setMediaElement(mediaElement());
diff --git a/Source/WebCore/html/track/AudioTrackList.h b/Source/WebCore/html/track/AudioTrackList.h
index 73fc04a97..9104b6bfd 100644
--- a/Source/WebCore/html/track/AudioTrackList.h
+++ b/Source/WebCore/html/track/AudioTrackList.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -34,11 +34,11 @@ namespace WebCore {
class AudioTrack;
-class AudioTrackList final : public TrackListBase {
+class AudioTrackList : public TrackListBase {
public:
- static Ref<AudioTrackList> create(HTMLMediaElement* owner, ScriptExecutionContext* context)
+ static PassRefPtr<AudioTrackList> create(HTMLMediaElement* owner, ScriptExecutionContext* context)
{
- return adoptRef(*new AudioTrackList(owner, context));
+ return adoptRef(new AudioTrackList(owner, context));
}
virtual ~AudioTrackList();
diff --git a/Source/WebCore/html/track/AudioTrackList.idl b/Source/WebCore/html/track/AudioTrackList.idl
index 8c24cab8e..439384725 100644
--- a/Source/WebCore/html/track/AudioTrackList.idl
+++ b/Source/WebCore/html/track/AudioTrackList.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -34,12 +34,16 @@
getter AudioTrack item(unsigned long index);
AudioTrack getTrackById(DOMString id);
- attribute EventHandler onchange;
- attribute EventHandler onaddtrack;
- attribute EventHandler onremovetrack;
+ attribute EventListener onchange;
+ attribute EventListener onaddtrack;
+ attribute EventListener onremovetrack;
- void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
- void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
- [RaisesException] boolean dispatchEvent(Event event);
+ void addEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ void removeEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ [RaisesException] boolean dispatchEvent(Event evt);
};
diff --git a/Source/WebCore/html/track/BufferedLineReader.cpp b/Source/WebCore/html/track/BufferedLineReader.cpp
deleted file mode 100644
index c23924bed..000000000
--- a/Source/WebCore/html/track/BufferedLineReader.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2013, Opera Software ASA. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "BufferedLineReader.h"
-
-#include <wtf/unicode/CharacterNames.h>
-
-namespace WebCore {
-
-bool BufferedLineReader::getLine(String& line)
-{
- if (m_maybeSkipLF) {
- // We ran out of data after a CR (U+000D), which means that we may be
- // in the middle of a CRLF pair. If the next character is a LF (U+000A)
- // then skip it, and then (unconditionally) return the buffered line.
- if (!m_buffer.isEmpty()) {
- scanCharacter(newlineCharacter);
- m_maybeSkipLF = false;
- }
- // If there was no (new) data available, then keep m_maybeSkipLF set,
- // and fall through all the way down to the EOS check at the end of
- // the method.
- }
-
- bool shouldReturnLine = false;
- bool checkForLF = false;
- while (!m_buffer.isEmpty()) {
- UChar c = m_buffer.currentChar();
- m_buffer.advance();
-
- if (c == newlineCharacter || c == carriageReturn) {
- // We found a line ending. Return the accumulated line.
- shouldReturnLine = true;
- checkForLF = (c == carriageReturn);
- break;
- }
-
- // NULs are transformed into U+FFFD (REPLACEMENT CHAR.) in step 1 of
- // the WebVTT parser algorithm.
- if (c == '\0')
- c = replacementCharacter;
-
- m_lineBuffer.append(c);
- }
-
- if (checkForLF) {
- // May be in the middle of a CRLF pair.
- if (!m_buffer.isEmpty()) {
- // Scan a potential newline character.
- scanCharacter(newlineCharacter);
- } else {
- // Check for the LF on the next call (unless we reached EOS, in
- // which case we'll return the contents of the line buffer, and
- // reset state for the next line.)
- m_maybeSkipLF = true;
- }
- }
-
- if (isAtEndOfStream()) {
- // We've reached the end of the stream proper. Emit a line if the
- // current line buffer is non-empty. (Note that if shouldReturnLine is
- // set already, we want to return a line nonetheless.)
- shouldReturnLine |= !m_lineBuffer.isEmpty();
- }
-
- if (shouldReturnLine) {
- line = m_lineBuffer.toString();
- m_lineBuffer.clear();
- return true;
- }
-
- ASSERT(m_buffer.isEmpty());
- return false;
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/html/track/BufferedLineReader.h b/Source/WebCore/html/track/BufferedLineReader.h
deleted file mode 100644
index 8aacd819b..000000000
--- a/Source/WebCore/html/track/BufferedLineReader.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2013, Opera Software ASA. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BufferedLineReader_h
-#define BufferedLineReader_h
-
-#include "SegmentedString.h"
-#include <wtf/text/StringBuilder.h>
-
-namespace WebCore {
-
-// Line collection helper for the WebVTT Parser.
-//
-// Converts a stream of data (== a sequence of Strings) into a set of
-// lines. CR, LR or CRLF are considered linebreaks. Normalizes NULs (U+0000)
-// to 'REPLACEMENT CHARACTER' (U+FFFD) and does not return the linebreaks as
-// part of the result.
-class BufferedLineReader {
- WTF_MAKE_NONCOPYABLE(BufferedLineReader);
-public:
- BufferedLineReader()
- : m_endOfStream(false)
- , m_maybeSkipLF(false) { }
-
- // Append data to the internal buffer.
- void append(const String& data)
- {
- ASSERT(!m_endOfStream);
- m_buffer.append(SegmentedString(data));
- }
-
- // Indicate that no more data will be appended. This will cause any
- // potentially "unterminated" line to be returned from getLine.
- void setEndOfStream() { m_endOfStream = true; }
-
- // Attempt to read a line from the internal buffer (fed via append).
- // If successful, true is returned and |line| is set to the line that was
- // read. If no line could be read false is returned.
- bool getLine(String& line);
-
- // Returns true if EOS has been reached proper.
- bool isAtEndOfStream() const { return m_endOfStream && m_buffer.isEmpty(); }
-
- void reset() { m_buffer.clear(); }
-
-private:
- // Consume the next character the buffer if it is the character |c|.
- void scanCharacter(UChar c)
- {
- ASSERT(!m_buffer.isEmpty());
- if (m_buffer.currentChar() == c)
- m_buffer.advance();
- }
-
- SegmentedString m_buffer;
- StringBuilder m_lineBuffer;
- bool m_endOfStream;
- bool m_maybeSkipLF;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/html/track/DataCue.cpp b/Source/WebCore/html/track/DataCue.cpp
deleted file mode 100644
index 2f4804ad1..000000000
--- a/Source/WebCore/html/track/DataCue.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2014 Cable Television Labs Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(VIDEO_TRACK)
-#include "DataCue.h"
-
-#include "Logging.h"
-#include "TextTrack.h"
-#include "TextTrackCueList.h"
-#include <runtime/Protect.h>
-
-namespace WebCore {
-
-DataCue::DataCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, ArrayBuffer* data, const String& type, ExceptionCode& ec)
- : TextTrackCue(context, start, end)
- , m_type(type)
-{
- setData(data, ec);
-}
-
-DataCue::DataCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, const void* data, unsigned length)
- : TextTrackCue(context, start, end)
-{
- m_data = ArrayBuffer::create(data, length);
-}
-
-#if ENABLE(DATACUE_VALUE)
-DataCue::DataCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, PassRefPtr<SerializedPlatformRepresentation> platformValue, const String& type)
- : TextTrackCue(context, start, end)
- , m_type(type)
- , m_platformValue(platformValue)
-{
-}
-
-DataCue::DataCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, JSC::JSValue value, const String& type)
- : TextTrackCue(context, start, end)
- , m_type(type)
- , m_value(value)
-{
-}
-#endif
-
-DataCue::~DataCue()
-{
-#if ENABLE(DATACUE_VALUE)
- if (m_value)
- JSC::gcUnprotect(m_value);
-#endif
-}
-
-PassRefPtr<ArrayBuffer> DataCue::data() const
-{
-#if ENABLE(DATACUE_VALUE)
- if (m_platformValue)
- return m_platformValue->data();
-#endif
-
- if (!m_data)
- return nullptr;
-
- return ArrayBuffer::create(m_data.get());
-}
-
-void DataCue::setData(ArrayBuffer* data, ExceptionCode& ec)
-{
- if (!data) {
- ec = TypeError;
- return;
- }
-
-#if ENABLE(DATACUE_VALUE)
- m_platformValue = nullptr;
- m_value = JSC::JSValue();
-#endif
-
- m_data = ArrayBuffer::create(data);
-}
-
-DataCue* toDataCue(TextTrackCue* cue)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(cue->cueType() == TextTrackCue::Data);
- return static_cast<DataCue*>(cue);
-}
-
-const DataCue* toDataCue(const TextTrackCue* cue)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(cue->cueType() == TextTrackCue::Data);
- return static_cast<const DataCue*>(cue);
-}
-
-bool DataCue::cueContentsMatch(const TextTrackCue& cue) const
-{
- if (cue.cueType() != TextTrackCue::Data)
- return false;
-
- const DataCue* dataCue = toDataCue(&cue);
- RefPtr<ArrayBuffer> otherData = dataCue->data();
- if ((otherData && !m_data) || (!otherData && m_data))
- return false;
- if (m_data && m_data->byteLength() != otherData->byteLength())
- return false;
- if (m_data && m_data->data() && memcmp(m_data->data(), otherData->data(), m_data->byteLength()))
- return false;
-
-#if ENABLE(DATACUE_VALUE)
- RefPtr<SerializedPlatformRepresentation> otherPlatformValue = dataCue->platformValue();
- if ((otherPlatformValue && !m_platformValue) || (!otherPlatformValue && m_platformValue))
- return false;
- if (m_platformValue && !m_platformValue->isEqual(*otherPlatformValue.get()))
- return false;
-
- JSC::JSValue thisValue = value(nullptr);
- JSC::JSValue otherValue = dataCue->value(nullptr);
- if ((otherValue && !thisValue) || (!otherValue && thisValue))
- return false;
- if (!JSC::JSValue::strictEqual(nullptr, thisValue, otherValue))
- return false;
-#endif
-
- return true;
-}
-
-bool DataCue::isEqual(const TextTrackCue& cue, TextTrackCue::CueMatchRules match) const
-{
- if (!TextTrackCue::isEqual(cue, match))
- return false;
-
- if (cue.cueType() != TextTrackCue::Data)
- return false;
-
- return cueContentsMatch(cue);
-}
-
-bool DataCue::doesExtendCue(const TextTrackCue& cue) const
-{
- if (!cueContentsMatch(cue))
- return false;
-
- return TextTrackCue::doesExtendCue(cue);
-}
-
-#if ENABLE(DATACUE_VALUE)
-JSC::JSValue DataCue::value(JSC::ExecState* exec) const
-{
- if (exec && m_platformValue)
- return m_platformValue->deserialize(exec);
-
- if (m_value)
- return m_value;
-
- return JSC::jsNull();
-}
-
-void DataCue::setValue(JSC::ExecState*, JSC::JSValue value)
-{
- // FIXME: this should use a SerializedScriptValue.
- if (m_value)
- JSC::gcUnprotect(m_value);
- m_value = value;
- if (m_value)
- JSC::gcProtect(m_value);
-
- m_platformValue = nullptr;
- m_data = nullptr;
-}
-#endif
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/html/track/DataCue.h b/Source/WebCore/html/track/DataCue.h
deleted file mode 100644
index ef52e7309..000000000
--- a/Source/WebCore/html/track/DataCue.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2014 Cable Television Labs Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DataCue_h
-#define DataCue_h
-
-#if ENABLE(VIDEO_TRACK)
-
-#include "TextTrackCue.h"
-#include <runtime/ArrayBuffer.h>
-#include <runtime/JSCInlines.h>
-#include <wtf/MediaTime.h>
-#include <wtf/RefCounted.h>
-
-#if ENABLE(DATACUE_VALUE)
-#include "SerializedPlatformRepresentation.h"
-#endif
-
-namespace WebCore {
-
-class ScriptExecutionContext;
-
-class DataCue final : public TextTrackCue {
-public:
- static Ref<DataCue> create(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, ArrayBuffer* data, ExceptionCode& ec)
- {
- return adoptRef(*new DataCue(context, start, end, data, emptyString(), ec));
- }
-
- static Ref<DataCue> create(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, const void* data, unsigned length)
- {
- return adoptRef(*new DataCue(context, start, end, data, length));
- }
-
- static Ref<DataCue> create(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, ArrayBuffer* data, const String& type, ExceptionCode& ec)
- {
- return adoptRef(*new DataCue(context, start, end, data, type, ec));
- }
-
-#if ENABLE(DATACUE_VALUE)
- static Ref<DataCue> create(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, PassRefPtr<SerializedPlatformRepresentation> platformValue, const String& type)
- {
- return adoptRef(*new DataCue(context, start, end, platformValue, type));
- }
-
- static Ref<DataCue> create(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, JSC::JSValue value, const String& type)
- {
- return adoptRef(*new DataCue(context, start, end, value, type));
- }
-#endif
-
- virtual ~DataCue();
- virtual CueType cueType() const override { return Data; }
-
- PassRefPtr<ArrayBuffer> data() const;
- void setData(ArrayBuffer*, ExceptionCode&);
-
-#if ENABLE(DATACUE_VALUE)
- const PassRefPtr<SerializedPlatformRepresentation> platformValue() const { return m_platformValue; }
-
- JSC::JSValue value(JSC::ExecState*) const;
- void setValue(JSC::ExecState*, JSC::JSValue);
-
- String type() const { return m_type; }
- void setType(const String& type) { m_type = type; }
-#endif
-
- virtual bool isEqual(const TextTrackCue&, CueMatchRules) const override;
- virtual bool cueContentsMatch(const TextTrackCue&) const override;
- virtual bool doesExtendCue(const TextTrackCue&) const override;
-
-protected:
- DataCue(ScriptExecutionContext&, const MediaTime& start, const MediaTime& end, ArrayBuffer*, const String&, ExceptionCode&);
- DataCue(ScriptExecutionContext&, const MediaTime& start, const MediaTime& end, const void*, unsigned);
-#if ENABLE(DATACUE_VALUE)
- DataCue(ScriptExecutionContext&, const MediaTime& start, const MediaTime& end, PassRefPtr<SerializedPlatformRepresentation>, const String&);
- DataCue(ScriptExecutionContext&, const MediaTime& start, const MediaTime& end, JSC::JSValue, const String&);
-#endif
-
-private:
- RefPtr<ArrayBuffer> m_data;
- String m_type;
-#if ENABLE(DATACUE_VALUE)
- RefPtr<SerializedPlatformRepresentation> m_platformValue;
- JSC::JSValue m_value;
-#endif
-};
-
-DataCue* toDataCue(TextTrackCue*);
-const DataCue* toDataCue(const TextTrackCue*);
-
-} // namespace WebCore
-
-#endif
-#endif
diff --git a/Source/WebCore/html/track/DataCue.idl b/Source/WebCore/html/track/DataCue.idl
deleted file mode 100644
index fa5e25ed4..000000000
--- a/Source/WebCore/html/track/DataCue.idl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2014 Cable Television Labs Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-[
- Conditional=VIDEO_TRACK,
- CustomConstructor,
-#if defined(ENABLE_DATACUE_VALUE) && ENABLE_DATACUE_VALUE
- CustomConstructor(unrestricted double startTime, unrestricted double endTime, any value, optional DOMString type),
- InterfaceName=WebKitDataCue,
-#else
- CustomConstructor(unrestricted double startTime, unrestricted double endTime, ArrayBuffer data),
-#endif
- ConstructorRaisesException,
-] interface DataCue : TextTrackCue {
- [SetterRaisesException] attribute ArrayBuffer data;
-
-#if defined(ENABLE_DATACUE_VALUE) && ENABLE_DATACUE_VALUE
- [CustomGetter, CustomSetter] attribute any value;
- readonly attribute DOMString type;
-#endif
-};
diff --git a/Source/WebCore/html/track/InbandDataTextTrack.cpp b/Source/WebCore/html/track/InbandDataTextTrack.cpp
deleted file mode 100644
index 95c03026e..000000000
--- a/Source/WebCore/html/track/InbandDataTextTrack.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2014 Cable Television Labs Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(VIDEO_TRACK)
-#include "InbandDataTextTrack.h"
-
-#include "DataCue.h"
-#include "ExceptionCodePlaceholder.h"
-#include "HTMLMediaElement.h"
-#include "InbandTextTrackPrivate.h"
-#include "Logging.h"
-#include <runtime/ArrayBuffer.h>
-
-namespace WebCore {
-
-Ref<InbandDataTextTrack> InbandDataTextTrack::create(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> playerPrivate)
-{
- return adoptRef(*new InbandDataTextTrack(context, client, playerPrivate));
-}
-
-InbandDataTextTrack::InbandDataTextTrack(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> trackPrivate)
- : InbandTextTrack(context, client, trackPrivate)
-{
-}
-
-InbandDataTextTrack::~InbandDataTextTrack()
-{
-}
-
-void InbandDataTextTrack::addDataCue(InbandTextTrackPrivate*, const MediaTime& start, const MediaTime& end, const void* data, unsigned length)
-{
- RefPtr<DataCue> cue = DataCue::create(*scriptExecutionContext(), start, end, data, length);
- addCue(cue.release(), ASSERT_NO_EXCEPTION);
-}
-
-#if ENABLE(DATACUE_VALUE)
-void InbandDataTextTrack::addDataCue(InbandTextTrackPrivate*, const MediaTime& start, const MediaTime& end, PassRefPtr<SerializedPlatformRepresentation> prpPlatformValue, const String& type)
-{
- RefPtr<SerializedPlatformRepresentation> platformValue = prpPlatformValue;
- if (m_incompleteCueMap.find(platformValue.get()) != m_incompleteCueMap.end())
- return;
-
- RefPtr<DataCue> cue = DataCue::create(*scriptExecutionContext(), start, end, platformValue, type);
- if (hasCue(cue.get(), TextTrackCue::IgnoreDuration)) {
- LOG(Media, "InbandDataTextTrack::addDataCue ignoring already added cue: start=%s, end=%s\n", toString(cue->startTime()).utf8().data(), toString(cue->endTime()).utf8().data());
- return;
- }
-
- if (end.isPositiveInfinite() && mediaElement()) {
- cue->setEndTime(mediaElement()->durationMediaTime());
- m_incompleteCueMap.add(platformValue, cue);
- }
-
- addCue(cue.release(), ASSERT_NO_EXCEPTION);
-}
-
-void InbandDataTextTrack::updateDataCue(InbandTextTrackPrivate*, const MediaTime& start, const MediaTime& inEnd, PassRefPtr<SerializedPlatformRepresentation> prpPlatformValue)
-{
- MediaTime end = inEnd;
-
- RefPtr<SerializedPlatformRepresentation> platformValue = prpPlatformValue;
- auto iter = m_incompleteCueMap.find(platformValue.get());
- if (iter == m_incompleteCueMap.end())
- return;
-
- RefPtr<DataCue> cue = iter->value;
- if (!cue)
- return;
-
- cue->willChange();
-
- if (end.isPositiveInfinite() && mediaElement())
- end = mediaElement()->durationMediaTime();
- else
- m_incompleteCueMap.remove(platformValue.get());
-
- LOG(Media, "InbandDataTextTrack::updateDataCue: was start=%s, end=%s, will be start=%s, end=%s\n", toString(cue->startTime()).utf8().data(), toString(cue->endTime()).utf8().data(), toString(start).utf8().data(), toString(end).utf8().data());
-
- cue->setStartTime(start);
- cue->setEndTime(end);
-
- cue->didChange();
-}
-
-void InbandDataTextTrack::removeDataCue(InbandTextTrackPrivate*, const MediaTime&, const MediaTime&, PassRefPtr<SerializedPlatformRepresentation> prpPlatformValue)
-{
- RefPtr<SerializedPlatformRepresentation> platformValue = prpPlatformValue;
- auto iter = m_incompleteCueMap.find(platformValue.get());
- if (iter == m_incompleteCueMap.end())
- return;
-
- RefPtr<DataCue> cue = iter->value;
- if (cue) {
- LOG(Media, "InbandDataTextTrack::removeDataCue removing cue: start=%s, end=%s\n", toString(cue->startTime()).utf8().data(), toString(cue->endTime()).utf8().data());
- removeCue(cue.get(), IGNORE_EXCEPTION);
- }
-}
-
-void InbandDataTextTrack::removeCue(TextTrackCue* cue, ExceptionCode& ec)
-{
- ASSERT(cue->cueType() == TextTrackCue::Data);
-
- RefPtr<SerializedPlatformRepresentation> platformValue = toDataCue(cue)->platformValue().get();
- auto iter = m_incompleteCueMap.find(platformValue.get());
- if (iter != m_incompleteCueMap.end())
- m_incompleteCueMap.remove(platformValue.get());
-
- InbandTextTrack::removeCue(cue, ec);
-}
-
-#endif
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/html/track/InbandDataTextTrack.h b/Source/WebCore/html/track/InbandDataTextTrack.h
deleted file mode 100644
index e95e76c0f..000000000
--- a/Source/WebCore/html/track/InbandDataTextTrack.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2014 Cable Television Labs Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef InbandDataTextTrack_h
-#define InbandDataTextTrack_h
-
-#if ENABLE(VIDEO_TRACK)
-
-#include "InbandTextTrack.h"
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
-class DataCue;
-class Document;
-class InbandTextTrackPrivate;
-
-#if ENABLE(DATACUE_VALUE)
-class SerializedPlatformRepresentation;
-#endif
-
-class InbandDataTextTrack final : public InbandTextTrack {
-public:
- static Ref<InbandDataTextTrack> create(ScriptExecutionContext*, TextTrackClient*, PassRefPtr<InbandTextTrackPrivate>);
- virtual ~InbandDataTextTrack();
-
-private:
- InbandDataTextTrack(ScriptExecutionContext*, TextTrackClient*, PassRefPtr<InbandTextTrackPrivate>);
-
- virtual void addDataCue(InbandTextTrackPrivate*, const MediaTime& start, const MediaTime& end, const void*, unsigned) override;
-
-#if ENABLE(DATACUE_VALUE)
- virtual void addDataCue(InbandTextTrackPrivate*, const MediaTime& start, const MediaTime& end, PassRefPtr<SerializedPlatformRepresentation>, const String&) override;
- virtual void updateDataCue(InbandTextTrackPrivate*, const MediaTime& start, const MediaTime& end, PassRefPtr<SerializedPlatformRepresentation>) override;
- virtual void removeDataCue(InbandTextTrackPrivate*, const MediaTime& start, const MediaTime& end, PassRefPtr<SerializedPlatformRepresentation>) override;
- virtual void removeCue(TextTrackCue*, ExceptionCode&) override;
-
- HashMap<RefPtr<SerializedPlatformRepresentation>, RefPtr<DataCue>> m_incompleteCueMap;
-#endif
-};
-
-} // namespace WebCore
-
-#endif
-#endif
diff --git a/Source/WebCore/html/track/InbandGenericTextTrack.cpp b/Source/WebCore/html/track/InbandGenericTextTrack.cpp
index b9fd6e828..d807dc2d3 100644
--- a/Source/WebCore/html/track/InbandGenericTextTrack.cpp
+++ b/Source/WebCore/html/track/InbandGenericTextTrack.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -36,10 +36,6 @@
#include <math.h>
#include <wtf/text/CString.h>
-#if ENABLE(WEBVTT_REGIONS)
-#include "VTTRegionList.h"
-#endif
-
namespace WebCore {
GenericTextTrackCueMap::GenericTextTrackCueMap()
@@ -92,9 +88,9 @@ void GenericTextTrackCueMap::remove(TextTrackCue* cue)
}
}
-Ref<InbandGenericTextTrack> InbandGenericTextTrack::create(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> playerPrivate)
+PassRefPtr<InbandGenericTextTrack> InbandGenericTextTrack::create(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> playerPrivate)
{
- return adoptRef(*new InbandGenericTextTrack(context, client, playerPrivate));
+ return adoptRef(new InbandGenericTextTrack(context, client, playerPrivate));
}
InbandGenericTextTrack::InbandGenericTextTrack(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> trackPrivate)
@@ -110,11 +106,11 @@ void InbandGenericTextTrack::updateCueFromCueData(TextTrackCueGeneric* cue, Gene
{
cue->willChange();
- cue->setStartTime(cueData->startTime());
- MediaTime endTime = cueData->endTime();
- if (endTime.isPositiveInfinite() && mediaElement())
- endTime = mediaElement()->durationMediaTime();
- cue->setEndTime(endTime);
+ cue->setStartTime(cueData->startTime(), IGNORE_EXCEPTION);
+ double endTime = cueData->endTime();
+ if (std::isinf(endTime) && mediaElement())
+ endTime = mediaElement()->duration();
+ cue->setEndTime(endTime, IGNORE_EXCEPTION);
cue->setText(cueData->content());
cue->setId(cueData->id());
cue->setBaseFontSizeRelativeToVideoHeight(cueData->baseFontSize());
@@ -156,16 +152,14 @@ void InbandGenericTextTrack::addGenericCue(InbandTextTrackPrivate* trackPrivate,
RefPtr<TextTrackCueGeneric> cue = TextTrackCueGeneric::create(*scriptExecutionContext(), cueData->startTime(), cueData->endTime(), cueData->content());
updateCueFromCueData(cue.get(), cueData.get());
if (hasCue(cue.get(), TextTrackCue::IgnoreDuration)) {
- LOG(Media, "InbandGenericTextTrack::addGenericCue ignoring already added cue: start=%s, end=%s, content=\"%s\"\n", toString(cueData->startTime()).utf8().data(), toString(cueData->endTime()).utf8().data(), cueData->content().utf8().data());
+ LOG(Media, "InbandGenericTextTrack::addGenericCue ignoring already added cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime(), cueData->endTime(), cueData->content().utf8().data());
return;
}
- LOG(Media, "InbandGenericTextTrack::addGenericCue added cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime().toDouble(), cueData->endTime().toDouble(), cueData->content().utf8().data());
-
if (cueData->status() != GenericCueData::Complete)
m_cueMap.add(cueData.get(), cue.get());
- addCue(cue, ASSERT_NO_EXCEPTION);
+ addCue(cue);
}
void InbandGenericTextTrack::updateGenericCue(InbandTextTrackPrivate*, GenericCueData* cueData)
@@ -184,12 +178,10 @@ void InbandGenericTextTrack::removeGenericCue(InbandTextTrackPrivate*, GenericCu
{
RefPtr<TextTrackCueGeneric> cue = m_cueMap.find(cueData);
if (cue) {
- LOG(Media, "InbandGenericTextTrack::removeGenericCue removing cue: start=%s, end=%s, content=\"%s\"\n", toString(cueData->startTime()).utf8().data(), toString(cueData->endTime()).utf8().data(), cueData->content().utf8().data());
+ LOG(Media, "InbandGenericTextTrack::removeGenericCue removing cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime(), cueData->endTime(), cueData->content().utf8().data());
removeCue(cue.get(), IGNORE_EXCEPTION);
- } else {
- LOG(Media, "InbandGenericTextTrack::removeGenericCue UNABLE to find cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime().toDouble(), cueData->endTime().toDouble(), cueData->content().utf8().data());
+ } else
m_cueMap.remove(cueData);
- }
}
void InbandGenericTextTrack::removeCue(TextTrackCue* cue, ExceptionCode& ec)
@@ -198,59 +190,6 @@ void InbandGenericTextTrack::removeCue(TextTrackCue* cue, ExceptionCode& ec)
TextTrack::removeCue(cue, ec);
}
-WebVTTParser& InbandGenericTextTrack::parser()
-{
- if (!m_webVTTParser)
- m_webVTTParser = std::make_unique<WebVTTParser>(static_cast<WebVTTParserClient*>(this), scriptExecutionContext());
- return *m_webVTTParser;
-}
-
-void InbandGenericTextTrack::parseWebVTTCueData(InbandTextTrackPrivate* trackPrivate, const ISOWebVTTCue& cueData)
-{
- ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
- parser().parseCueData(cueData);
-}
-
-void InbandGenericTextTrack::parseWebVTTFileHeader(InbandTextTrackPrivate* trackPrivate, String header)
-{
- ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
- parser().parseFileHeader(header);
-}
-
-void InbandGenericTextTrack::newCuesParsed()
-{
- Vector<RefPtr<WebVTTCueData>> cues;
- parser().getNewCues(cues);
-
- for (auto& cueData : cues) {
- RefPtr<VTTCue> vttCue = VTTCue::create(*scriptExecutionContext(), *cueData);
-
- if (hasCue(vttCue.get(), TextTrackCue::IgnoreDuration)) {
- LOG(Media, "InbandGenericTextTrack::newCuesParsed ignoring already added cue: start=%.2f, end=%.2f, content=\"%s\"\n", vttCue->startTime(), vttCue->endTime(), vttCue->text().utf8().data());
- return;
- }
- addCue(vttCue.release(), ASSERT_NO_EXCEPTION);
- }
-}
-
-#if ENABLE(WEBVTT_REGIONS)
-void InbandGenericTextTrack::newRegionsParsed()
-{
- Vector<RefPtr<VTTRegion>> newRegions;
- parser().getNewRegions(newRegions);
-
- for (auto& region : newRegions) {
- region->setTrack(this);
- regions()->add(region);
- }
-}
-#endif
-
-void InbandGenericTextTrack::fileFailedToParse()
-{
- LOG(Media, "Error parsing WebVTT stream.");
-}
-
} // namespace WebCore
#endif
diff --git a/Source/WebCore/html/track/InbandGenericTextTrack.h b/Source/WebCore/html/track/InbandGenericTextTrack.h
index 274b4bacb..2456a9adc 100644
--- a/Source/WebCore/html/track/InbandGenericTextTrack.h
+++ b/Source/WebCore/html/track/InbandGenericTextTrack.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,7 +30,6 @@
#include "InbandTextTrack.h"
#include "TextTrackCueGeneric.h"
-#include "WebVTTParser.h"
#include <wtf/RefPtr.h>
namespace WebCore {
@@ -39,10 +38,10 @@ class Document;
class InbandTextTrackPrivate;
class TextTrackCue;
-class GenericTextTrackCueMap final {
+class GenericTextTrackCueMap {
public:
GenericTextTrackCueMap();
- ~GenericTextTrackCueMap();
+ virtual ~GenericTextTrackCueMap();
void add(GenericCueData*, TextTrackCueGeneric*);
@@ -60,9 +59,9 @@ private:
CueDataToCueMap m_dataToCueMap;
};
-class InbandGenericTextTrack final : public InbandTextTrack, private WebVTTParserClient {
+class InbandGenericTextTrack : public InbandTextTrack {
public:
- static Ref<InbandGenericTextTrack> create(ScriptExecutionContext*, TextTrackClient*, PassRefPtr<InbandTextTrackPrivate>);
+ static PassRefPtr<InbandGenericTextTrack> create(ScriptExecutionContext*, TextTrackClient*, PassRefPtr<InbandTextTrackPrivate>);
virtual ~InbandGenericTextTrack();
private:
@@ -73,21 +72,12 @@ private:
virtual void removeGenericCue(InbandTextTrackPrivate*, GenericCueData*) override;
virtual void removeCue(TextTrackCue*, ExceptionCode&) override;
+ virtual void parseWebVTTCueData(InbandTextTrackPrivate*, const char*, unsigned) override { ASSERT_NOT_REACHED(); }
+
PassRefPtr<TextTrackCueGeneric> createCue(PassRefPtr<GenericCueData>);
void updateCueFromCueData(TextTrackCueGeneric*, GenericCueData*);
- WebVTTParser& parser();
- virtual void parseWebVTTCueData(InbandTextTrackPrivate*, const ISOWebVTTCue&) override;
- virtual void parseWebVTTFileHeader(InbandTextTrackPrivate*, String) override;
-
- virtual void newCuesParsed() override;
-#if ENABLE(WEBVTT_REGIONS)
- virtual void newRegionsParsed() override;
-#endif
- virtual void fileFailedToParse() override;
-
GenericTextTrackCueMap m_cueMap;
- std::unique_ptr<WebVTTParser> m_webVTTParser;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/track/InbandTextTrack.cpp b/Source/WebCore/html/track/InbandTextTrack.cpp
index 875e7d84c..f8772cbc2 100644
--- a/Source/WebCore/html/track/InbandTextTrack.cpp
+++ b/Source/WebCore/html/track/InbandTextTrack.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -33,7 +33,6 @@
#include "Event.h"
#include "ExceptionCodePlaceholder.h"
#include "HTMLMediaElement.h"
-#include "InbandDataTextTrack.h"
#include "InbandGenericTextTrack.h"
#include "InbandTextTrackPrivate.h"
#include "InbandWebVTTTextTrack.h"
@@ -48,8 +47,6 @@ PassRefPtr<InbandTextTrack> InbandTextTrack::create(ScriptExecutionContext* cont
TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> trackPrivate)
{
switch (trackPrivate->cueFormat()) {
- case InbandTextTrackPrivate::Data:
- return InbandDataTextTrack::create(context, client, trackPrivate);
case InbandTextTrackPrivate::Generic:
return InbandGenericTextTrack::create(context, client, trackPrivate);
case InbandTextTrackPrivate::WebVTT:
@@ -61,11 +58,35 @@ PassRefPtr<InbandTextTrack> InbandTextTrack::create(ScriptExecutionContext* cont
}
InbandTextTrack::InbandTextTrack(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> trackPrivate)
- : TextTrack(context, client, emptyAtom, trackPrivate->id(), trackPrivate->label(), trackPrivate->language(), InBand)
+ : TextTrack(context, client, emptyString(), trackPrivate->id(), trackPrivate->label(), trackPrivate->language(), InBand)
, m_private(trackPrivate)
{
m_private->setClient(this);
- updateKindFromPrivate();
+
+ switch (m_private->kind()) {
+ case InbandTextTrackPrivate::Subtitles:
+ setKind(TextTrack::subtitlesKeyword());
+ break;
+ case InbandTextTrackPrivate::Captions:
+ setKind(TextTrack::captionsKeyword());
+ break;
+ case InbandTextTrackPrivate::Descriptions:
+ setKind(TextTrack::descriptionsKeyword());
+ break;
+ case InbandTextTrackPrivate::Chapters:
+ setKind(TextTrack::chaptersKeyword());
+ break;
+ case InbandTextTrackPrivate::Metadata:
+ setKind(TextTrack::metadataKeyword());
+ break;
+ case InbandTextTrackPrivate::Forced:
+ setKind(TextTrack::forcedKeyword());
+ break;
+ case InbandTextTrackPrivate::None:
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
}
InbandTextTrack::~InbandTextTrack()
@@ -73,30 +94,10 @@ InbandTextTrack::~InbandTextTrack()
m_private->setClient(0);
}
-void InbandTextTrack::setPrivate(PassRefPtr<InbandTextTrackPrivate> trackPrivate)
-{
- ASSERT(m_private);
- ASSERT(trackPrivate);
-
- if (m_private == trackPrivate)
- return;
-
- m_private->setClient(0);
- m_private = trackPrivate;
- m_private->setClient(this);
-
- setModeInternal(mode());
- updateKindFromPrivate();
-}
-
void InbandTextTrack::setMode(const AtomicString& mode)
{
TextTrack::setMode(mode);
- setModeInternal(mode);
-}
-void InbandTextTrack::setModeInternal(const AtomicString& mode)
-{
if (mode == TextTrack::disabledKeyword())
m_private->setMode(InbandTextTrackPrivate::Disabled);
else if (mode == TextTrack::hiddenKeyword())
@@ -153,25 +154,19 @@ size_t InbandTextTrack::inbandTrackIndex()
return m_private->trackIndex();
}
-AtomicString InbandTextTrack::inBandMetadataTrackDispatchType() const
-{
- ASSERT(m_private);
- return m_private->inBandMetadataTrackDispatchType();
-}
-
-void InbandTextTrack::idChanged(TrackPrivateBase* trackPrivate, const AtomicString& id)
+void InbandTextTrack::idChanged(TrackPrivateBase* trackPrivate, const String& id)
{
ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
setId(id);
}
-void InbandTextTrack::labelChanged(TrackPrivateBase* trackPrivate, const AtomicString& label)
+void InbandTextTrack::labelChanged(TrackPrivateBase* trackPrivate, const String& label)
{
ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
setLabel(label);
}
-void InbandTextTrack::languageChanged(TrackPrivateBase* trackPrivate, const AtomicString& language)
+void InbandTextTrack::languageChanged(TrackPrivateBase* trackPrivate, const String& language)
{
ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
setLanguage(language);
@@ -185,42 +180,6 @@ void InbandTextTrack::willRemove(TrackPrivateBase* trackPrivate)
mediaElement()->removeTextTrack(this);
}
-void InbandTextTrack::updateKindFromPrivate()
-{
- switch (m_private->kind()) {
- case InbandTextTrackPrivate::Subtitles:
- setKind(TextTrack::subtitlesKeyword());
- break;
- case InbandTextTrackPrivate::Captions:
- setKind(TextTrack::captionsKeyword());
- break;
- case InbandTextTrackPrivate::Descriptions:
- setKind(TextTrack::descriptionsKeyword());
- break;
- case InbandTextTrackPrivate::Chapters:
- setKind(TextTrack::chaptersKeyword());
- break;
- case InbandTextTrackPrivate::Metadata:
- setKind(TextTrack::metadataKeyword());
- break;
- case InbandTextTrackPrivate::Forced:
- setKind(TextTrack::forcedKeyword());
- break;
- case InbandTextTrackPrivate::None:
- default:
- ASSERT_NOT_REACHED();
- break;
- }
-}
-
-MediaTime InbandTextTrack::startTimeVariance() const
-{
- if (!m_private)
- return MediaTime::zeroTime();
-
- return m_private->startTimeVariance();
-}
-
} // namespace WebCore
#endif
diff --git a/Source/WebCore/html/track/InbandTextTrack.h b/Source/WebCore/html/track/InbandTextTrack.h
index cab7a3d04..1e1313bf5 100644
--- a/Source/WebCore/html/track/InbandTextTrack.h
+++ b/Source/WebCore/html/track/InbandTextTrack.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -32,7 +32,6 @@
#include "TextTrack.h"
#include "TextTrackCueGeneric.h"
#include <wtf/RefPtr.h>
-#include <wtf/TypeCasts.h>
namespace WebCore {
@@ -49,42 +48,17 @@ public:
virtual void setMode(const AtomicString&) override;
size_t inbandTrackIndex();
- virtual AtomicString inBandMetadataTrackDispatchType() const override;
-
- void setPrivate(PassRefPtr<InbandTextTrackPrivate>);
-
protected:
InbandTextTrack(ScriptExecutionContext*, TextTrackClient*, PassRefPtr<InbandTextTrackPrivate>);
- void setModeInternal(const AtomicString&);
- void updateKindFromPrivate();
-
RefPtr<InbandTextTrackPrivate> m_private;
private:
- virtual bool isInband() const override final { return true; }
- virtual void idChanged(TrackPrivateBase*, const AtomicString&) override;
- virtual void labelChanged(TrackPrivateBase*, const AtomicString&) override;
- virtual void languageChanged(TrackPrivateBase*, const AtomicString&) override;
- virtual void willRemove(TrackPrivateBase*) override;
-
- virtual void addDataCue(InbandTextTrackPrivate*, const MediaTime&, const MediaTime&, const void*, unsigned) override { ASSERT_NOT_REACHED(); }
-
-#if ENABLE(DATACUE_VALUE)
- virtual void addDataCue(InbandTextTrackPrivate*, const MediaTime&, const MediaTime&, PassRefPtr<SerializedPlatformRepresentation>, const String&) override { ASSERT_NOT_REACHED(); }
- virtual void updateDataCue(InbandTextTrackPrivate*, const MediaTime&, const MediaTime&, PassRefPtr<SerializedPlatformRepresentation>) override { ASSERT_NOT_REACHED(); }
- virtual void removeDataCue(InbandTextTrackPrivate*, const MediaTime&, const MediaTime&, PassRefPtr<SerializedPlatformRepresentation>) override { ASSERT_NOT_REACHED(); }
-#endif
- virtual void addGenericCue(InbandTextTrackPrivate*, PassRefPtr<GenericCueData>) override { ASSERT_NOT_REACHED(); }
- virtual void updateGenericCue(InbandTextTrackPrivate*, GenericCueData*) override { ASSERT_NOT_REACHED(); }
- virtual void removeGenericCue(InbandTextTrackPrivate*, GenericCueData*) override { ASSERT_NOT_REACHED(); }
-
- virtual void parseWebVTTFileHeader(InbandTextTrackPrivate*, String) override { ASSERT_NOT_REACHED(); }
- virtual void parseWebVTTCueData(InbandTextTrackPrivate*, const char*, unsigned) override { ASSERT_NOT_REACHED(); }
- virtual void parseWebVTTCueData(InbandTextTrackPrivate*, const ISOWebVTTCue&) override { ASSERT_NOT_REACHED(); }
-
- virtual MediaTime startTimeVariance() const override;
+ virtual void idChanged(TrackPrivateBase*, const String&) override;
+ virtual void labelChanged(TrackPrivateBase*, const String&) override;
+ virtual void languageChanged(TrackPrivateBase*, const String&) override;
+ virtual void willRemove(TrackPrivateBase*) override;
#if USE(PLATFORM_TEXT_TRACK_MENU)
virtual InbandTextTrackPrivate* privateTrack() override { return m_private.get(); }
@@ -93,10 +67,5 @@ private:
} // namespace WebCore
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::InbandTextTrack)
- static bool isType(const WebCore::TextTrack& track) { return track.isInband(); }
-SPECIALIZE_TYPE_TRAITS_END()
-
-#endif // ENABLE(VIDEO_TRACK)
-
-#endif // InbandTextTrack_h
+#endif
+#endif
diff --git a/Source/WebCore/html/track/InbandWebVTTTextTrack.cpp b/Source/WebCore/html/track/InbandWebVTTTextTrack.cpp
index d6115d9c2..7e03d41a6 100644
--- a/Source/WebCore/html/track/InbandWebVTTTextTrack.cpp
+++ b/Source/WebCore/html/track/InbandWebVTTTextTrack.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -31,18 +31,13 @@
#include "InbandTextTrackPrivate.h"
#include "Logging.h"
-#include "NotImplemented.h"
#include <wtf/text/CString.h>
-#if ENABLE(WEBVTT_REGIONS)
-#include "VTTRegionList.h"
-#endif
-
namespace WebCore {
-Ref<InbandTextTrack> InbandWebVTTTextTrack::create(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> playerPrivate)
+PassRefPtr<InbandTextTrack> InbandWebVTTTextTrack::create(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> playerPrivate)
{
- return adoptRef(*new InbandWebVTTTextTrack(context, client, playerPrivate));
+ return adoptRef(new InbandWebVTTTextTrack(context, client, playerPrivate));
}
InbandWebVTTTextTrack::InbandWebVTTTextTrack(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> trackPrivate)
@@ -54,57 +49,35 @@ InbandWebVTTTextTrack::~InbandWebVTTTextTrack()
{
}
-WebVTTParser& InbandWebVTTTextTrack::parser()
-{
- if (!m_webVTTParser)
- m_webVTTParser = std::make_unique<WebVTTParser>(static_cast<WebVTTParserClient*>(this), scriptExecutionContext());
- return *m_webVTTParser;
-}
-
void InbandWebVTTTextTrack::parseWebVTTCueData(InbandTextTrackPrivate* trackPrivate, const char* data, unsigned length)
{
ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
- parser().parseBytes(data, length);
-}
-
-void InbandWebVTTTextTrack::parseWebVTTCueData(InbandTextTrackPrivate* trackPrivate, const ISOWebVTTCue& cueData)
-{
- ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
- parser().parseCueData(cueData);
+ if (!m_webVTTParser)
+ m_webVTTParser = WebVTTParser::create(this, scriptExecutionContext());
+ m_webVTTParser->parseBytes(data, length);
}
void InbandWebVTTTextTrack::newCuesParsed()
{
Vector<RefPtr<WebVTTCueData>> cues;
- parser().getNewCues(cues);
-
- for (auto& cueData : cues) {
- RefPtr<VTTCue> vttCue = VTTCue::create(*scriptExecutionContext(), *cueData);
-
- if (hasCue(vttCue.get(), TextTrackCue::IgnoreDuration)) {
- LOG(Media, "InbandWebVTTTextTrack::newCuesParsed ignoring already added cue: start=%.2f, end=%.2f, content=\"%s\"\n", vttCue->startTime(), vttCue->endTime(), vttCue->text().utf8().data());
+ m_webVTTParser->getNewCues(cues);
+ for (size_t i = 0; i < cues.size(); ++i) {
+ RefPtr<WebVTTCueData> cueData = cues[i];
+ RefPtr<TextTrackCue> cue = TextTrackCue::create(*scriptExecutionContext(), cueData->startTime(), cueData->endTime(), cueData->content());
+ cue->setId(cueData->id());
+ cue->setCueSettings(cueData->settings());
+
+ if (hasCue(cue.get(), TextTrackCue::IgnoreDuration)) {
+ LOG(Media, "InbandWebVTTTextTrack::newCuesParsed ignoring already added cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime(), cueData->endTime(), cueData->content().utf8().data());
return;
}
- addCue(vttCue.release(), ASSERT_NO_EXCEPTION);
+ addCue(cue.release());
}
}
-
-#if ENABLE(WEBVTT_REGIONS)
-void InbandWebVTTTextTrack::newRegionsParsed()
-{
- Vector<RefPtr<VTTRegion>> newRegions;
- parser().getNewRegions(newRegions);
- for (auto& region : newRegions) {
- region->setTrack(this);
- regions()->add(region);
- }
-}
-#endif
-
void InbandWebVTTTextTrack::fileFailedToParse()
{
- LOG(Media, "Error parsing WebVTT stream.");
+ LOG(Media, "Unable to parse WebVTT stream.");
}
} // namespace WebCore
diff --git a/Source/WebCore/html/track/InbandWebVTTTextTrack.h b/Source/WebCore/html/track/InbandWebVTTTextTrack.h
index abfd42e43..c0c2ef830 100644
--- a/Source/WebCore/html/track/InbandWebVTTTextTrack.h
+++ b/Source/WebCore/html/track/InbandWebVTTTextTrack.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,22 +30,19 @@
#include "InbandTextTrack.h"
#include "WebVTTParser.h"
-#include <memory>
#include <wtf/RefPtr.h>
namespace WebCore {
-class InbandWebVTTTextTrack final : public InbandTextTrack, private WebVTTParserClient {
+class InbandWebVTTTextTrack : public InbandTextTrack, private WebVTTParserClient {
public:
- static Ref<InbandTextTrack> create(ScriptExecutionContext*, TextTrackClient*, PassRefPtr<InbandTextTrackPrivate>);
+ static PassRefPtr<InbandTextTrack> create(ScriptExecutionContext*, TextTrackClient*, PassRefPtr<InbandTextTrackPrivate>);
virtual ~InbandWebVTTTextTrack();
private:
InbandWebVTTTextTrack(ScriptExecutionContext*, TextTrackClient*, PassRefPtr<InbandTextTrackPrivate>);
- WebVTTParser& parser();
virtual void parseWebVTTCueData(InbandTextTrackPrivate*, const char* data, unsigned length) override;
- virtual void parseWebVTTCueData(InbandTextTrackPrivate*, const ISOWebVTTCue&) override;
virtual void newCuesParsed() override;
#if ENABLE(WEBVTT_REGIONS)
@@ -53,7 +50,11 @@ private:
#endif
virtual void fileFailedToParse() override;
- std::unique_ptr<WebVTTParser> m_webVTTParser;
+ virtual void addGenericCue(InbandTextTrackPrivate*, PassRefPtr<GenericCueData>) override { ASSERT_NOT_REACHED(); }
+ virtual void updateGenericCue(InbandTextTrackPrivate*, GenericCueData*) override { ASSERT_NOT_REACHED(); }
+ virtual void removeGenericCue(InbandTextTrackPrivate*, GenericCueData*) override { ASSERT_NOT_REACHED(); }
+
+ OwnPtr<WebVTTParser> m_webVTTParser;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/track/LoadableTextTrack.cpp b/Source/WebCore/html/track/LoadableTextTrack.cpp
index d0af46803..e61cffc6a 100644
--- a/Source/WebCore/html/track/LoadableTextTrack.cpp
+++ b/Source/WebCore/html/track/LoadableTextTrack.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -34,16 +34,12 @@
#include "ScriptExecutionContext.h"
#include "TextTrackCueList.h"
-#if ENABLE(WEBVTT_REGIONS)
-#include "VTTRegionList.h"
-#endif
-
namespace WebCore {
LoadableTextTrack::LoadableTextTrack(HTMLTrackElement* track, const String& kind, const String& label, const String& language)
: TextTrack(&track->document(), track, kind, emptyString(), label, language, TrackElement)
, m_trackElement(track)
- , m_loadTimer(*this, &LoadableTextTrack::loadTimerFired)
+ , m_loadTimer(this, &LoadableTextTrack::loadTimerFired)
, m_isDefault(false)
{
}
@@ -85,7 +81,7 @@ void LoadableTextTrack::setTrackElement(HTMLTrackElement* element)
m_trackElement = element;
}
-void LoadableTextTrack::loadTimerFired()
+void LoadableTextTrack::loadTimerFired(Timer<LoadableTextTrack>&)
{
if (m_loader)
m_loader->cancelLoad();
@@ -98,14 +94,14 @@ void LoadableTextTrack::loadTimerFired()
// 4. Download: If URL is not the empty string, perform a potentially CORS-enabled fetch of URL, with the
// mode being the state of the media element's crossorigin content attribute, the origin being the
// origin of the media element's Document, and the default origin behaviour set to fail.
- m_loader = std::make_unique<TextTrackLoader>(static_cast<TextTrackLoaderClient&>(*this), static_cast<ScriptExecutionContext*>(&m_trackElement->document()));
- if (!m_loader->load(m_url, m_trackElement->mediaElementCrossOriginAttribute(), m_trackElement->isInUserAgentShadowTree()))
+ m_loader = TextTrackLoader::create(*this, static_cast<ScriptExecutionContext*>(&m_trackElement->document()));
+ if (!m_loader->load(m_url, m_trackElement->mediaElementCrossOriginAttribute()))
m_trackElement->didCompleteLoad(HTMLTrackElement::Failure);
}
void LoadableTextTrack::newCuesAvailable(TextTrackLoader* loader)
{
- ASSERT_UNUSED(loader, m_loader.get() == loader);
+ ASSERT_UNUSED(loader, m_loader == loader);
Vector<RefPtr<TextTrackCue>> newCues;
m_loader->getNewCues(newCues);
@@ -124,7 +120,7 @@ void LoadableTextTrack::newCuesAvailable(TextTrackLoader* loader)
void LoadableTextTrack::cueLoadingCompleted(TextTrackLoader* loader, bool loadingFailed)
{
- ASSERT_UNUSED(loader, m_loader.get() == loader);
+ ASSERT_UNUSED(loader, m_loader == loader);
if (!m_trackElement)
return;
@@ -135,14 +131,14 @@ void LoadableTextTrack::cueLoadingCompleted(TextTrackLoader* loader, bool loadin
#if ENABLE(WEBVTT_REGIONS)
void LoadableTextTrack::newRegionsAvailable(TextTrackLoader* loader)
{
- ASSERT_UNUSED(loader, m_loader.get() == loader);
+ ASSERT_UNUSED(loader, m_loader == loader);
- Vector<RefPtr<VTTRegion>> newRegions;
+ Vector<RefPtr<TextTrackRegion>> newRegions;
m_loader->getNewRegions(newRegions);
for (size_t i = 0; i < newRegions.size(); ++i) {
newRegions[i]->setTrack(this);
- regions()->add(newRegions[i]);
+ regionList()->add(newRegions[i]);
}
}
#endif
diff --git a/Source/WebCore/html/track/LoadableTextTrack.h b/Source/WebCore/html/track/LoadableTextTrack.h
index 8e347c23b..970c3322d 100644
--- a/Source/WebCore/html/track/LoadableTextTrack.h
+++ b/Source/WebCore/html/track/LoadableTextTrack.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,7 +30,6 @@
#include "TextTrack.h"
#include "TextTrackLoader.h"
-#include <wtf/TypeCasts.h>
#include <wtf/Vector.h>
namespace WebCore {
@@ -38,11 +37,11 @@ namespace WebCore {
class HTMLTrackElement;
class LoadableTextTrack;
-class LoadableTextTrack final : public TextTrack, private TextTrackLoaderClient {
+class LoadableTextTrack : public TextTrack, private TextTrackLoaderClient {
public:
- static Ref<LoadableTextTrack> create(HTMLTrackElement* track, const String& kind, const String& label, const String& language)
+ static PassRefPtr<LoadableTextTrack> create(HTMLTrackElement* track, const String& kind, const String& label, const String& language)
{
- return adoptRef(*new LoadableTextTrack(track, kind, label, language));
+ return adoptRef(new LoadableTextTrack(track, kind, label, language));
}
virtual ~LoadableTextTrack();
@@ -65,25 +64,20 @@ private:
virtual void newCuesAvailable(TextTrackLoader*) override;
virtual void cueLoadingCompleted(TextTrackLoader*, bool loadingFailed) override;
#if ENABLE(WEBVTT_REGIONS)
- virtual void newRegionsAvailable(TextTrackLoader*) override;
+ virtual void newRegionsAvailable(TextTrackLoader*);
#endif
LoadableTextTrack(HTMLTrackElement*, const String& kind, const String& label, const String& language);
- void loadTimerFired();
+ void loadTimerFired(Timer<LoadableTextTrack>&);
HTMLTrackElement* m_trackElement;
- Timer m_loadTimer;
- std::unique_ptr<TextTrackLoader> m_loader;
+ Timer<LoadableTextTrack> m_loadTimer;
+ OwnPtr<TextTrackLoader> m_loader;
URL m_url;
bool m_isDefault;
};
} // namespace WebCore
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::LoadableTextTrack)
- static bool isType(const WebCore::TextTrack& track) { return track.trackType() == WebCore::TextTrack::TrackElement; }
-SPECIALIZE_TYPE_TRAITS_END()
-
-#endif // ENABLE(VIDEO_TRACK)
-
-#endif // LoadableTextTrack_h
+#endif
+#endif
diff --git a/Source/WebCore/html/track/TextTrack.cpp b/Source/WebCore/html/track/TextTrack.cpp
index 2a133a5fc..52b57b32c 100644
--- a/Source/WebCore/html/track/TextTrack.cpp
+++ b/Source/WebCore/html/track/TextTrack.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2011, 2013 Google Inc. All rights reserved.
- * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -40,8 +40,7 @@
#include "SourceBuffer.h"
#include "TextTrackCueList.h"
#include "TextTrackList.h"
-#include "VTTRegion.h"
-#include "VTTRegionList.h"
+#include "TextTrackRegionList.h"
namespace WebCore {
@@ -49,77 +48,77 @@ static const int invalidTrackIndex = -1;
const AtomicString& TextTrack::subtitlesKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, subtitles, ("subtitles", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, subtitles, ("subtitles", AtomicString::ConstructFromLiteral));
return subtitles;
}
const AtomicString& TextTrack::captionsKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, captions, ("captions", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, captions, ("captions", AtomicString::ConstructFromLiteral));
return captions;
}
const AtomicString& TextTrack::descriptionsKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, descriptions, ("descriptions", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, descriptions, ("descriptions", AtomicString::ConstructFromLiteral));
return descriptions;
}
const AtomicString& TextTrack::chaptersKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, chapters, ("chapters", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, chapters, ("chapters", AtomicString::ConstructFromLiteral));
return chapters;
}
const AtomicString& TextTrack::metadataKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, metadata, ("metadata", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, metadata, ("metadata", AtomicString::ConstructFromLiteral));
return metadata;
}
const AtomicString& TextTrack::forcedKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, forced, ("forced", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, forced, ("forced", AtomicString::ConstructFromLiteral));
return forced;
}
const AtomicString& TextTrack::disabledKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, open, ("disabled", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, open, ("disabled", AtomicString::ConstructFromLiteral));
return open;
}
const AtomicString& TextTrack::hiddenKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, closed, ("hidden", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, closed, ("hidden", AtomicString::ConstructFromLiteral));
return closed;
}
const AtomicString& TextTrack::showingKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, ended, ("showing", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, ended, ("showing", AtomicString::ConstructFromLiteral));
return ended;
}
TextTrack* TextTrack::captionMenuOffItem()
{
- static TextTrack& off = TextTrack::create(0, 0, "off menu item", "", "", "").leakRef();
- return &off;
+ static TextTrack* off = TextTrack::create(0, 0, "off menu item", "", "", "").leakRef();
+ return off;
}
TextTrack* TextTrack::captionMenuAutomaticItem()
{
- static TextTrack& automatic = TextTrack::create(0, 0, "automatic menu item", "", "", "").leakRef();
- return &automatic;
+ static TextTrack* automatic = TextTrack::create(0, 0, "automatic menu item", "", "", "").leakRef();
+ return automatic;
}
TextTrack::TextTrack(ScriptExecutionContext* context, TextTrackClient* client, const AtomicString& kind, const AtomicString& id, const AtomicString& label, const AtomicString& language, TextTrackType type)
: TrackBase(TrackBase::TextTrack, id, label, language)
, m_cues(0)
+ , m_scriptExecutionContext(context)
#if ENABLE(WEBVTT_REGIONS)
, m_regions(0)
#endif
- , m_scriptExecutionContext(context)
, m_mode(disabledKeyword().string())
, m_client(client)
, m_trackType(type)
@@ -140,10 +139,8 @@ TextTrack::~TextTrack()
for (size_t i = 0; i < m_cues->length(); ++i)
m_cues->item(i)->setTrack(0);
#if ENABLE(WEBVTT_REGIONS)
- if (m_regions) {
- for (size_t i = 0; i < m_regions->length(); ++i)
- m_regions->item(i)->setTrack(0);
- }
+ for (size_t i = 0; i < m_regions->length(); ++i)
+ m_regions->item(i)->setTrack(0);
#endif
}
clearClient();
@@ -210,10 +207,11 @@ void TextTrack::setKind(const AtomicString& newKind)
void TextTrack::setMode(const AtomicString& mode)
{
- ASSERT(mode == disabledKeyword() || mode == hiddenKeyword() || mode == showingKeyword());
-
// On setting, if the new value isn't equal to what the attribute would currently
// return, the new value must be processed as follows ...
+ if (mode != disabledKeyword() && mode != hiddenKeyword() && mode != showingKeyword())
+ return;
+
if (m_mode == mode)
return;
@@ -222,13 +220,9 @@ void TextTrack::setMode(const AtomicString& mode)
if (mode == disabledKeyword() && m_client && m_cues)
m_client->textTrackRemoveCues(this, m_cues.get());
- if (mode != showingKeyword() && m_cues) {
- for (size_t i = 0; i < m_cues->length(); ++i) {
- TextTrackCue* cue = m_cues->item(i);
- if (cue->isRenderable())
- toVTTCue(cue)->removeDisplayTree();
- }
- }
+ if (mode != showingKeyword() && m_cues)
+ for (size_t i = 0; i < m_cues->length(); ++i)
+ m_cues->item(i)->removeDisplayTree();
m_mode = mode;
@@ -245,7 +239,7 @@ TextTrackCueList* TextTrack::cues()
// http://www.whatwg.org/specs/web-apps/current-work/#dom-texttrack-cues
if (m_mode != disabledKeyword())
return ensureTextTrackCueList();
- return nullptr;
+ return 0;
}
void TextTrack::removeAllCues()
@@ -257,9 +251,9 @@ void TextTrack::removeAllCues()
m_client->textTrackRemoveCues(this, m_cues.get());
for (size_t i = 0; i < m_cues->length(); ++i)
- m_cues->item(i)->setTrack(nullptr);
+ m_cues->item(i)->setTrack(0);
- m_cues = nullptr;
+ m_cues = 0;
}
TextTrackCueList* TextTrack::activeCues() const
@@ -272,29 +266,18 @@ TextTrackCueList* TextTrack::activeCues() const
// http://www.whatwg.org/specs/web-apps/current-work/#dom-texttrack-activecues
if (m_cues && m_mode != disabledKeyword())
return m_cues->activeCues();
- return nullptr;
+ return 0;
}
-void TextTrack::addCue(PassRefPtr<TextTrackCue> prpCue, ExceptionCode& ec)
+void TextTrack::addCue(PassRefPtr<TextTrackCue> prpCue)
{
if (!prpCue)
return;
RefPtr<TextTrackCue> cue = prpCue;
- // 4.7.10.12.6 Text tracks exposing in-band metadata
- // The UA will use DataCue to expose only text track cue objects that belong to a text track that has a text
- // track kind of metadata.
- // If a DataCue is added to a TextTrack via the addCue() method but the text track does not have its text
- // track kind set to metadata, throw a InvalidNodeTypeError exception and don't add the cue to the TextTrackList
- // of the TextTrack.
- if (cue->cueType() == TextTrackCue::Data && kind() != metadataKeyword()) {
- ec = INVALID_NODE_TYPE_ERR;
- return;
- }
-
// TODO(93143): Add spec-compliant behavior for negative time values.
- if (!cue->startMediaTime().isValid() || !cue->endMediaTime().isValid() || cue->startMediaTime() < MediaTime::zeroTime() || cue->endMediaTime() < MediaTime::zeroTime())
+ if (std::isnan(cue->startTime()) || std::isnan(cue->endTime()) || cue->startTime() < 0 || cue->endTime() < 0)
return;
// 4.8.10.12.5 Text track API
@@ -343,35 +326,40 @@ void TextTrack::removeCue(TextTrackCue* cue, ExceptionCode& ec)
}
#if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS)
-VTTRegionList* TextTrack::ensureVTTRegionList()
+TextTrackRegionList* TextTrack::regionList()
+{
+ return ensureTextTrackRegionList();
+}
+
+TextTrackRegionList* TextTrack::ensureTextTrackRegionList()
{
if (!m_regions)
- m_regions = VTTRegionList::create();
+ m_regions = TextTrackRegionList::create();
return m_regions.get();
}
-VTTRegionList* TextTrack::regions()
+TextTrackRegionList* TextTrack::regions()
{
// If the text track mode of the text track that the TextTrack object
// represents is not the text track disabled mode, then the regions
- // attribute must return a live VTTRegionList object that represents
+ // attribute must return a live TextTrackRegionList object that represents
// the text track list of regions of the text track. Otherwise, it must
// return null. When an object is returned, the same object must be returned
// each time.
if (m_mode != disabledKeyword())
- return ensureVTTRegionList();
+ return ensureTextTrackRegionList();
return 0;
}
-void TextTrack::addRegion(PassRefPtr<VTTRegion> prpRegion)
+void TextTrack::addRegion(PassRefPtr<TextTrackRegion> prpRegion)
{
if (!prpRegion)
return;
- RefPtr<VTTRegion> region = prpRegion;
- VTTRegionList* regionList = ensureVTTRegionList();
+ RefPtr<TextTrackRegion> region = prpRegion;
+ TextTrackRegionList* regionList = ensureTextTrackRegionList();
// 1. If the given region is in a text track list of regions, then remove
// region from that text track list of regions.
@@ -383,7 +371,7 @@ void TextTrack::addRegion(PassRefPtr<VTTRegion> prpRegion)
// a region with the same identifier as region replace the values of that
// region's width, height, anchor point, viewport anchor point and scroll
// attributes with those of region.
- VTTRegion* existingRegion = regionList->getRegionById(region->id());
+ TextTrackRegion* existingRegion = regionList->getRegionById(region->id());
if (existingRegion) {
existingRegion->updateParametersFromRegion(region.get());
return;
@@ -395,7 +383,7 @@ void TextTrack::addRegion(PassRefPtr<VTTRegion> prpRegion)
regionList->add(region);
}
-void TextTrack::removeRegion(VTTRegion* region, ExceptionCode &ec)
+void TextTrack::removeRegion(TextTrackRegion* region, ExceptionCode &ec)
{
if (!region)
return;
@@ -485,7 +473,7 @@ int TextTrack::trackIndexRelativeToRenderedTracks()
bool TextTrack::hasCue(TextTrackCue* cue, TextTrackCue::CueMatchRules match)
{
- if (cue->startMediaTime() < MediaTime::zeroTime() || cue->endMediaTime() < MediaTime::zeroTime())
+ if (cue->startTime() < 0 || cue->endTime() < 0)
return false;
if (!m_cues || !m_cues->length())
@@ -507,7 +495,7 @@ bool TextTrack::hasCue(TextTrackCue* cue, TextTrackCue::CueMatchRules match)
// If there is more than one cue with the same start time, back up to first one so we
// consider all of them.
- while (searchStart >= 2 && cue->hasEquivalentStartTime(*m_cues->item(searchStart - 2)))
+ while (searchStart >= 2 && cue->startTime() == m_cues->item(searchStart - 2)->startTime())
--searchStart;
bool firstCompare = true;
@@ -519,20 +507,19 @@ bool TextTrack::hasCue(TextTrackCue* cue, TextTrackCue::CueMatchRules match)
return false;
existingCue = m_cues->item(searchStart - 1);
- if (!existingCue)
- return false;
-
- if (cue->startMediaTime() > (existingCue->startMediaTime() + startTimeVariance()))
+ if (!existingCue || cue->startTime() > existingCue->startTime())
return false;
- if (existingCue->isEqual(*cue, match))
- return true;
+ if (!existingCue->isEqual(*cue, match))
+ continue;
+
+ return true;
}
}
size_t index = (searchStart + searchEnd) / 2;
existingCue = m_cues->item(index);
- if ((cue->startMediaTime() + startTimeVariance()) < existingCue->startMediaTime() || (match != TextTrackCue::IgnoreDuration && cue->hasEquivalentStartTime(*existingCue) && cue->endMediaTime() > existingCue->endMediaTime()))
+ if (cue->startTime() < existingCue->startTime() || (match != TextTrackCue::IgnoreDuration && cue->startTime() == existingCue->startTime() && cue->endTime() > existingCue->endTime()))
searchEnd = index;
else
searchStart = index + 1;
@@ -545,6 +532,8 @@ bool TextTrack::hasCue(TextTrackCue* cue, TextTrackCue::CueMatchRules match)
#if USE(PLATFORM_TEXT_TRACK_MENU)
PassRefPtr<PlatformTextTrack> TextTrack::platformTextTrack()
{
+ static int uniqueId = 0;
+
if (m_platformTextTrack)
return m_platformTextTrack;
@@ -570,15 +559,7 @@ PassRefPtr<PlatformTextTrack> TextTrack::platformTextTrack()
else if (m_trackType == InBand)
type = PlatformTextTrack::InBand;
- PlatformTextTrack::TrackMode platformMode = PlatformTextTrack::Disabled;
- if (TextTrack::hiddenKeyword() == mode())
- platformMode = PlatformTextTrack::Hidden;
- else if (TextTrack::disabledKeyword() == mode())
- platformMode = PlatformTextTrack::Disabled;
- else if (TextTrack::showingKeyword() == mode())
- platformMode = PlatformTextTrack::Showing;
-
- m_platformTextTrack = PlatformTextTrack::create(this, label(), language(), platformMode, platformKind, type, uniqueId());
+ m_platformTextTrack = PlatformTextTrack::create(this, label(), language(), platformKind, type, ++uniqueId);
return m_platformTextTrack;
}
diff --git a/Source/WebCore/html/track/TextTrack.h b/Source/WebCore/html/track/TextTrack.h
index 522e57436..43e788f33 100644
--- a/Source/WebCore/html/track/TextTrack.h
+++ b/Source/WebCore/html/track/TextTrack.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -32,7 +32,7 @@
#include "ExceptionCode.h"
#include "TextTrackCue.h"
#include "TrackBase.h"
-#include "VTTCue.h"
+#include <wtf/PassOwnPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
@@ -46,8 +46,8 @@ class ScriptExecutionContext;
class TextTrack;
class TextTrackCueList;
#if ENABLE(WEBVTT_REGIONS)
-class VTTRegion;
-class VTTRegionList;
+class TextTrackRegion;
+class TextTrackRegionList;
#endif
class TextTrackClient {
@@ -67,9 +67,9 @@ class TextTrack : public TrackBase, public EventTargetWithInlineData
#endif
{
public:
- static Ref<TextTrack> create(ScriptExecutionContext* context, TextTrackClient* client, const AtomicString& kind, const AtomicString& id, const AtomicString& label, const AtomicString& language)
+ static PassRefPtr<TextTrack> create(ScriptExecutionContext* context, TextTrackClient* client, const AtomicString& kind, const AtomicString& id, const AtomicString& label, const AtomicString& language)
{
- return adoptRef(*new TextTrack(context, client, kind, id, label, language, AddTrack));
+ return adoptRef(new TextTrack(context, client, kind, id, label, language, AddTrack));
}
virtual ~TextTrack();
@@ -94,8 +94,6 @@ public:
virtual void setKind(const AtomicString&) override;
- virtual AtomicString inBandMetadataTrackDispatchType() const { return emptyString(); }
-
AtomicString mode() const { return m_mode; }
virtual void setMode(const AtomicString&);
@@ -109,20 +107,22 @@ public:
virtual void clearClient() override { m_client = 0; }
TextTrackClient* client() { return m_client; }
- void addCue(PassRefPtr<TextTrackCue>, ExceptionCode&);
+ void addCue(PassRefPtr<TextTrackCue>);
virtual void removeCue(TextTrackCue*, ExceptionCode&);
bool hasCue(TextTrackCue*, TextTrackCue::CueMatchRules = TextTrackCue::MatchAllFields);
#if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS)
- VTTRegionList* regions();
- void addRegion(PassRefPtr<VTTRegion>);
- void removeRegion(VTTRegion*, ExceptionCode&);
+ TextTrackRegionList* regions();
+ void addRegion(PassRefPtr<TextTrackRegion>);
+ void removeRegion(TextTrackRegion*, ExceptionCode&);
#endif
void cueWillChange(TextTrackCue*);
void cueDidChange(TextTrackCue*);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(cuechange);
+
enum TextTrackType { TrackElement, AddTrack, InBand };
TextTrackType trackType() const { return m_trackType; }
@@ -154,15 +154,14 @@ public:
virtual void setLanguage(const AtomicString&) override;
#endif
- virtual bool isInband() const { return false; }
-
- virtual MediaTime startTimeVariance() const { return MediaTime::zeroTime(); }
-
using RefCounted<TrackBase>::ref;
using RefCounted<TrackBase>::deref;
protected:
TextTrack(ScriptExecutionContext*, TextTrackClient*, const AtomicString& kind, const AtomicString& id, const AtomicString& label, const AtomicString& language, TextTrackType);
+#if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS)
+ TextTrackRegionList* regionList();
+#endif
RefPtr<TextTrackCueList> m_cues;
@@ -175,8 +174,8 @@ private:
virtual void derefEventTarget() override final { deref(); }
#if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS)
- VTTRegionList* ensureVTTRegionList();
- RefPtr<VTTRegionList> m_regions;
+ TextTrackRegionList* ensureTextTrackRegionList();
+ RefPtr<TextTrackRegionList> m_regions;
#endif
#if USE(PLATFORM_TEXT_TRACK_MENU)
diff --git a/Source/WebCore/html/track/TextTrack.idl b/Source/WebCore/html/track/TextTrack.idl
index 404d02226..90f6d1b93 100644
--- a/Source/WebCore/html/track/TextTrack.idl
+++ b/Source/WebCore/html/track/TextTrack.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -23,9 +23,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-enum TextTrackMode { "disabled", "hidden", "showing" };
-enum TextTrackKind { "subtitles", "captions", "descriptions", "chapters", "metadata" };
-
[
Conditional=VIDEO_TRACK,
EventTarget,
@@ -34,29 +31,31 @@ enum TextTrackKind { "subtitles", "captions", "descriptions", "chapters", "me
SkipVTableValidation,
] interface TextTrack {
readonly attribute DOMString id;
- [CustomSetter] attribute TextTrackKind kind;
+ [CustomSetter] attribute DOMString kind;
readonly attribute DOMString label;
[CustomSetter] attribute DOMString language;
- readonly attribute DOMString inBandMetadataTrackDispatchType;
- attribute TextTrackMode mode;
+ attribute DOMString mode;
readonly attribute TextTrackCueList cues;
readonly attribute TextTrackCueList activeCues;
+ attribute EventListener oncuechange;
- [RaisesException] void addCue(TextTrackCue cue);
+ void addCue(TextTrackCue cue);
[RaisesException] void removeCue(TextTrackCue cue);
- attribute EventHandler oncuechange;
-
-#if !defined(LANGUAGE_GOBJECT) || !LANGUAGE_GOBJECT // Work around shortcomings in the gobject binding generator handling of conditional features by turning these off for gobject.
- [Conditional=WEBVTT_REGIONS] readonly attribute VTTRegionList regions;
- [Conditional=WEBVTT_REGIONS] void addRegion(VTTRegion region);
- [Conditional=WEBVTT_REGIONS, RaisesException] void removeRegion(VTTRegion region);
+#if defined(ENABLE_WEBVTT_REGIONS) && ENABLE_WEBVTT_REGIONS
+ readonly attribute TextTrackRegionList regions;
+ void addRegion(TextTrackRegion region);
+ [RaisesException] void removeRegion(TextTrackRegion region);
#endif
// EventTarget interface
- void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
- void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
- [RaisesException] boolean dispatchEvent(Event event);
+ void addEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ void removeEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ [RaisesException] boolean dispatchEvent(Event evt);
};
diff --git a/Source/WebCore/html/track/TextTrackCue.cpp b/Source/WebCore/html/track/TextTrackCue.cpp
index af2cf267e..67ff91a98 100644
--- a/Source/WebCore/html/track/TextTrackCue.cpp
+++ b/Source/WebCore/html/track/TextTrackCue.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2011, 2013 Google Inc. All rights reserved.
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -43,46 +43,195 @@
#include "HTMLSpanElement.h"
#include "Logging.h"
#include "NodeTraversal.h"
+#include "RenderTextTrackCue.h"
#include "Text.h"
#include "TextTrack.h"
#include "TextTrackCueList.h"
-#include "VTTCue.h"
+#include "WebVTTElement.h"
+#include "WebVTTParser.h"
#include <wtf/MathExtras.h>
#include <wtf/text/StringBuilder.h>
-#if ENABLE(WEBVTT_REGIONS)
-#include "VTTRegionList.h"
-#endif
-
namespace WebCore {
static const int invalidCueIndex = -1;
+static const int undefinedPosition = -1;
+
+static const String& startKeyword()
+{
+ DEFINE_STATIC_LOCAL(const String, start, (ASCIILiteral("start")));
+ return start;
+}
+
+static const String& middleKeyword()
+{
+ DEFINE_STATIC_LOCAL(const String, middle, (ASCIILiteral("middle")));
+ return middle;
+}
+
+static const String& endKeyword()
+{
+ DEFINE_STATIC_LOCAL(const String, end, (ASCIILiteral("end")));
+ return end;
+}
+
+static const String& horizontalKeyword()
+{
+ return emptyString();
+}
+
+static const String& verticalGrowingLeftKeyword()
+{
+ DEFINE_STATIC_LOCAL(const String, verticalrl, (ASCIILiteral("rl")));
+ return verticalrl;
+}
+
+static const String& verticalGrowingRightKeyword()
+{
+ DEFINE_STATIC_LOCAL(const String, verticallr, (ASCIILiteral("lr")));
+ return verticallr;
+}
+
+// ----------------------------
+
+TextTrackCueBox::TextTrackCueBox(Document& document, TextTrackCue* cue)
+ : HTMLElement(divTag, document)
+ , m_cue(cue)
+{
+ setPseudo(textTrackCueBoxShadowPseudoId());
+}
+
+TextTrackCue* TextTrackCueBox::getCue() const
+{
+ return m_cue;
+}
+
+void TextTrackCueBox::applyCSSProperties(const IntSize&)
+{
+ // FIXME: Apply all the initial CSS positioning properties. http://wkb.ug/79916
+
+ // 3.5.1 On the (root) List of WebVTT Node Objects:
+
+ // the 'position' property must be set to 'absolute'
+ setInlineStyleProperty(CSSPropertyPosition, CSSValueAbsolute);
+
+ // the 'unicode-bidi' property must be set to 'plaintext'
+ setInlineStyleProperty(CSSPropertyUnicodeBidi, CSSValueWebkitPlaintext);
+
+ // the 'direction' property must be set to direction
+ setInlineStyleProperty(CSSPropertyDirection, m_cue->getCSSWritingDirection());
+
+ // the 'writing-mode' property must be set to writing-mode
+ setInlineStyleProperty(CSSPropertyWebkitWritingMode, m_cue->getCSSWritingMode(), false);
+
+ std::pair<float, float> position = m_cue->getCSSPosition();
+
+ // the 'top' property must be set to top,
+ setInlineStyleProperty(CSSPropertyTop, static_cast<double>(position.second), CSSPrimitiveValue::CSS_PERCENTAGE);
+
+ // the 'left' property must be set to left
+ setInlineStyleProperty(CSSPropertyLeft, static_cast<double>(position.first), CSSPrimitiveValue::CSS_PERCENTAGE);
+
+ // the 'width' property must be set to width, and the 'height' property must be set to height
+ if (m_cue->vertical() == horizontalKeyword()) {
+ setInlineStyleProperty(CSSPropertyWidth, static_cast<double>(m_cue->getCSSSize()), CSSPrimitiveValue::CSS_PERCENTAGE);
+ setInlineStyleProperty(CSSPropertyHeight, CSSValueAuto);
+ } else {
+ setInlineStyleProperty(CSSPropertyWidth, CSSValueAuto);
+ setInlineStyleProperty(CSSPropertyHeight, static_cast<double>(m_cue->getCSSSize()), CSSPrimitiveValue::CSS_PERCENTAGE);
+ }
-PassRefPtr<TextTrackCue> TextTrackCue::create(ScriptExecutionContext& context, double start, double end, const String& content)
+ // The 'text-align' property on the (root) List of WebVTT Node Objects must
+ // be set to the value in the second cell of the row of the table below
+ // whose first cell is the value of the corresponding cue's text track cue
+ // alignment:
+ if (m_cue->align() == startKeyword())
+ setInlineStyleProperty(CSSPropertyTextAlign, CSSValueStart);
+ else if (m_cue->align() == endKeyword())
+ setInlineStyleProperty(CSSPropertyTextAlign, CSSValueEnd);
+ else
+ setInlineStyleProperty(CSSPropertyTextAlign, CSSValueCenter);
+
+ if (!m_cue->snapToLines()) {
+ // 10.13.1 Set up x and y:
+ // Note: x and y are set through the CSS left and top above.
+
+ // 10.13.2 Position the boxes in boxes such that the point x% along the
+ // width of the bounding box of the boxes in boxes is x% of the way
+ // across the width of the video's rendering area, and the point y%
+ // along the height of the bounding box of the boxes in boxes is y%
+ // of the way across the height of the video's rendering area, while
+ // maintaining the relative positions of the boxes in boxes to each
+ // other.
+ setInlineStyleProperty(CSSPropertyWebkitTransform,
+ String::format("translate(-%.2f%%, -%.2f%%)", position.first, position.second));
+
+ setInlineStyleProperty(CSSPropertyWhiteSpace, CSSValuePre);
+ }
+}
+
+const AtomicString& TextTrackCueBox::textTrackCueBoxShadowPseudoId()
{
- return create(context, MediaTime::createWithDouble(start), MediaTime::createWithDouble(end), content);
+ DEFINE_STATIC_LOCAL(const AtomicString, trackDisplayBoxShadowPseudoId, ("-webkit-media-text-track-display", AtomicString::ConstructFromLiteral));
+ return trackDisplayBoxShadowPseudoId;
}
-PassRefPtr<TextTrackCue> TextTrackCue::create(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, const String& content)
+RenderPtr<RenderElement> TextTrackCueBox::createElementRenderer(PassRef<RenderStyle> style)
{
- return VTTCue::create(context, start, end, content);
+ return createRenderer<RenderTextTrackCue>(*this, std::move(style));
}
-TextTrackCue::TextTrackCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end)
+// ----------------------------
+
+TextTrackCue::TextTrackCue(ScriptExecutionContext& context, double start, double end, const String& content)
: m_startTime(start)
, m_endTime(end)
+ , m_content(content)
+ , m_linePosition(undefinedPosition)
+ , m_computedLinePosition(undefinedPosition)
+ , m_textPosition(50)
+ , m_cueSize(100)
, m_cueIndex(invalidCueIndex)
, m_processingCueChanges(0)
+ , m_writingDirection(Horizontal)
+ , m_cueAlignment(Middle)
+ , m_webVTTNodeTree(0)
, m_track(0)
, m_scriptExecutionContext(context)
, m_isActive(false)
, m_pauseOnExit(false)
+ , m_snapToLines(true)
+ , m_cueBackgroundBox(HTMLSpanElement::create(spanTag, toDocument(context)))
+ , m_displayTreeShouldChange(true)
+ , m_displayDirection(CSSValueLtr)
{
ASSERT(m_scriptExecutionContext.isDocument());
+
+ // 4. If the text track cue writing direction is horizontal, then let
+ // writing-mode be 'horizontal-tb'. Otherwise, if the text track cue writing
+ // direction is vertical growing left, then let writing-mode be
+ // 'vertical-rl'. Otherwise, the text track cue writing direction is
+ // vertical growing right; let writing-mode be 'vertical-lr'.
+ m_displayWritingModeMap[Horizontal] = CSSValueHorizontalTb;
+ m_displayWritingModeMap[VerticalGrowingLeft] = CSSValueVerticalRl;
+ m_displayWritingModeMap[VerticalGrowingRight] = CSSValueVerticalLr;
}
TextTrackCue::~TextTrackCue()
{
+ removeDisplayTree();
+}
+
+PassRefPtr<TextTrackCueBox> TextTrackCue::createDisplayTree()
+{
+ return TextTrackCueBox::create(ownerDocument(), this);
+}
+
+TextTrackCueBox* TextTrackCue::displayTreeInternal()
+{
+ if (!m_displayTree)
+ m_displayTree = createDisplayTree();
+ return m_displayTree.get();
}
void TextTrackCue::willChange()
@@ -102,6 +251,8 @@ void TextTrackCue::didChange()
if (m_track)
m_track->cueDidChange(this);
+
+ m_displayTreeShouldChange = true;
}
TextTrack* TextTrackCue::track() const
@@ -133,14 +284,9 @@ void TextTrackCue::setStartTime(double value, ExceptionCode& ec)
}
// TODO(93143): Add spec-compliant behavior for negative time values.
- if (m_startTime.toDouble() == value || value < 0)
+ if (m_startTime == value || value < 0)
return;
- setStartTime(MediaTime::createWithDouble(value));
-}
-
-void TextTrackCue::setStartTime(const MediaTime& value)
-{
willChange();
m_startTime = value;
didChange();
@@ -155,14 +301,9 @@ void TextTrackCue::setEndTime(double value, ExceptionCode& ec)
}
// TODO(93143): Add spec-compliant behavior for negative time values.
- if (m_endTime.toDouble() == value || value < 0)
+ if (m_endTime == value || value < 0)
return;
- setEndTime(MediaTime::createWithDouble(value));
-}
-
-void TextTrackCue::setEndTime(const MediaTime& value)
-{
willChange();
m_endTime = value;
didChange();
@@ -176,6 +317,169 @@ void TextTrackCue::setPauseOnExit(bool value)
m_pauseOnExit = value;
}
+const String& TextTrackCue::vertical() const
+{
+ switch (m_writingDirection) {
+ case Horizontal:
+ return horizontalKeyword();
+ case VerticalGrowingLeft:
+ return verticalGrowingLeftKeyword();
+ case VerticalGrowingRight:
+ return verticalGrowingRightKeyword();
+ default:
+ ASSERT_NOT_REACHED();
+ return emptyString();
+ }
+}
+
+void TextTrackCue::setVertical(const String& value, ExceptionCode& ec)
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-vertical
+ // On setting, the text track cue writing direction must be set to the value given
+ // in the first cell of the row in the table above whose second cell is a
+ // case-sensitive match for the new value, if any. If none of the values match, then
+ // the user agent must instead throw a SyntaxError exception.
+
+ WritingDirection direction = m_writingDirection;
+ if (value == horizontalKeyword())
+ direction = Horizontal;
+ else if (value == verticalGrowingLeftKeyword())
+ direction = VerticalGrowingLeft;
+ else if (value == verticalGrowingRightKeyword())
+ direction = VerticalGrowingRight;
+ else
+ ec = SYNTAX_ERR;
+
+ if (direction == m_writingDirection)
+ return;
+
+ willChange();
+ m_writingDirection = direction;
+ didChange();
+}
+
+void TextTrackCue::setSnapToLines(bool value)
+{
+ if (m_snapToLines == value)
+ return;
+
+ willChange();
+ m_snapToLines = value;
+ didChange();
+}
+
+void TextTrackCue::setLine(int position, ExceptionCode& ec)
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-line
+ // On setting, if the text track cue snap-to-lines flag is not set, and the new
+ // value is negative or greater than 100, then throw an IndexSizeError exception.
+ if (!m_snapToLines && (position < 0 || position > 100)) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ // Otherwise, set the text track cue line position to the new value.
+ if (m_linePosition == position)
+ return;
+
+ willChange();
+ m_linePosition = position;
+ m_computedLinePosition = calculateComputedLinePosition();
+ didChange();
+}
+
+void TextTrackCue::setPosition(int position, ExceptionCode& ec)
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-position
+ // On setting, if the new value is negative or greater than 100, then throw an IndexSizeError exception.
+ // Otherwise, set the text track cue text position to the new value.
+ if (position < 0 || position > 100) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ // Otherwise, set the text track cue line position to the new value.
+ if (m_textPosition == position)
+ return;
+
+ willChange();
+ m_textPosition = position;
+ didChange();
+}
+
+void TextTrackCue::setSize(int size, ExceptionCode& ec)
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-size
+ // On setting, if the new value is negative or greater than 100, then throw an IndexSizeError
+ // exception. Otherwise, set the text track cue size to the new value.
+ if (size < 0 || size > 100) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ // Otherwise, set the text track cue line position to the new value.
+ if (m_cueSize == size)
+ return;
+
+ willChange();
+ m_cueSize = size;
+ didChange();
+}
+
+const String& TextTrackCue::align() const
+{
+ switch (m_cueAlignment) {
+ case Start:
+ return startKeyword();
+ case Middle:
+ return middleKeyword();
+ case End:
+ return endKeyword();
+ default:
+ ASSERT_NOT_REACHED();
+ return emptyString();
+ }
+}
+
+void TextTrackCue::setAlign(const String& value, ExceptionCode& ec)
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-align
+ // On setting, the text track cue alignment must be set to the value given in the
+ // first cell of the row in the table above whose second cell is a case-sensitive
+ // match for the new value, if any. If none of the values match, then the user
+ // agent must instead throw a SyntaxError exception.
+
+ CueAlignment alignment = m_cueAlignment;
+ if (value == startKeyword())
+ alignment = Start;
+ else if (value == middleKeyword())
+ alignment = Middle;
+ else if (value == endKeyword())
+ alignment = End;
+ else
+ ec = SYNTAX_ERR;
+
+ if (alignment == m_cueAlignment)
+ return;
+
+ willChange();
+ m_cueAlignment = alignment;
+ didChange();
+}
+
+void TextTrackCue::setText(const String& text)
+{
+ if (m_content == text)
+ return;
+
+ willChange();
+ // Clear the document fragment but don't bother to create it again just yet as we can do that
+ // when it is requested.
+ m_webVTTNodeTree = 0;
+ m_content = text;
+ didChange();
+}
+
int TextTrackCue::cueIndex()
{
if (m_cueIndex == invalidCueIndex) {
@@ -193,6 +497,49 @@ void TextTrackCue::invalidateCueIndex()
m_cueIndex = invalidCueIndex;
}
+void TextTrackCue::createWebVTTNodeTree()
+{
+ if (!m_webVTTNodeTree)
+ m_webVTTNodeTree = WebVTTParser::create(0, &m_scriptExecutionContext)->createDocumentFragmentFromCueText(m_content);
+}
+
+void TextTrackCue::copyWebVTTNodeToDOMTree(ContainerNode* webVTTNode, ContainerNode* parent)
+{
+ for (Node* node = webVTTNode->firstChild(); node; node = node->nextSibling()) {
+ RefPtr<Node> clonedNode;
+ if (node->isWebVTTElement())
+ clonedNode = toWebVTTElement(node)->createEquivalentHTMLElement(ownerDocument());
+ else
+ clonedNode = node->cloneNode(false);
+ parent->appendChild(clonedNode, ASSERT_NO_EXCEPTION);
+ if (node->isContainerNode())
+ copyWebVTTNodeToDOMTree(toContainerNode(node), toContainerNode(clonedNode.get()));
+ }
+}
+
+PassRefPtr<DocumentFragment> TextTrackCue::getCueAsHTML()
+{
+ createWebVTTNodeTree();
+ if (!m_webVTTNodeTree)
+ return 0;
+
+ RefPtr<DocumentFragment> clonedFragment = DocumentFragment::create(ownerDocument());
+ copyWebVTTNodeToDOMTree(m_webVTTNodeTree.get(), clonedFragment.get());
+ return clonedFragment.release();
+}
+
+PassRefPtr<DocumentFragment> TextTrackCue::createCueRenderingTree()
+{
+ RefPtr<DocumentFragment> clonedFragment;
+ createWebVTTNodeTree();
+ if (!m_webVTTNodeTree)
+ return 0;
+
+ clonedFragment = DocumentFragment::create(ownerDocument());
+ m_webVTTNodeTree->cloneChildNodes(clonedFragment.get());
+ return clonedFragment.release();
+}
+
bool TextTrackCue::dispatchEvent(PassRefPtr<Event> event)
{
// When a TextTrack's mode is disabled: no cues are active, no events fired.
@@ -202,6 +549,18 @@ bool TextTrackCue::dispatchEvent(PassRefPtr<Event> event)
return EventTarget::dispatchEvent(event);
}
+#if ENABLE(WEBVTT_REGIONS)
+void TextTrackCue::setRegionId(const String& regionId)
+{
+ if (m_regionId == regionId)
+ return;
+
+ willChange();
+ m_regionId = regionId;
+ didChange();
+}
+#endif
+
bool TextTrackCue::isActive()
{
return m_isActive && track() && track()->mode() != TextTrack::disabledKeyword();
@@ -210,61 +569,636 @@ bool TextTrackCue::isActive()
void TextTrackCue::setIsActive(bool active)
{
m_isActive = active;
+
+ if (!active) {
+ if (!hasDisplayTree())
+ return;
+
+ // Remove the display tree as soon as the cue becomes inactive.
+ displayTreeInternal()->remove(ASSERT_NO_EXCEPTION);
+ }
}
-bool TextTrackCue::isOrderedBefore(const TextTrackCue* other) const
+int TextTrackCue::calculateComputedLinePosition()
{
- return startMediaTime() < other->startMediaTime() || (startMediaTime() == other->startMediaTime() && endMediaTime() > other->endMediaTime());
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-computed-line-position
+
+ // If the text track cue line position is numeric, then that is the text
+ // track cue computed line position.
+ if (m_linePosition != undefinedPosition)
+ return m_linePosition;
+
+ // If the text track cue snap-to-lines flag of the text track cue is not
+ // set, the text track cue computed line position is the value 100;
+ if (!m_snapToLines)
+ return 100;
+
+ // Otherwise, it is the value returned by the following algorithm:
+
+ // If cue is not associated with a text track, return -1 and abort these
+ // steps.
+ if (!track())
+ return -1;
+
+ // Let n be the number of text tracks whose text track mode is showing or
+ // showing by default and that are in the media element's list of text
+ // tracks before track.
+ int n = track()->trackIndexRelativeToRenderedTracks();
+
+ // Increment n by one.
+ n++;
+
+ // Negate n.
+ n = -n;
+
+ return n;
}
-bool TextTrackCue::cueContentsMatch(const TextTrackCue& cue) const
+static bool isCueParagraphSeparator(UChar character)
{
- if (cueType() != cue.cueType())
- return false;
+ // Within a cue, paragraph boundaries are only denoted by Type B characters,
+ // such as U+000A LINE FEED (LF), U+0085 NEXT LINE (NEL), and U+2029 PARAGRAPH SEPARATOR.
+ return u_charType(character) == U_PARAGRAPH_SEPARATOR;
+}
- if (id() != cue.id())
- return false;
+void TextTrackCue::determineTextDirection()
+{
+ DEFINE_STATIC_LOCAL(const String, rtTag, (ASCIILiteral("rt")));
+ createWebVTTNodeTree();
+ if (!m_webVTTNodeTree)
+ return;
- return true;
+ // Apply the Unicode Bidirectional Algorithm's Paragraph Level steps to the
+ // concatenation of the values of each WebVTT Text Object in nodes, in a
+ // pre-order, depth-first traversal, excluding WebVTT Ruby Text Objects and
+ // their descendants.
+ StringBuilder paragraphBuilder;
+ for (Node* node = m_webVTTNodeTree->firstChild(); node; node = NodeTraversal::next(node, m_webVTTNodeTree.get())) {
+ // FIXME: The code does not match the comment above. This does not actually exclude Ruby Text Object descendant.
+ if (!node->isTextNode() || node->localName() == rtTag)
+ continue;
+
+ paragraphBuilder.append(node->nodeValue());
+ }
+
+ String paragraph = paragraphBuilder.toString();
+ if (!paragraph.length())
+ return;
+
+ for (size_t i = 0; i < paragraph.length(); ++i) {
+ UChar current = paragraph[i];
+ if (!current || isCueParagraphSeparator(current))
+ return;
+
+ if (UChar current = paragraph[i]) {
+ UCharDirection charDirection = u_charDirection(current);
+ if (charDirection == U_LEFT_TO_RIGHT) {
+ m_displayDirection = CSSValueLtr;
+ return;
+ }
+ if (charDirection == U_RIGHT_TO_LEFT || charDirection == U_RIGHT_TO_LEFT_ARABIC) {
+ m_displayDirection = CSSValueRtl;
+ return;
+ }
+ }
+ }
}
-bool TextTrackCue::isEqual(const TextTrackCue& cue, TextTrackCue::CueMatchRules match) const
+void TextTrackCue::calculateDisplayParameters()
{
- if (cueType() != cue.cueType())
- return false;
+ // Steps 10.2, 10.3
+ determineTextDirection();
- if (match != IgnoreDuration && endMediaTime() != cue.endMediaTime())
- return false;
- if (!hasEquivalentStartTime(cue))
- return false;
- if (!cueContentsMatch(cue))
- return false;
+ // 10.4 If the text track cue writing direction is horizontal, then let
+ // block-flow be 'tb'. Otherwise, if the text track cue writing direction is
+ // vertical growing left, then let block-flow be 'lr'. Otherwise, the text
+ // track cue writing direction is vertical growing right; let block-flow be
+ // 'rl'.
+ m_displayWritingMode = m_displayWritingModeMap[m_writingDirection];
- return true;
+ // 10.5 Determine the value of maximum size for cue as per the appropriate
+ // rules from the following list:
+ int maximumSize = m_textPosition;
+ if ((m_writingDirection == Horizontal && m_cueAlignment == Start && m_displayDirection == CSSValueLtr)
+ || (m_writingDirection == Horizontal && m_cueAlignment == End && m_displayDirection == CSSValueRtl)
+ || (m_writingDirection == VerticalGrowingLeft && m_cueAlignment == Start)
+ || (m_writingDirection == VerticalGrowingRight && m_cueAlignment == Start)) {
+ maximumSize = 100 - m_textPosition;
+ } else if ((m_writingDirection == Horizontal && m_cueAlignment == End && m_displayDirection == CSSValueLtr)
+ || (m_writingDirection == Horizontal && m_cueAlignment == Start && m_displayDirection == CSSValueRtl)
+ || (m_writingDirection == VerticalGrowingLeft && m_cueAlignment == End)
+ || (m_writingDirection == VerticalGrowingRight && m_cueAlignment == End)) {
+ maximumSize = m_textPosition;
+ } else if (m_cueAlignment == Middle) {
+ maximumSize = m_textPosition <= 50 ? m_textPosition : (100 - m_textPosition);
+ maximumSize = maximumSize * 2;
+ }
+
+ // 10.6 If the text track cue size is less than maximum size, then let size
+ // be text track cue size. Otherwise, let size be maximum size.
+ m_displaySize = std::min(m_cueSize, maximumSize);
+
+ // 10.8 Determine the value of x-position or y-position for cue as per the
+ // appropriate rules from the following list:
+ if (m_writingDirection == Horizontal) {
+ if (m_cueAlignment == Start) {
+ if (m_displayDirection == CSSValueLtr)
+ m_displayPosition.first = m_textPosition;
+ else
+ m_displayPosition.first = 100 - m_textPosition - m_displaySize;
+ } else if (m_cueAlignment == End) {
+ if (m_displayDirection == CSSValueRtl)
+ m_displayPosition.first = 100 - m_textPosition;
+ else
+ m_displayPosition.first = m_textPosition - m_displaySize;
+ }
+ }
+
+ if ((m_writingDirection == VerticalGrowingLeft && m_cueAlignment == Start)
+ || (m_writingDirection == VerticalGrowingRight && m_cueAlignment == Start)) {
+ m_displayPosition.second = m_textPosition;
+ } else if ((m_writingDirection == VerticalGrowingLeft && m_cueAlignment == End)
+ || (m_writingDirection == VerticalGrowingRight && m_cueAlignment == End)) {
+ m_displayPosition.second = 100 - m_textPosition;
+ }
+
+ if (m_writingDirection == Horizontal && m_cueAlignment == Middle) {
+ if (m_displayDirection == CSSValueLtr)
+ m_displayPosition.first = m_textPosition - m_displaySize / 2;
+ else
+ m_displayPosition.first = 100 - m_textPosition - m_displaySize / 2;
+ }
+
+ if ((m_writingDirection == VerticalGrowingLeft && m_cueAlignment == Middle)
+ || (m_writingDirection == VerticalGrowingRight && m_cueAlignment == Middle))
+ m_displayPosition.second = m_textPosition - m_displaySize / 2;
+
+ // 10.9 Determine the value of whichever of x-position or y-position is not
+ // yet calculated for cue as per the appropriate rules from the following
+ // list:
+ if (m_snapToLines && m_displayPosition.second == undefinedPosition && m_writingDirection == Horizontal)
+ m_displayPosition.second = 0;
+
+ if (!m_snapToLines && m_displayPosition.second == undefinedPosition && m_writingDirection == Horizontal)
+ m_displayPosition.second = m_computedLinePosition;
+
+ if (m_snapToLines && m_displayPosition.first == undefinedPosition
+ && (m_writingDirection == VerticalGrowingLeft || m_writingDirection == VerticalGrowingRight))
+ m_displayPosition.first = 0;
+
+ if (!m_snapToLines && (m_writingDirection == VerticalGrowingLeft || m_writingDirection == VerticalGrowingRight))
+ m_displayPosition.first = m_computedLinePosition;
+
+ // A text track cue has a text track cue computed line position whose value
+ // is defined in terms of the other aspects of the cue.
+ m_computedLinePosition = calculateComputedLinePosition();
+}
+
+void TextTrackCue::markFutureAndPastNodes(ContainerNode* root, double previousTimestamp, double movieTime)
+{
+ DEFINE_STATIC_LOCAL(const String, timestampTag, (ASCIILiteral("timestamp")));
+
+ bool isPastNode = true;
+ double currentTimestamp = previousTimestamp;
+ if (currentTimestamp > movieTime)
+ isPastNode = false;
+
+ for (Node* child = root->firstChild(); child; child = NodeTraversal::next(child, root)) {
+ if (child->nodeName() == timestampTag) {
+ unsigned position = 0;
+ String timestamp = child->nodeValue();
+ double currentTimestamp = WebVTTParser::create(0, &m_scriptExecutionContext)->collectTimeStamp(timestamp, &position);
+ ASSERT(currentTimestamp != -1);
+
+ if (currentTimestamp > movieTime)
+ isPastNode = false;
+ }
+
+ if (child->isWebVTTElement()) {
+ toWebVTTElement(child)->setIsPastNode(isPastNode);
+ // Make an elemenet id match a cue id for style matching purposes.
+ if (!m_id.isEmpty())
+ toElement(child)->setIdAttribute(m_id);
+ }
+ }
}
-bool TextTrackCue::hasEquivalentStartTime(const TextTrackCue& cue) const
+void TextTrackCue::updateDisplayTree(double movieTime)
{
- MediaTime startTimeVariance = MediaTime::zeroTime();
- if (track())
- startTimeVariance = track()->startTimeVariance();
- else if (cue.track())
- startTimeVariance = cue.track()->startTimeVariance();
+ // The display tree may contain WebVTT timestamp objects representing
+ // timestamps (processing instructions), along with displayable nodes.
+
+ if (!track()->isRendered())
+ return;
+
+ // Clear the contents of the set.
+ m_cueBackgroundBox->removeChildren();
+
+ // Update the two sets containing past and future WebVTT objects.
+ RefPtr<DocumentFragment> referenceTree = createCueRenderingTree();
+ if (!referenceTree)
+ return;
- return abs(abs(startMediaTime()) - abs(cue.startMediaTime())) <= startTimeVariance;
+ markFutureAndPastNodes(referenceTree.get(), startTime(), movieTime);
+ m_cueBackgroundBox->appendChild(referenceTree);
}
-bool TextTrackCue::doesExtendCue(const TextTrackCue& cue) const
+TextTrackCueBox* TextTrackCue::getDisplayTree(const IntSize& videoSize)
{
- if (!cueContentsMatch(cue))
- return false;
+ RefPtr<TextTrackCueBox> displayTree = displayTreeInternal();
+ if (!m_displayTreeShouldChange || !track()->isRendered())
+ return displayTree.get();
+
+ // 10.1 - 10.10
+ calculateDisplayParameters();
+
+ // 10.11. Apply the terms of the CSS specifications to nodes within the
+ // following constraints, thus obtaining a set of CSS boxes positioned
+ // relative to an initial containing block:
+ displayTree->removeChildren();
+
+ // The document tree is the tree of WebVTT Node Objects rooted at nodes.
+
+ // The children of the nodes must be wrapped in an anonymous box whose
+ // 'display' property has the value 'inline'. This is the WebVTT cue
+ // background box.
+
+ // Note: This is contained by default in m_cueBackgroundBox.
+ m_cueBackgroundBox->setPseudo(cueShadowPseudoId());
+ displayTree->appendChild(m_cueBackgroundBox, ASSERT_NO_EXCEPTION);
+
+ // FIXME(BUG 79916): Runs of children of WebVTT Ruby Objects that are not
+ // WebVTT Ruby Text Objects must be wrapped in anonymous boxes whose
+ // 'display' property has the value 'ruby-base'.
+
+ // FIXME(BUG 79916): Text runs must be wrapped according to the CSS
+ // line-wrapping rules, except that additionally, regardless of the value of
+ // the 'white-space' property, lines must be wrapped at the edge of their
+ // containing blocks, even if doing so requires splitting a word where there
+ // is no line breaking opportunity. (Thus, normally text wraps as needed,
+ // but if there is a particularly long word, it does not overflow as it
+ // normally would in CSS, it is instead forcibly wrapped at the box's edge.)
+ displayTree->applyCSSProperties(videoSize);
+
+ m_displayTreeShouldChange = false;
+
+ // 10.15. Let cue's text track cue display state have the CSS boxes in
+ // boxes.
+ return displayTree.get();
+}
+
+void TextTrackCue::removeDisplayTree()
+{
+ if (!hasDisplayTree())
+ return;
+ displayTreeInternal()->remove(ASSERT_NO_EXCEPTION);
+}
+
+std::pair<double, double> TextTrackCue::getPositionCoordinates() const
+{
+ // This method is used for setting x and y when snap to lines is not set.
+ std::pair<double, double> coordinates;
+
+ if (m_writingDirection == Horizontal && m_displayDirection == CSSValueLtr) {
+ coordinates.first = m_textPosition;
+ coordinates.second = m_computedLinePosition;
+
+ return coordinates;
+ }
+
+ if (m_writingDirection == Horizontal && m_displayDirection == CSSValueRtl) {
+ coordinates.first = 100 - m_textPosition;
+ coordinates.second = m_computedLinePosition;
+
+ return coordinates;
+ }
+
+ if (m_writingDirection == VerticalGrowingLeft) {
+ coordinates.first = 100 - m_computedLinePosition;
+ coordinates.second = m_textPosition;
+
+ return coordinates;
+ }
+
+ if (m_writingDirection == VerticalGrowingRight) {
+ coordinates.first = m_computedLinePosition;
+ coordinates.second = m_textPosition;
+
+ return coordinates;
+ }
- if (endMediaTime() != cue.startMediaTime())
+ ASSERT_NOT_REACHED();
+
+ return coordinates;
+}
+
+TextTrackCue::CueSetting TextTrackCue::settingName(const String& name)
+{
+ DEFINE_STATIC_LOCAL(const String, verticalKeyword, (ASCIILiteral("vertical")));
+ DEFINE_STATIC_LOCAL(const String, lineKeyword, (ASCIILiteral("line")));
+ DEFINE_STATIC_LOCAL(const String, positionKeyword, (ASCIILiteral("position")));
+ DEFINE_STATIC_LOCAL(const String, sizeKeyword, (ASCIILiteral("size")));
+ DEFINE_STATIC_LOCAL(const String, alignKeyword, (ASCIILiteral("align")));
+#if ENABLE(WEBVTT_REGIONS)
+ DEFINE_STATIC_LOCAL(const String, regionIdKeyword, (ASCIILiteral("region")));
+#endif
+
+ if (name == verticalKeyword)
+ return Vertical;
+ else if (name == lineKeyword)
+ return Line;
+ else if (name == positionKeyword)
+ return Position;
+ else if (name == sizeKeyword)
+ return Size;
+ else if (name == alignKeyword)
+ return Align;
+#if ENABLE(WEBVTT_REGIONS)
+ else if (name == regionIdKeyword)
+ return RegionId;
+#endif
+
+ return None;
+}
+
+void TextTrackCue::setCueSettings(const String& input)
+{
+ m_settings = input;
+ unsigned position = 0;
+
+ while (position < input.length()) {
+
+ // The WebVTT cue settings part of a WebVTT cue consists of zero or more of the following components, in any order,
+ // separated from each other by one or more U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters.
+ while (position < input.length() && WebVTTParser::isValidSettingDelimiter(input[position]))
+ position++;
+ if (position >= input.length())
+ break;
+
+ // When the user agent is to parse the WebVTT settings given by a string input for a text track cue cue,
+ // the user agent must run the following steps:
+ // 1. Let settings be the result of splitting input on spaces.
+ // 2. For each token setting in the list settings, run the following substeps:
+ // 1. If setting does not contain a U+003A COLON character (:), or if the first U+003A COLON character (:)
+ // in setting is either the first or last character of setting, then jump to the step labeled next setting.
+ unsigned endOfSetting = position;
+ String setting = WebVTTParser::collectWord(input, &endOfSetting);
+ CueSetting name;
+ size_t colonOffset = setting.find(':', 1);
+ if (colonOffset == notFound || colonOffset == 0 || colonOffset == setting.length() - 1)
+ goto NextSetting;
+
+ // 2. Let name be the leading substring of setting up to and excluding the first U+003A COLON character (:) in that string.
+ name = settingName(setting.substring(0, colonOffset));
+
+ // 3. Let value be the trailing substring of setting starting from the character immediately after the first U+003A COLON character (:) in that string.
+ position += colonOffset + 1;
+ if (position >= input.length())
+ break;
+
+ // 4. Run the appropriate substeps that apply for the value of name, as follows:
+ switch (name) {
+ case Vertical:
+ {
+ // If name is a case-sensitive match for "vertical"
+ // 1. If value is a case-sensitive match for the string "rl", then let cue's text track cue writing direction
+ // be vertical growing left.
+ String writingDirection = WebVTTParser::collectWord(input, &position);
+ if (writingDirection == verticalGrowingLeftKeyword())
+ m_writingDirection = VerticalGrowingLeft;
+
+ // 2. Otherwise, if value is a case-sensitive match for the string "lr", then let cue's text track cue writing
+ // direction be vertical growing right.
+ else if (writingDirection == verticalGrowingRightKeyword())
+ m_writingDirection = VerticalGrowingRight;
+ }
+ break;
+ case Line:
+ {
+ // 1-2 - Collect chars that are either '-', '%', or a digit.
+ // 1. If value contains any characters other than U+002D HYPHEN-MINUS characters (-), U+0025 PERCENT SIGN
+ // characters (%), and characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump
+ // to the step labeled next setting.
+ StringBuilder linePositionBuilder;
+ while (position < input.length() && (input[position] == '-' || input[position] == '%' || isASCIIDigit(input[position])))
+ linePositionBuilder.append(input[position++]);
+ if (position < input.length() && !WebVTTParser::isValidSettingDelimiter(input[position]))
+ break;
+
+ // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT
+ // NINE (9), then jump to the step labeled next setting.
+ // 3. If any character in value other than the first character is a U+002D HYPHEN-MINUS character (-), then
+ // jump to the step labeled next setting.
+ // 4. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%), then
+ // jump to the step labeled next setting.
+ String linePosition = linePositionBuilder.toString();
+ if (linePosition.find('-', 1) != notFound || linePosition.reverseFind("%", linePosition.length() - 2) != notFound)
+ break;
+
+ // 5. If the first character in value is a U+002D HYPHEN-MINUS character (-) and the last character in value is a
+ // U+0025 PERCENT SIGN character (%), then jump to the step labeled next setting.
+ if (linePosition[0] == '-' && linePosition[linePosition.length() - 1] == '%')
+ break;
+
+ // 6. Ignoring the trailing percent sign, if any, interpret value as a (potentially signed) integer, and
+ // let number be that number.
+ // NOTE: toInt ignores trailing non-digit characters, such as '%'.
+ bool validNumber;
+ int number = linePosition.toInt(&validNumber);
+ if (!validNumber)
+ break;
+
+ // 7. If the last character in value is a U+0025 PERCENT SIGN character (%), but number is not in the range
+ // 0 ≤ number ≤ 100, then jump to the step labeled next setting.
+ // 8. Let cue's text track cue line position be number.
+ // 9. If the last character in value is a U+0025 PERCENT SIGN character (%), then let cue's text track cue
+ // snap-to-lines flag be false. Otherwise, let it be true.
+ if (linePosition[linePosition.length() - 1] == '%') {
+ if (number < 0 || number > 100)
+ break;
+
+ // 10 - If '%' then set snap-to-lines flag to false.
+ m_snapToLines = false;
+ }
+
+ m_linePosition = number;
+ }
+ break;
+ case Position:
+ {
+ // 1. If value contains any characters other than U+0025 PERCENT SIGN characters (%) and characters in the range
+ // U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step labeled next setting.
+ // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9),
+ // then jump to the step labeled next setting.
+ String textPosition = WebVTTParser::collectDigits(input, &position);
+ if (textPosition.isEmpty())
+ break;
+ if (position >= input.length())
+ break;
+
+ // 3. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%), then jump
+ // to the step labeled next setting.
+ // 4. If the last character in value is not a U+0025 PERCENT SIGN character (%), then jump to the step labeled
+ // next setting.
+ if (input[position++] != '%')
+ break;
+ if (position < input.length() && !WebVTTParser::isValidSettingDelimiter(input[position]))
+ break;
+
+ // 5. Ignoring the trailing percent sign, interpret value as an integer, and let number be that number.
+ // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step labeled next setting.
+ // NOTE: toInt ignores trailing non-digit characters, such as '%'.
+ bool validNumber;
+ int number = textPosition.toInt(&validNumber);
+ if (!validNumber)
+ break;
+ if (number < 0 || number > 100)
+ break;
+
+ // 7. Let cue's text track cue text position be number.
+ m_textPosition = number;
+ }
+ break;
+ case Size:
+ {
+ // 1. If value contains any characters other than U+0025 PERCENT SIGN characters (%) and characters in the
+ // range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step labeled next setting.
+ // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT
+ // NINE (9), then jump to the step labeled next setting.
+ String cueSize = WebVTTParser::collectDigits(input, &position);
+ if (cueSize.isEmpty())
+ break;
+ if (position >= input.length())
+ break;
+
+ // 3. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%),
+ // then jump to the step labeled next setting.
+ // 4. If the last character in value is not a U+0025 PERCENT SIGN character (%), then jump to the step
+ // labeled next setting.
+ if (input[position++] != '%')
+ break;
+ if (position < input.length() && !WebVTTParser::isValidSettingDelimiter(input[position]))
+ break;
+
+ // 5. Ignoring the trailing percent sign, interpret value as an integer, and let number be that number.
+ // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step labeled next setting.
+ bool validNumber;
+ int number = cueSize.toInt(&validNumber);
+ if (!validNumber)
+ break;
+ if (number < 0 || number > 100)
+ break;
+
+ // 7. Let cue's text track cue size be number.
+ m_cueSize = number;
+ }
+ break;
+ case Align:
+ {
+ String cueAlignment = WebVTTParser::collectWord(input, &position);
+
+ // 1. If value is a case-sensitive match for the string "start", then let cue's text track cue alignment be start alignment.
+ if (cueAlignment == startKeyword())
+ m_cueAlignment = Start;
+
+ // 2. If value is a case-sensitive match for the string "middle", then let cue's text track cue alignment be middle alignment.
+ else if (cueAlignment == middleKeyword())
+ m_cueAlignment = Middle;
+
+ // 3. If value is a case-sensitive match for the string "end", then let cue's text track cue alignment be end alignment.
+ else if (cueAlignment == endKeyword())
+ m_cueAlignment = End;
+ }
+ break;
+#if ENABLE(WEBVTT_REGIONS)
+ case RegionId:
+ m_regionId = WebVTTParser::collectWord(input, &position);
+ break;
+#endif
+ case None:
+ break;
+ }
+
+NextSetting:
+ position = endOfSetting;
+ }
+#if ENABLE(WEBVTT_REGIONS)
+ // If cue's line position is not auto or cue's size is not 100 or cue's
+ // writing direction is not horizontal, but cue's region identifier is not
+ // the empty string, let cue's region identifier be the empty string.
+ if (m_regionId.isEmpty())
+ return;
+
+ if (m_linePosition != undefinedPosition || m_cueSize != 100 || m_writingDirection != Horizontal)
+ m_regionId = emptyString();
+#endif
+}
+
+CSSValueID TextTrackCue::getCSSWritingDirection() const
+{
+ return m_displayDirection;
+}
+
+CSSValueID TextTrackCue::getCSSWritingMode() const
+{
+ return m_displayWritingMode;
+}
+
+int TextTrackCue::getCSSSize() const
+{
+ return m_displaySize;
+}
+
+std::pair<double, double> TextTrackCue::getCSSPosition() const
+{
+ if (!m_snapToLines)
+ return getPositionCoordinates();
+
+ return m_displayPosition;
+}
+
+bool TextTrackCue::isEqual(const TextTrackCue& cue, CueMatchRules match) const
+{
+ if (cueType() != cue.cueType())
+ return false;
+
+ if (match != IgnoreDuration && m_endTime != cue.endTime())
+ return false;
+ if (m_startTime != cue.startTime())
+ return false;
+ if (m_content != cue.text())
+ return false;
+ if (m_settings != cue.cueSettings())
+ return false;
+ if (m_id != cue.id())
+ return false;
+ if (m_textPosition != cue.position())
+ return false;
+ if (m_linePosition != cue.line())
+ return false;
+ if (m_cueSize != cue.size())
+ return false;
+ if (align() != cue.align())
return false;
return true;
}
+bool TextTrackCue::isOrderedBefore(const TextTrackCue* other) const
+{
+ return startTime() < other->startTime() || (startTime() == other->startTime() && endTime() > other->endTime());
+}
+
+void TextTrackCue::setFontSize(int fontSize, const IntSize&, bool important)
+{
+ if (!hasDisplayTree() || !fontSize)
+ return;
+
+ LOG(Media, "TextTrackCue::setFontSize - setting cue font size to %i", fontSize);
+
+ displayTreeInternal()->setInlineStyleProperty(CSSPropertyFontSize, fontSize, CSSPrimitiveValue::CSS_PX, important);
+}
+
} // namespace WebCore
#endif
diff --git a/Source/WebCore/html/track/TextTrackCue.h b/Source/WebCore/html/track/TextTrackCue.h
index ec2ab22e2..5d3cf4e9c 100644
--- a/Source/WebCore/html/track/TextTrackCue.h
+++ b/Source/WebCore/html/track/TextTrackCue.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -36,21 +36,51 @@
#include "EventTarget.h"
#include "HTMLElement.h"
-#include <wtf/MediaTime.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
+class DocumentFragment;
+class HTMLSpanElement;
+class ScriptExecutionContext;
class TextTrack;
+class TextTrackCue;
+
+// ----------------------------
+
+class TextTrackCueBox : public HTMLElement {
+public:
+ static PassRefPtr<TextTrackCueBox> create(Document& document, TextTrackCue* cue)
+ {
+ return adoptRef(new TextTrackCueBox(document, cue));
+ }
+
+ TextTrackCue* getCue() const;
+ virtual void applyCSSProperties(const IntSize& videoSize);
+
+ static const AtomicString& textTrackCueBoxShadowPseudoId();
+
+protected:
+ TextTrackCueBox(Document&, TextTrackCue*);
+
+ virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
+
+ TextTrackCue* m_cue;
+};
+
+// ----------------------------
class TextTrackCue : public RefCounted<TextTrackCue>, public EventTargetWithInlineData {
public:
- static PassRefPtr<TextTrackCue> create(ScriptExecutionContext&, double start, double end, const String& content);
- static PassRefPtr<TextTrackCue> create(ScriptExecutionContext&, const MediaTime& start, const MediaTime& end, const String& content);
+ static PassRefPtr<TextTrackCue> create(ScriptExecutionContext& context, double start, double end, const String& content)
+ {
+ return adoptRef(new TextTrackCue(context, start, end, content));
+ }
static const AtomicString& cueShadowPseudoId()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, cue, ("cue", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, cue, ("cue", AtomicString::ConstructFromLiteral));
return cue;
}
@@ -62,80 +92,190 @@ public:
const String& id() const { return m_id; }
void setId(const String&);
- MediaTime startMediaTime() const { return m_startTime; }
- double startTime() const { return startMediaTime().toDouble(); }
- void setStartTime(const MediaTime&);
+ double startTime() const { return m_startTime; }
void setStartTime(double, ExceptionCode&);
- MediaTime endMediaTime() const { return m_endTime; }
- double endTime() const { return endMediaTime().toDouble(); }
- void setEndTime(const MediaTime&);
+ double endTime() const { return m_endTime; }
void setEndTime(double, ExceptionCode&);
bool pauseOnExit() const { return m_pauseOnExit; }
void setPauseOnExit(bool);
+ const String& vertical() const;
+ void setVertical(const String&, ExceptionCode&);
+
+ bool snapToLines() const { return m_snapToLines; }
+ void setSnapToLines(bool);
+
+ int line() const { return m_linePosition; }
+ virtual void setLine(int, ExceptionCode&);
+
+ int position() const { return m_textPosition; }
+ virtual void setPosition(int, ExceptionCode&);
+
+ int size() const { return m_cueSize; }
+ virtual void setSize(int, ExceptionCode&);
+
+ const String& align() const;
+ void setAlign(const String&, ExceptionCode&);
+
+ const String& text() const { return m_content; }
+ void setText(const String&);
+
+ const String& cueSettings() const { return m_settings; }
+ void setCueSettings(const String&);
+
int cueIndex();
void invalidateCueIndex();
+ PassRefPtr<DocumentFragment> getCueAsHTML();
+ PassRefPtr<DocumentFragment> createCueRenderingTree();
+
using EventTarget::dispatchEvent;
virtual bool dispatchEvent(PassRefPtr<Event>) override;
+#if ENABLE(WEBVTT_REGIONS)
+ const String& regionId() const { return m_regionId; }
+ void setRegionId(const String&);
+#endif
+
bool isActive();
- virtual void setIsActive(bool);
+ void setIsActive(bool);
+
+ bool hasDisplayTree() const { return m_displayTree; }
+ TextTrackCueBox* getDisplayTree(const IntSize& videoSize);
+ HTMLSpanElement* element() const { return m_cueBackgroundBox.get(); }
+
+ void updateDisplayTree(double);
+ void removeDisplayTree();
+ void markFutureAndPastNodes(ContainerNode*, double, double);
+
+ int calculateComputedLinePosition();
+ std::pair<double, double> getPositionCoordinates() const;
virtual EventTargetInterface eventTargetInterface() const override final { return TextTrackCueEventTargetInterfaceType; }
virtual ScriptExecutionContext* scriptExecutionContext() const override final { return &m_scriptExecutionContext; }
- virtual bool isOrderedBefore(const TextTrackCue*) const;
- virtual bool isPositionedAbove(const TextTrackCue* cue) const { return isOrderedBefore(cue); }
+ std::pair<double, double> getCSSPosition() const;
- bool hasEquivalentStartTime(const TextTrackCue&) const;
+ int getCSSSize() const;
+ CSSValueID getCSSWritingDirection() const;
+ CSSValueID getCSSWritingMode() const;
- enum CueType {
- Data,
- Generic,
- WebVTT
+ enum WritingDirection {
+ Horizontal,
+ VerticalGrowingLeft,
+ VerticalGrowingRight,
+ NumberOfWritingDirections
};
- virtual CueType cueType() const = 0;
- virtual bool isRenderable() const { return false; }
+ WritingDirection getWritingDirection() const { return m_writingDirection; }
+
+ enum CueAlignment {
+ Start,
+ Middle,
+ End
+ };
+ CueAlignment getAlignment() const { return m_cueAlignment; }
+
+ virtual void setFontSize(int, const IntSize&, bool important);
enum CueMatchRules {
MatchAllFields,
IgnoreDuration,
};
virtual bool isEqual(const TextTrackCue&, CueMatchRules) const;
- virtual bool cueContentsMatch(const TextTrackCue&) const;
- virtual bool doesExtendCue(const TextTrackCue&) const;
+
+ virtual bool isOrderedBefore(const TextTrackCue*) const;
+
+ enum CueType {
+ Generic,
+ WebVTT
+ };
+ virtual CueType cueType() const { return WebVTT; }
void willChange();
- virtual void didChange();
+ void didChange();
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(enter);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(exit);
using RefCounted<TextTrackCue>::ref;
using RefCounted<TextTrackCue>::deref;
protected:
- TextTrackCue(ScriptExecutionContext&, const MediaTime& start, const MediaTime& end);
+ TextTrackCue(ScriptExecutionContext&, double start, double end, const String& content);
+
+ Document& ownerDocument() { return toDocument(m_scriptExecutionContext); }
- Document& ownerDocument() { return downcast<Document>(m_scriptExecutionContext); }
+ virtual PassRefPtr<TextTrackCueBox> createDisplayTree();
+ TextTrackCueBox* displayTreeInternal();
private:
+ void createWebVTTNodeTree();
+ void copyWebVTTNodeToDOMTree(ContainerNode* WebVTTNode, ContainerNode* root);
+
+ void parseSettings(const String&);
+
+ void determineTextDirection();
+ void calculateDisplayParameters();
virtual void refEventTarget() override final { ref(); }
virtual void derefEventTarget() override final { deref(); }
+ enum CueSetting {
+ None,
+ Vertical,
+ Line,
+ Position,
+ Size,
+ Align,
+#if ENABLE(WEBVTT_REGIONS)
+ RegionId
+#endif
+ };
+ CueSetting settingName(const String&);
+
String m_id;
- MediaTime m_startTime;
- MediaTime m_endTime;
+ double m_startTime;
+ double m_endTime;
+ String m_content;
+ String m_settings;
+ int m_linePosition;
+ int m_computedLinePosition;
+ int m_textPosition;
+ int m_cueSize;
int m_cueIndex;
int m_processingCueChanges;
+ WritingDirection m_writingDirection;
+
+ CueAlignment m_cueAlignment;
+
+ RefPtr<DocumentFragment> m_webVTTNodeTree;
TextTrack* m_track;
ScriptExecutionContext& m_scriptExecutionContext;
- bool m_isActive : 1;
- bool m_pauseOnExit : 1;
+ bool m_isActive;
+ bool m_pauseOnExit;
+ bool m_snapToLines;
+
+ RefPtr<HTMLSpanElement> m_cueBackgroundBox;
+
+ bool m_displayTreeShouldChange;
+ RefPtr<TextTrackCueBox> m_displayTree;
+
+ CSSValueID m_displayDirection;
+
+ CSSValueID m_displayWritingModeMap[NumberOfWritingDirections];
+ CSSValueID m_displayWritingMode;
+
+ int m_displaySize;
+
+ std::pair<float, float> m_displayPosition;
+#if ENABLE(WEBVTT_REGIONS)
+ String m_regionId;
+#endif
};
} // namespace WebCore
diff --git a/Source/WebCore/html/track/TextTrackCue.idl b/Source/WebCore/html/track/TextTrackCue.idl
index b772bb66d..e860b9765 100644
--- a/Source/WebCore/html/track/TextTrackCue.idl
+++ b/Source/WebCore/html/track/TextTrackCue.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,27 +26,44 @@
[
Conditional=VIDEO_TRACK,
JSGenerateToNativeObject,
- Constructor(unrestricted double startTime, unrestricted double endTime, DOMString text),
+ Constructor(double startTime, double endTime, DOMString text),
ConstructorCallWith=ScriptExecutionContext,
EventTarget,
JSCustomMarkFunction,
CustomIsReachable,
- CustomToJSObject,
SkipVTableValidation,
] interface TextTrackCue {
readonly attribute TextTrack track;
attribute DOMString id;
- [SetterRaisesException] attribute unrestricted double startTime;
- [SetterRaisesException] attribute unrestricted double endTime;
+ [SetterRaisesException] attribute double startTime;
+ [SetterRaisesException] attribute double endTime;
attribute boolean pauseOnExit;
- attribute EventHandler onenter;
- attribute EventHandler onexit;
+ [SetterRaisesException] attribute DOMString vertical;
+ attribute boolean snapToLines;
+ [SetterRaisesException] attribute long line;
+ [SetterRaisesException] attribute long position;
+ [SetterRaisesException] attribute long size;
+ [SetterRaisesException] attribute DOMString align;
+
+ attribute DOMString text;
+ DocumentFragment getCueAsHTML();
+
+ attribute EventListener onenter;
+ attribute EventListener onexit;
// EventTarget interface
- void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
- void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
- [RaisesException] boolean dispatchEvent(Event event);
+ void addEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ void removeEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ [RaisesException] boolean dispatchEvent(Event evt);
+
+#if defined(ENABLE_WEBVTT_REGIONS) && ENABLE_WEBVTT_REGIONS
+ attribute DOMString regionId;
+#endif
};
diff --git a/Source/WebCore/html/track/TextTrackCueGeneric.cpp b/Source/WebCore/html/track/TextTrackCueGeneric.cpp
index 1c2d76699..a3344dcbc 100644
--- a/Source/WebCore/html/track/TextTrackCueGeneric.cpp
+++ b/Source/WebCore/html/track/TextTrackCueGeneric.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -30,7 +30,6 @@
#include "TextTrackCueGeneric.h"
#include "CSSPropertyNames.h"
-#include "CSSStyleDeclaration.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
#include "HTMLSpanElement.h"
@@ -38,30 +37,25 @@
#include "Logging.h"
#include "RenderObject.h"
#include "ScriptExecutionContext.h"
-#include "StyleProperties.h"
#include "TextTrackCue.h"
-#include <wtf/MathExtras.h>
namespace WebCore {
-// This default value must be the same as the one specified in mediaControlsApple.css for -webkit-media-controls-closed-captions-container
-const static int DEFAULTCAPTIONFONTSIZE = 10;
-
-class TextTrackCueGenericBoxElement final : public VTTCueBox {
+class TextTrackCueGenericBoxElement final : public TextTrackCueBox {
public:
- static Ref<TextTrackCueGenericBoxElement> create(Document& document, TextTrackCueGeneric& cue)
+ static PassRefPtr<TextTrackCueGenericBoxElement> create(Document& document, TextTrackCueGeneric* cue)
{
- return adoptRef(*new TextTrackCueGenericBoxElement(document, cue));
+ return adoptRef(new TextTrackCueGenericBoxElement(document, cue));
}
virtual void applyCSSProperties(const IntSize&) override;
private:
- TextTrackCueGenericBoxElement(Document&, VTTCue&);
+ TextTrackCueGenericBoxElement(Document&, TextTrackCue*);
};
-TextTrackCueGenericBoxElement::TextTrackCueGenericBoxElement(Document& document, VTTCue& cue)
- : VTTCueBox(document, cue)
+TextTrackCueGenericBoxElement::TextTrackCueGenericBoxElement(Document& document, TextTrackCue* cue)
+ : TextTrackCueBox(document, cue)
{
}
@@ -73,7 +67,6 @@ void TextTrackCueGenericBoxElement::applyCSSProperties(const IntSize& videoSize)
TextTrackCueGeneric* cue = static_cast<TextTrackCueGeneric*>(getCue());
RefPtr<HTMLSpanElement> cueElement = cue->element();
- CSSValueID alignment = cue->getCSSAlignment();
float size = static_cast<float>(cue->getCSSSize());
if (cue->useDefaultPosition()) {
setInlineStyleProperty(CSSPropertyBottom, 0, CSSPrimitiveValue::CSS_PX);
@@ -82,40 +75,10 @@ void TextTrackCueGenericBoxElement::applyCSSProperties(const IntSize& videoSize)
setInlineStyleProperty(CSSPropertyLeft, static_cast<float>(cue->position()), CSSPrimitiveValue::CSS_PERCENTAGE);
setInlineStyleProperty(CSSPropertyTop, static_cast<float>(cue->line()), CSSPrimitiveValue::CSS_PERCENTAGE);
- double authorFontSize = videoSize.height() * cue->baseFontSizeRelativeToVideoHeight() / 100.0;
- if (!authorFontSize)
- authorFontSize = DEFAULTCAPTIONFONTSIZE;
-
- if (cue->fontSizeMultiplier())
- authorFontSize *= cue->fontSizeMultiplier() / 100;
-
- double multiplier = m_fontSizeFromCaptionUserPrefs / authorFontSize;
- double newCueSize = std::min(size * multiplier, 100.0);
- if (cue->getWritingDirection() == VTTCue::Horizontal) {
- setInlineStyleProperty(CSSPropertyWidth, newCueSize, CSSPrimitiveValue::CSS_PERCENTAGE);
- if ((alignment == CSSValueMiddle || alignment == CSSValueCenter) && multiplier != 1.0)
- setInlineStyleProperty(CSSPropertyLeft, static_cast<double>(cue->position() - (newCueSize - m_cue.getCSSSize()) / 2), CSSPrimitiveValue::CSS_PERCENTAGE);
- } else {
- setInlineStyleProperty(CSSPropertyHeight, newCueSize, CSSPrimitiveValue::CSS_PERCENTAGE);
- if ((alignment == CSSValueMiddle || alignment == CSSValueCenter) && multiplier != 1.0)
- setInlineStyleProperty(CSSPropertyTop, static_cast<double>(cue->line() - (newCueSize - m_cue.getCSSSize()) / 2), CSSPrimitiveValue::CSS_PERCENTAGE);
- }
- }
-
- double textPosition = m_cue.position();
- double maxSize = 100.0;
-
- if (alignment == CSSValueEnd || alignment == CSSValueRight)
- maxSize = textPosition;
- else if (alignment == CSSValueStart || alignment == CSSValueLeft)
- maxSize = 100.0 - textPosition;
-
- if (cue->getWritingDirection() == VTTCue::Horizontal) {
- setInlineStyleProperty(CSSPropertyMinWidth, "-webkit-min-content");
- setInlineStyleProperty(CSSPropertyMaxWidth, maxSize, CSSPrimitiveValue::CSS_PERCENTAGE);
- } else {
- setInlineStyleProperty(CSSPropertyMinHeight, "-webkit-min-content");
- setInlineStyleProperty(CSSPropertyMaxHeight, maxSize, CSSPrimitiveValue::CSS_PERCENTAGE);
+ if (cue->getWritingDirection() == TextTrackCue::Horizontal)
+ setInlineStyleProperty(CSSPropertyWidth, size, CSSPrimitiveValue::CSS_PERCENTAGE);
+ else
+ setInlineStyleProperty(CSSPropertyHeight, size, CSSPrimitiveValue::CSS_PERCENTAGE);
}
if (cue->foregroundColor().isValid())
@@ -123,7 +86,7 @@ void TextTrackCueGenericBoxElement::applyCSSProperties(const IntSize& videoSize)
if (cue->highlightColor().isValid())
cueElement->setInlineStyleProperty(CSSPropertyBackgroundColor, cue->highlightColor().serialized());
- if (cue->getWritingDirection() == VTTCue::Horizontal)
+ if (cue->getWritingDirection() == TextTrackCue::Horizontal)
setInlineStyleProperty(CSSPropertyHeight, CSSValueAuto);
else
setInlineStyleProperty(CSSPropertyWidth, CSSValueAuto);
@@ -131,9 +94,9 @@ void TextTrackCueGenericBoxElement::applyCSSProperties(const IntSize& videoSize)
if (cue->baseFontSizeRelativeToVideoHeight())
cue->setFontSize(cue->baseFontSizeRelativeToVideoHeight(), videoSize, false);
- if (cue->getAlignment() == VTTCue::Middle)
+ if (cue->getAlignment() == TextTrackCue::Middle)
setInlineStyleProperty(CSSPropertyTextAlign, CSSValueCenter);
- else if (cue->getAlignment() == VTTCue::End)
+ else if (cue->getAlignment() == TextTrackCue::End)
setInlineStyleProperty(CSSPropertyTextAlign, CSSValueEnd);
else
setInlineStyleProperty(CSSPropertyTextAlign, CSSValueStart);
@@ -142,31 +105,32 @@ void TextTrackCueGenericBoxElement::applyCSSProperties(const IntSize& videoSize)
setInlineStyleProperty(CSSPropertyBackgroundColor, cue->backgroundColor().serialized());
setInlineStyleProperty(CSSPropertyWebkitWritingMode, cue->getCSSWritingMode(), false);
setInlineStyleProperty(CSSPropertyWhiteSpace, CSSValuePreWrap);
+ setInlineStyleProperty(CSSPropertyWordBreak, CSSValueNormal);
}
-TextTrackCueGeneric::TextTrackCueGeneric(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, const String& content)
- : VTTCue(context, start, end, content)
+TextTrackCueGeneric::TextTrackCueGeneric(ScriptExecutionContext& context, double start, double end, const String& content)
+ : TextTrackCue(context, start, end, content)
, m_baseFontSizeRelativeToVideoHeight(0)
, m_fontSizeMultiplier(0)
, m_defaultPosition(true)
{
}
-PassRefPtr<VTTCueBox> TextTrackCueGeneric::createDisplayTree()
+PassRefPtr<TextTrackCueBox> TextTrackCueGeneric::createDisplayTree()
{
- return TextTrackCueGenericBoxElement::create(ownerDocument(), *this);
+ return TextTrackCueGenericBoxElement::create(ownerDocument(), this);
}
-void TextTrackCueGeneric::setLine(double line, ExceptionCode& ec)
+void TextTrackCueGeneric::setLine(int line, ExceptionCode& ec)
{
m_defaultPosition = false;
- VTTCue::setLine(line, ec);
+ TextTrackCue::setLine(line, ec);
}
-void TextTrackCueGeneric::setPosition(double position, ExceptionCode& ec)
+void TextTrackCueGeneric::setPosition(int position, ExceptionCode& ec)
{
m_defaultPosition = false;
- VTTCue::setPosition(position, ec);
+ TextTrackCue::setPosition(position, ec);
}
void TextTrackCueGeneric::setFontSize(int fontSize, const IntSize& videoSize, bool important)
@@ -175,7 +139,7 @@ void TextTrackCueGeneric::setFontSize(int fontSize, const IntSize& videoSize, bo
return;
if (important || !baseFontSizeRelativeToVideoHeight()) {
- VTTCue::setFontSize(fontSize, videoSize, important);
+ TextTrackCue::setFontSize(fontSize, videoSize, important);
return;
}
@@ -186,14 +150,12 @@ void TextTrackCueGeneric::setFontSize(int fontSize, const IntSize& videoSize, bo
LOG(Media, "TextTrackCueGeneric::setFontSize - setting cue font size to %li", lround(size));
}
-
-bool TextTrackCueGeneric::cueContentsMatch(const TextTrackCue& cue) const
+
+bool TextTrackCueGeneric::isEqual(const TextTrackCue& cue, TextTrackCue::CueMatchRules match) const
{
- // Do call the parent class cueContentsMatch here, because we want to confirm
- // the content of the two cues are identical (even though the types are not the same).
- if (!VTTCue::cueContentsMatch(cue))
+ if (cue.cueType() != TextTrackCue::Generic)
return false;
-
+
const TextTrackCueGeneric* other = static_cast<const TextTrackCueGeneric*>(&cue);
if (m_baseFontSizeRelativeToVideoHeight != other->baseFontSizeRelativeToVideoHeight())
@@ -207,60 +169,23 @@ bool TextTrackCueGeneric::cueContentsMatch(const TextTrackCue& cue) const
if (m_backgroundColor != other->backgroundColor())
return false;
- return true;
-}
-
-bool TextTrackCueGeneric::isEqual(const TextTrackCue& cue, TextTrackCue::CueMatchRules match) const
-{
- // Do not call the parent class isEqual here, because we are not cueType() == VTTCue,
- // and will fail that equality test.
- if (!TextTrackCue::isEqual(cue, match))
- return false;
-
- if (cue.cueType() != TextTrackCue::Generic)
- return false;
-
- return cueContentsMatch(cue);
-}
-
-
-bool TextTrackCueGeneric::doesExtendCue(const TextTrackCue& cue) const
-{
- if (!cueContentsMatch(cue))
- return false;
-
- return VTTCue::doesExtendCue(cue);
+ return TextTrackCue::isEqual(cue, match);
}
bool TextTrackCueGeneric::isOrderedBefore(const TextTrackCue* that) const
{
- if (VTTCue::isOrderedBefore(that))
+ if (TextTrackCue::isOrderedBefore(that))
return true;
if (that->cueType() == Generic && startTime() == that->startTime() && endTime() == that->endTime()) {
// Further order generic cues by their calculated line value.
std::pair<double, double> thisPosition = getPositionCoordinates();
- std::pair<double, double> thatPosition = toVTTCue(that)->getPositionCoordinates();
+ std::pair<double, double> thatPosition = that->getPositionCoordinates();
return thisPosition.second > thatPosition.second || (thisPosition.second == thatPosition.second && thisPosition.first < thatPosition.first);
}
return false;
}
-
-bool TextTrackCueGeneric::isPositionedAbove(const TextTrackCue* that) const
-{
- if (that->cueType() == Generic && startTime() == that->startTime() && endTime() == that->endTime()) {
- // Further order generic cues by their calculated line value.
- std::pair<double, double> thisPosition = getPositionCoordinates();
- std::pair<double, double> thatPosition = toVTTCue(that)->getPositionCoordinates();
- return thisPosition.second > thatPosition.second || (thisPosition.second == thatPosition.second && thisPosition.first < thatPosition.first);
- }
-
- if (that->cueType() == Generic)
- return startTime() > that->startTime();
-
- return VTTCue::isOrderedBefore(that);
-}
} // namespace WebCore
diff --git a/Source/WebCore/html/track/TextTrackCueGeneric.h b/Source/WebCore/html/track/TextTrackCueGeneric.h
index 334c47e47..37d908013 100644
--- a/Source/WebCore/html/track/TextTrackCueGeneric.h
+++ b/Source/WebCore/html/track/TextTrackCueGeneric.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -29,26 +29,26 @@
#if ENABLE(VIDEO_TRACK)
#include "Color.h"
-#include "VTTCue.h"
+#include "TextTrackCue.h"
namespace WebCore {
class GenericCueData;
// A "generic" cue is a non-WebVTT cue, so it is not positioned/sized with the WebVTT logic.
-class TextTrackCueGeneric final : public VTTCue {
+class TextTrackCueGeneric final : public TextTrackCue {
public:
- static Ref<TextTrackCueGeneric> create(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, const String& content)
+ static PassRefPtr<TextTrackCueGeneric> create(ScriptExecutionContext& context, double start, double end, const String& content)
{
- return adoptRef(*new TextTrackCueGeneric(context, start, end, content));
+ return adoptRef(new TextTrackCueGeneric(context, start, end, content));
}
virtual ~TextTrackCueGeneric() { }
- virtual PassRefPtr<VTTCueBox> createDisplayTree() override;
+ virtual PassRefPtr<TextTrackCueBox> createDisplayTree() override;
- virtual void setLine(double, ExceptionCode&) override;
- virtual void setPosition(double, ExceptionCode&) override;
+ virtual void setLine(int, ExceptionCode&) override;
+ virtual void setPosition(int, ExceptionCode&) override;
bool useDefaultPosition() const { return m_defaultPosition; }
@@ -73,16 +73,13 @@ public:
virtual void setFontSize(int, const IntSize&, bool important) override;
virtual bool isEqual(const TextTrackCue&, CueMatchRules) const override;
- virtual bool cueContentsMatch(const TextTrackCue&) const override;
- virtual bool doesExtendCue(const TextTrackCue&) const override;
virtual TextTrackCue::CueType cueType() const override { return TextTrackCue::Generic; }
private:
virtual bool isOrderedBefore(const TextTrackCue*) const override;
- virtual bool isPositionedAbove(const TextTrackCue*) const override;
- TextTrackCueGeneric(ScriptExecutionContext&, const MediaTime& start, const MediaTime& end, const String&);
+ TextTrackCueGeneric(ScriptExecutionContext&, double start, double end, const String&);
Color m_foregroundColor;
Color m_backgroundColor;
diff --git a/Source/WebCore/html/track/TextTrackCueList.cpp b/Source/WebCore/html/track/TextTrackCueList.cpp
index e8566c259..f5451f5f0 100644
--- a/Source/WebCore/html/track/TextTrackCueList.cpp
+++ b/Source/WebCore/html/track/TextTrackCueList.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -77,8 +77,8 @@ TextTrackCueList* TextTrackCueList::activeCues()
bool TextTrackCueList::add(PassRefPtr<TextTrackCue> cue)
{
- ASSERT(cue->startMediaTime() >= MediaTime::zeroTime());
- ASSERT(cue->endMediaTime() >= MediaTime::zeroTime());
+ ASSERT(cue->startTime() >= 0);
+ ASSERT(cue->endTime() >= 0);
return add(cue, 0, m_list.size());
}
diff --git a/Source/WebCore/html/track/TextTrackCueList.h b/Source/WebCore/html/track/TextTrackCueList.h
index f83722966..8478fa31f 100644
--- a/Source/WebCore/html/track/TextTrackCueList.h
+++ b/Source/WebCore/html/track/TextTrackCueList.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -37,9 +37,9 @@ namespace WebCore {
class TextTrackCueList : public RefCounted<TextTrackCueList> {
public:
- static Ref<TextTrackCueList> create()
+ static PassRefPtr<TextTrackCueList> create()
{
- return adoptRef(*new TextTrackCueList);
+ return adoptRef(new TextTrackCueList);
}
~TextTrackCueList() { }
diff --git a/Source/WebCore/html/track/TextTrackCueList.idl b/Source/WebCore/html/track/TextTrackCueList.idl
index 6aaafdb08..3a083b91b 100644
--- a/Source/WebCore/html/track/TextTrackCueList.idl
+++ b/Source/WebCore/html/track/TextTrackCueList.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/track/TextTrackList.cpp b/Source/WebCore/html/track/TextTrackList.cpp
index 159fb3ddf..18d3f1bab 100644
--- a/Source/WebCore/html/track/TextTrackList.cpp
+++ b/Source/WebCore/html/track/TextTrackList.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -51,10 +51,10 @@ unsigned TextTrackList::length() const
return m_addTrackTracks.size() + m_elementTracks.size() + m_inbandTracks.size();
}
-int TextTrackList::getTrackIndex(TextTrack* textTrack)
+int TextTrackList::getTrackIndex(TextTrack *textTrack)
{
- if (is<LoadableTextTrack>(textTrack))
- return downcast<LoadableTextTrack>(*textTrack).trackElementIndex();
+ if (textTrack->trackType() == TextTrack::TrackElement)
+ return static_cast<LoadableTextTrack*>(textTrack)->trackElementIndex();
if (textTrack->trackType() == TextTrack::AddTrack)
return m_elementTracks.size() + m_addTrackTracks.find(textTrack);
@@ -176,9 +176,9 @@ void TextTrackList::append(PassRefPtr<TextTrack> prpTrack)
if (track->trackType() == TextTrack::AddTrack)
m_addTrackTracks.append(track);
- else if (is<LoadableTextTrack>(*track)) {
+ else if (track->trackType() == TextTrack::TrackElement) {
// Insert tracks added for <track> element in tree order.
- size_t index = downcast<LoadableTextTrack>(*track).trackElementIndex();
+ size_t index = static_cast<LoadableTextTrack*>(track.get())->trackElementIndex();
m_elementTracks.insert(index, track);
} else if (track->trackType() == TextTrack::InBand) {
// Insert tracks added for in-band in the media file order.
@@ -195,7 +195,7 @@ void TextTrackList::append(PassRefPtr<TextTrack> prpTrack)
scheduleAddTrackEvent(track.release());
}
-void TextTrackList::remove(TrackBase* track, bool scheduleEvent)
+void TextTrackList::remove(TrackBase* track)
{
TextTrack* textTrack = toTextTrack(track);
Vector<RefPtr<TrackBase>>* tracks = 0;
@@ -219,9 +219,7 @@ void TextTrackList::remove(TrackBase* track, bool scheduleEvent)
RefPtr<TrackBase> trackRef = (*tracks)[index];
tracks->remove(index);
-
- if (scheduleEvent)
- scheduleRemoveTrackEvent(trackRef.release());
+ scheduleRemoveTrackEvent(trackRef.release());
}
bool TextTrackList::contains(TrackBase* track) const
diff --git a/Source/WebCore/html/track/TextTrackList.h b/Source/WebCore/html/track/TextTrackList.h
index 6aa00e035..57c8b8288 100644
--- a/Source/WebCore/html/track/TextTrackList.h
+++ b/Source/WebCore/html/track/TextTrackList.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -34,11 +34,11 @@ namespace WebCore {
class TextTrack;
-class TextTrackList final : public TrackListBase {
+class TextTrackList : public TrackListBase {
public:
- static Ref<TextTrackList> create(HTMLMediaElement* element, ScriptExecutionContext* context)
+ static PassRefPtr<TextTrackList> create(HTMLMediaElement* element, ScriptExecutionContext* context)
{
- return adoptRef(*new TextTrackList(element, context));
+ return adoptRef(new TextTrackList(element, context));
}
virtual ~TextTrackList();
@@ -52,7 +52,7 @@ public:
TextTrack* lastItem() const { return item(length() - 1); }
void append(PassRefPtr<TextTrack>);
- virtual void remove(TrackBase*, bool scheduleEvent = true) override;
+ virtual void remove(TrackBase*) override;
// EventTarget
virtual EventTargetInterface eventTargetInterface() const override;
diff --git a/Source/WebCore/html/track/TextTrackList.idl b/Source/WebCore/html/track/TextTrackList.idl
index 08cca4a14..10e514fe5 100644
--- a/Source/WebCore/html/track/TextTrackList.idl
+++ b/Source/WebCore/html/track/TextTrackList.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -33,12 +33,16 @@
getter TextTrack item(unsigned long index);
TextTrack getTrackById(DOMString id);
- attribute EventHandler onaddtrack;
- attribute EventHandler onchange;
- attribute EventHandler onremovetrack;
+ attribute EventListener onaddtrack;
+ attribute EventListener onchange;
+ attribute EventListener onremovetrack;
- void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
- void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
- [RaisesException] boolean dispatchEvent(Event event);
+ void addEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ void removeEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ [RaisesException] boolean dispatchEvent(Event evt);
};
diff --git a/Source/WebCore/html/track/VTTRegion.h b/Source/WebCore/html/track/TextTrackRegion.h
index 4fa598ba6..01b64ce4d 100644
--- a/Source/WebCore/html/track/VTTRegion.h
+++ b/Source/WebCore/html/track/TextTrackRegion.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -29,31 +28,26 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef VTTRegion_h
-#define VTTRegion_h
+#ifndef TextTrackRegion_h
+#define TextTrackRegion_h
#if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS)
-#include "ContextDestructionObserver.h"
-#include "Document.h"
#include "FloatPoint.h"
#include "TextTrack.h"
+#include <wtf/PassOwnPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
-class HTMLDivElement;
-class VTTCueBox;
-class VTTScanner;
-
-class VTTRegion final : public RefCounted<VTTRegion>, public ContextDestructionObserver {
+class TextTrackRegion : public RefCounted<TextTrackRegion> {
public:
- static Ref<VTTRegion> create(ScriptExecutionContext& context)
+ static PassRefPtr<TextTrackRegion> create()
{
- return adoptRef(*new VTTRegion(context));
+ return adoptRef(new TextTrackRegion());
}
- virtual ~VTTRegion();
+ virtual ~TextTrackRegion();
TextTrack* track() const { return m_track; }
void setTrack(TextTrack*);
@@ -82,30 +76,13 @@ public:
const AtomicString scroll() const;
void setScroll(const AtomicString&, ExceptionCode&);
- void updateParametersFromRegion(VTTRegion*);
+ void updateParametersFromRegion(TextTrackRegion*);
const String& regionSettings() const { return m_settings; }
void setRegionSettings(const String&);
- bool isScrollingRegion() { return m_scroll; }
-
- PassRefPtr<HTMLDivElement> getDisplayTree();
-
- void appendTextTrackCueBox(PassRefPtr<VTTCueBox>);
- void displayLastTextTrackCueBox();
- void willRemoveTextTrackCueBox(VTTCueBox*);
-
private:
- VTTRegion(ScriptExecutionContext&);
-
- Document* ownerDocument() { return downcast<Document>(m_scriptExecutionContext); }
-
- void prepareRegionDisplayTree();
-
- // The timer is needed to continue processing when cue scrolling ended.
- void startTimer();
- void stopTimer();
- void scrollTimerFired();
+ TextTrackRegion();
enum RegionSetting {
None,
@@ -117,13 +94,10 @@ private:
Scroll
};
- RegionSetting scanSettingName(VTTScanner&);
-
- void parseSettingValue(RegionSetting, VTTScanner&);
+ RegionSetting getSettingFromString(const String&);
- static const AtomicString& textTrackCueContainerShadowPseudoId();
- static const AtomicString& textTrackCueContainerScrollingClass();
- static const AtomicString& textTrackRegionShadowPseudoId();
+ void parseSettingValue(RegionSetting, const String&);
+ void parseSetting(const String&, unsigned*);
String m_id;
String m_settings;
@@ -136,26 +110,11 @@ private:
bool m_scroll;
- // The cue container is the container that is scrolled up to obtain the
- // effect of scrolling cues when this is enabled for the regions.
- RefPtr<HTMLDivElement> m_cueContainer;
- RefPtr<HTMLDivElement> m_regionDisplayTree;
-
// The member variable track can be a raw pointer as it will never
// reference a destroyed TextTrack, as this member variable
// is cleared in the TextTrack destructor and it is generally
// set/reset within the addRegion and removeRegion methods.
TextTrack* m_track;
-
- // Keep track of the current numeric value of the css "top" property.
- double m_currentTop;
-
- // The timer is used to display the next cue line after the current one has
- // been displayed. It's main use is for scrolling regions and it triggers as
- // soon as the animation for rolling out one line has finished, but
- // currently it is used also for non-scrolling regions to use a single
- // code path.
- Timer m_scrollTimer;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/track/VTTRegion.idl b/Source/WebCore/html/track/TextTrackRegion.idl
index ce25944a6..f8f23b27b 100644
--- a/Source/WebCore/html/track/VTTRegion.idl
+++ b/Source/WebCore/html/track/TextTrackRegion.idl
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -27,18 +26,17 @@
[
Conditional=VIDEO_TRACK & WEBVTT_REGIONS,
JSGenerateToNativeObject,
- Constructor(),
- ConstructorCallWith=ScriptExecutionContext
-] interface VTTRegion {
+ Constructor()
+] interface TextTrackRegion {
readonly attribute TextTrack track;
attribute DOMString id;
- [SetterRaisesException] attribute unrestricted double width;
+ [SetterRaisesException] attribute double width;
[SetterRaisesException] attribute long height;
- [SetterRaisesException] attribute unrestricted double regionAnchorX;
- [SetterRaisesException] attribute unrestricted double regionAnchorY;
- [SetterRaisesException] attribute unrestricted double viewportAnchorX;
- [SetterRaisesException] attribute unrestricted double viewportAnchorY;
+ [SetterRaisesException] attribute double regionAnchorX;
+ [SetterRaisesException] attribute double regionAnchorY;
+ [SetterRaisesException] attribute double viewportAnchorX;
+ [SetterRaisesException] attribute double viewportAnchorY;
[SetterRaisesException] attribute DOMString scroll;
};
diff --git a/Source/WebCore/html/track/VTTRegionList.h b/Source/WebCore/html/track/TextTrackRegionList.h
index adf4977c3..070e3e56e 100644
--- a/Source/WebCore/html/track/VTTRegionList.h
+++ b/Source/WebCore/html/track/TextTrackRegionList.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -24,40 +23,40 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef VTTRegionList_h
-#define VTTRegionList_h
+#ifndef TextTrackRegionList_h
+#define TextTrackRegionList_h
#if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS)
-#include "VTTRegion.h"
+#include "TextTrackRegion.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
namespace WebCore {
-class VTTRegionList : public RefCounted<VTTRegionList> {
+class TextTrackRegionList : public RefCounted<TextTrackRegionList> {
public:
- static Ref<VTTRegionList> create()
+ static PassRefPtr<TextTrackRegionList> create()
{
- return adoptRef(*new VTTRegionList);
+ return adoptRef(new TextTrackRegionList());
}
- ~VTTRegionList() { }
+ ~TextTrackRegionList() { }
unsigned long length() const;
- VTTRegion* item(unsigned index) const;
- VTTRegion* getRegionById(const String&) const;
+ TextTrackRegion* item(unsigned index) const;
+ TextTrackRegion* getRegionById(const String&) const;
- void add(PassRefPtr<VTTRegion>);
- bool remove(VTTRegion*);
+ void add(PassRefPtr<TextTrackRegion>);
+ bool remove(TextTrackRegion*);
private:
- VTTRegionList();
+ TextTrackRegionList();
void clear();
- Vector<RefPtr<VTTRegion> > m_list;
+ Vector<RefPtr<TextTrackRegion> > m_list;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/track/VTTRegionList.idl b/Source/WebCore/html/track/TextTrackRegionList.idl
index fd5b58bbc..31a0519d1 100644
--- a/Source/WebCore/html/track/VTTRegionList.idl
+++ b/Source/WebCore/html/track/TextTrackRegionList.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -27,9 +27,9 @@
NoInterfaceObject,
Conditional=VIDEO_TRACK & WEBVTT_REGIONS,
ImplementationLacksVTable,
-] interface VTTRegionList {
+] interface TextTrackRegionList {
readonly attribute unsigned long length;
- getter VTTRegion item(unsigned long index);
- VTTRegion getRegionById(DOMString id);
+ getter TextTrackRegion item(unsigned long index);
+ TextTrackRegion getRegionById(DOMString id);
};
diff --git a/Source/WebCore/html/track/TrackBase.cpp b/Source/WebCore/html/track/TrackBase.cpp
index ff0b6ca11..e93e9e908 100644
--- a/Source/WebCore/html/track/TrackBase.cpp
+++ b/Source/WebCore/html/track/TrackBase.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -32,14 +32,11 @@
namespace WebCore {
-static int s_uniqueId = 0;
-
TrackBase::TrackBase(Type type, const AtomicString& id, const AtomicString& label, const AtomicString& language)
: m_mediaElement(0)
#if ENABLE(MEDIA_SOURCE)
, m_sourceBuffer(0)
#endif
- , m_uniqueId(++s_uniqueId)
, m_id(id)
, m_label(label)
, m_language(language)
diff --git a/Source/WebCore/html/track/TrackBase.h b/Source/WebCore/html/track/TrackBase.h
index 245988b7c..509f7a61f 100644
--- a/Source/WebCore/html/track/TrackBase.h
+++ b/Source/WebCore/html/track/TrackBase.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -62,8 +62,6 @@ public:
virtual void clearClient() = 0;
- virtual int uniqueId() const { return m_uniqueId; }
-
#if ENABLE(MEDIA_SOURCE)
SourceBuffer* sourceBuffer() const { return m_sourceBuffer; }
void setSourceBuffer(SourceBuffer* buffer) { m_sourceBuffer = buffer; }
@@ -87,7 +85,6 @@ protected:
private:
Type m_type;
- int m_uniqueId;
AtomicString m_id;
AtomicString m_kind;
AtomicString m_label;
diff --git a/Source/WebCore/html/track/TrackEvent.cpp b/Source/WebCore/html/track/TrackEvent.cpp
index d26147b9e..16eb4d8be 100644
--- a/Source/WebCore/html/track/TrackEvent.cpp
+++ b/Source/WebCore/html/track/TrackEvent.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/track/TrackEvent.h b/Source/WebCore/html/track/TrackEvent.h
index ca4083153..3c7e43a45 100644
--- a/Source/WebCore/html/track/TrackEvent.h
+++ b/Source/WebCore/html/track/TrackEvent.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -39,18 +39,18 @@ struct TrackEventInit : public EventInit {
RefPtr<TrackBase> track;
};
-class TrackEvent final : public Event {
+class TrackEvent : public Event {
public:
virtual ~TrackEvent();
- static Ref<TrackEvent> create()
+ static PassRefPtr<TrackEvent> create()
{
- return adoptRef(*new TrackEvent);
+ return adoptRef(new TrackEvent);
}
- static Ref<TrackEvent> create(const AtomicString& type, const TrackEventInit& initializer)
+ static PassRefPtr<TrackEvent> create(const AtomicString& type, const TrackEventInit& initializer)
{
- return adoptRef(*new TrackEvent(type, initializer));
+ return adoptRef(new TrackEvent(type, initializer));
}
virtual EventInterface eventInterface() const override;
diff --git a/Source/WebCore/html/track/TrackEvent.idl b/Source/WebCore/html/track/TrackEvent.idl
index 3ee5c8426..576761e1a 100644
--- a/Source/WebCore/html/track/TrackEvent.idl
+++ b/Source/WebCore/html/track/TrackEvent.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/track/TrackListBase.cpp b/Source/WebCore/html/track/TrackListBase.cpp
index 4d915a716..7fb47b68d 100644
--- a/Source/WebCore/html/track/TrackListBase.cpp
+++ b/Source/WebCore/html/track/TrackListBase.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -58,7 +58,7 @@ unsigned TrackListBase::length() const
return m_inbandTracks.size();
}
-void TrackListBase::remove(TrackBase* track, bool scheduleEvent)
+void TrackListBase::remove(TrackBase* track)
{
size_t index = m_inbandTracks.find(track);
ASSERT(index != notFound);
@@ -70,8 +70,7 @@ void TrackListBase::remove(TrackBase* track, bool scheduleEvent)
m_inbandTracks.remove(index);
- if (scheduleEvent)
- scheduleRemoveTrackEvent(trackRef.release());
+ scheduleRemoveTrackEvent(trackRef.release());
}
bool TrackListBase::contains(TrackBase* track) const
diff --git a/Source/WebCore/html/track/TrackListBase.h b/Source/WebCore/html/track/TrackListBase.h
index 84a5cbc5a..87c86a479 100644
--- a/Source/WebCore/html/track/TrackListBase.h
+++ b/Source/WebCore/html/track/TrackListBase.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -48,14 +48,18 @@ public:
virtual unsigned length() const;
virtual bool contains(TrackBase*) const;
- virtual void remove(TrackBase*, bool scheduleEvent = true);
+ virtual void remove(TrackBase*);
// EventTarget
- virtual EventTargetInterface eventTargetInterface() const override = 0;
+ virtual EventTargetInterface eventTargetInterface() const = 0;
using RefCounted<TrackListBase>::ref;
using RefCounted<TrackListBase>::deref;
virtual ScriptExecutionContext* scriptExecutionContext() const override final { return m_context; }
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack);
+
void clearElement() { m_element = 0; }
Element* element() const;
HTMLMediaElement* mediaElement() const { return m_element; }
diff --git a/Source/WebCore/html/track/VTTCue.cpp b/Source/WebCore/html/track/VTTCue.cpp
deleted file mode 100644
index 0b9c71793..000000000
--- a/Source/WebCore/html/track/VTTCue.cpp
+++ /dev/null
@@ -1,1175 +0,0 @@
-/*
- * Copyright (C) 2011, 2013 Google Inc. All rights reserved.
- * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(VIDEO_TRACK)
-#include "VTTCue.h"
-
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "DocumentFragment.h"
-#include "Event.h"
-#include "HTMLDivElement.h"
-#include "HTMLSpanElement.h"
-#include "Logging.h"
-#include "NodeTraversal.h"
-#include "RenderVTTCue.h"
-#include "Text.h"
-#include "TextTrack.h"
-#include "TextTrackCueList.h"
-#include "VTTScanner.h"
-#include "WebVTTElement.h"
-#include "WebVTTParser.h"
-#include <wtf/MathExtras.h>
-#include <wtf/text/StringBuilder.h>
-
-#if ENABLE(WEBVTT_REGIONS)
-#include "VTTRegionList.h"
-#endif
-
-namespace WebCore {
-
-// This constant should correspond with the percentage returned by CaptionUserPreferences::captionFontSizeScaleAndImportance.
-const static double DEFAULTCAPTIONFONTSIZEPERCENTAGE = 5;
-
-static const int undefinedPosition = -1;
-
-static const CSSValueID displayWritingModeMap[] = {
- CSSValueHorizontalTb, CSSValueVerticalRl, CSSValueVerticalLr
-};
-COMPILE_ASSERT(WTF_ARRAY_LENGTH(displayWritingModeMap) == VTTCue::NumberOfWritingDirections, displayWritingModeMap_has_wrong_size);
-
-static const CSSValueID displayAlignmentMap[] = {
- CSSValueStart, CSSValueCenter, CSSValueEnd, CSSValueLeft, CSSValueRight
-};
-COMPILE_ASSERT(WTF_ARRAY_LENGTH(displayAlignmentMap) == VTTCue::NumberOfAlignments, displayAlignmentMap_has_wrong_size);
-
-static const String& startKeyword()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, start, (ASCIILiteral("start")));
- return start;
-}
-
-static const String& middleKeyword()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, middle, (ASCIILiteral("middle")));
- return middle;
-}
-
-static const String& endKeyword()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, end, (ASCIILiteral("end")));
- return end;
-}
-
-static const String& leftKeyword()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, left, ("left"));
- return left;
-}
-
-static const String& rightKeyword()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, right, ("right"));
- return right;
-}
-
-static const String& horizontalKeyword()
-{
- return emptyString();
-}
-
-static const String& verticalGrowingLeftKeyword()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, verticalrl, (ASCIILiteral("rl")));
- return verticalrl;
-}
-
-static const String& verticalGrowingRightKeyword()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, verticallr, (ASCIILiteral("lr")));
- return verticallr;
-}
-
-// ----------------------------
-
-PassRefPtr<VTTCueBox> VTTCueBox::create(Document& document, VTTCue& cue)
-{
- VTTCueBox* cueBox = new VTTCueBox(document, cue);
- cueBox->setPseudo(VTTCueBox::vttCueBoxShadowPseudoId());
- return adoptRef(cueBox);
-}
-
-VTTCueBox::VTTCueBox(Document& document, VTTCue& cue)
- : HTMLElement(divTag, document)
- , m_cue(cue)
-{
- setPseudo(vttCueBoxShadowPseudoId());
-}
-
-VTTCue* VTTCueBox::getCue() const
-{
- return &m_cue;
-}
-
-void VTTCueBox::applyCSSProperties(const IntSize& videoSize)
-{
- // FIXME: Apply all the initial CSS positioning properties. http://wkb.ug/79916
-#if ENABLE(WEBVTT_REGIONS)
- if (!m_cue.regionId().isEmpty()) {
- setInlineStyleProperty(CSSPropertyPosition, CSSValueRelative);
- return;
- }
-#endif
-
- // 3.5.1 On the (root) List of WebVTT Node Objects:
-
- // the 'position' property must be set to 'absolute'
- setInlineStyleProperty(CSSPropertyPosition, CSSValueAbsolute);
-
- // the 'unicode-bidi' property must be set to 'plaintext'
- setInlineStyleProperty(CSSPropertyUnicodeBidi, CSSValueWebkitPlaintext);
-
- // the 'direction' property must be set to direction
- setInlineStyleProperty(CSSPropertyDirection, m_cue.getCSSWritingDirection());
-
- // the 'writing-mode' property must be set to writing-mode
- setInlineStyleProperty(CSSPropertyWebkitWritingMode, m_cue.getCSSWritingMode(), false);
-
- std::pair<float, float> position = m_cue.getCSSPosition();
-
- // the 'top' property must be set to top,
- setInlineStyleProperty(CSSPropertyTop, static_cast<double>(position.second), CSSPrimitiveValue::CSS_PERCENTAGE);
-
- // the 'left' property must be set to left
- setInlineStyleProperty(CSSPropertyLeft, static_cast<double>(position.first), CSSPrimitiveValue::CSS_PERCENTAGE);
-
- double authorFontSize = std::min(videoSize.width(), videoSize.height()) * DEFAULTCAPTIONFONTSIZEPERCENTAGE / 100.0;
- double multiplier = 1.0;
- if (authorFontSize)
- multiplier = m_fontSizeFromCaptionUserPrefs / authorFontSize;
-
- double textPosition = m_cue.position();
- double maxSize = 100.0;
- CSSValueID alignment = m_cue.getCSSAlignment();
- if (alignment == CSSValueEnd || alignment == CSSValueRight)
- maxSize = textPosition;
- else if (alignment == CSSValueStart || alignment == CSSValueLeft)
- maxSize = 100.0 - textPosition;
-
- double newCueSize = std::min(m_cue.getCSSSize() * multiplier, 100.0);
- // the 'width' property must be set to width, and the 'height' property must be set to height
- if (m_cue.vertical() == horizontalKeyword()) {
- setInlineStyleProperty(CSSPropertyWidth, newCueSize, CSSPrimitiveValue::CSS_PERCENTAGE);
- setInlineStyleProperty(CSSPropertyHeight, CSSValueAuto);
- setInlineStyleProperty(CSSPropertyMinWidth, "-webkit-min-content");
- setInlineStyleProperty(CSSPropertyMaxWidth, maxSize, CSSPrimitiveValue::CSS_PERCENTAGE);
- if ((alignment == CSSValueMiddle || alignment == CSSValueCenter) && multiplier != 1.0)
- setInlineStyleProperty(CSSPropertyLeft, static_cast<double>(position.first - (newCueSize - m_cue.getCSSSize()) / 2), CSSPrimitiveValue::CSS_PERCENTAGE);
- } else {
- setInlineStyleProperty(CSSPropertyWidth, CSSValueAuto);
- setInlineStyleProperty(CSSPropertyHeight, newCueSize, CSSPrimitiveValue::CSS_PERCENTAGE);
- setInlineStyleProperty(CSSPropertyMinHeight, "-webkit-min-content");
- setInlineStyleProperty(CSSPropertyMaxHeight, maxSize, CSSPrimitiveValue::CSS_PERCENTAGE);
- if ((alignment == CSSValueMiddle || alignment == CSSValueCenter) && multiplier != 1.0)
- setInlineStyleProperty(CSSPropertyTop, static_cast<double>(position.second - (newCueSize - m_cue.getCSSSize()) / 2), CSSPrimitiveValue::CSS_PERCENTAGE);
- }
-
- // The 'text-align' property on the (root) List of WebVTT Node Objects must
- // be set to the value in the second cell of the row of the table below
- // whose first cell is the value of the corresponding cue's text track cue
- // alignment:
- setInlineStyleProperty(CSSPropertyTextAlign, m_cue.getCSSAlignment());
-
- if (!m_cue.snapToLines()) {
- // 10.13.1 Set up x and y:
- // Note: x and y are set through the CSS left and top above.
-
- // 10.13.2 Position the boxes in boxes such that the point x% along the
- // width of the bounding box of the boxes in boxes is x% of the way
- // across the width of the video's rendering area, and the point y%
- // along the height of the bounding box of the boxes in boxes is y%
- // of the way across the height of the video's rendering area, while
- // maintaining the relative positions of the boxes in boxes to each
- // other.
- setInlineStyleProperty(CSSPropertyTransform,
- String::format("translate(-%.2f%%, -%.2f%%)", position.first, position.second));
-
- setInlineStyleProperty(CSSPropertyWhiteSpace, CSSValuePre);
- }
-}
-
-const AtomicString& VTTCueBox::vttCueBoxShadowPseudoId()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, trackDisplayBoxShadowPseudoId, ("-webkit-media-text-track-display", AtomicString::ConstructFromLiteral));
- return trackDisplayBoxShadowPseudoId;
-}
-
-RenderPtr<RenderElement> VTTCueBox::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
-{
- return createRenderer<RenderVTTCue>(*this, WTF::move(style));
-}
-
-// ----------------------------
-
-const AtomicString& VTTCue::cueBackdropShadowPseudoId()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, cueBackdropShadowPseudoId, ("-webkit-media-text-track-display-backdrop", AtomicString::ConstructFromLiteral));
- return cueBackdropShadowPseudoId;
-}
-
-Ref<VTTCue> VTTCue::create(ScriptExecutionContext& context, const WebVTTCueData& data)
-{
- return adoptRef(*new VTTCue(context, data));
-}
-
-VTTCue::VTTCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, const String& content)
- : TextTrackCue(context, start, end)
- , m_content(content)
-{
- initialize(context);
-}
-
-VTTCue::VTTCue(ScriptExecutionContext& context, const WebVTTCueData& cueData)
- : TextTrackCue(context, MediaTime::zeroTime(), MediaTime::zeroTime())
-{
- initialize(context);
- setText(cueData.content());
- setStartTime(cueData.startTime());
- setEndTime(cueData.endTime());
- setId(cueData.id());
- setCueSettings(cueData.settings());
- m_originalStartTime = cueData.originalStartTime();
-}
-
-VTTCue::~VTTCue()
-{
- if (!hasDisplayTree())
- return;
-
- displayTreeInternal()->remove(ASSERT_NO_EXCEPTION);
-}
-
-void VTTCue::initialize(ScriptExecutionContext& context)
-{
- m_linePosition = undefinedPosition;
- m_computedLinePosition = undefinedPosition;
- m_textPosition = 50;
- m_cueSize = 100;
- m_writingDirection = Horizontal;
- m_cueAlignment = Middle;
- m_webVTTNodeTree = nullptr;
- m_cueBackdropBox = HTMLDivElement::create(downcast<Document>(context));
- m_cueHighlightBox = HTMLSpanElement::create(spanTag, downcast<Document>(context));
- m_displayDirection = CSSValueLtr;
- m_displaySize = 0;
- m_snapToLines = true;
- m_displayTreeShouldChange = true;
- m_notifyRegion = true;
- m_originalStartTime = MediaTime::zeroTime();
-}
-
-PassRefPtr<VTTCueBox> VTTCue::createDisplayTree()
-{
- return VTTCueBox::create(ownerDocument(), *this);
-}
-
-VTTCueBox* VTTCue::displayTreeInternal()
-{
- if (!m_displayTree)
- m_displayTree = createDisplayTree();
- return m_displayTree.get();
-}
-
-void VTTCue::didChange()
-{
- TextTrackCue::didChange();
- m_displayTreeShouldChange = true;
-}
-
-const String& VTTCue::vertical() const
-{
- switch (m_writingDirection) {
- case Horizontal:
- return horizontalKeyword();
- case VerticalGrowingLeft:
- return verticalGrowingLeftKeyword();
- case VerticalGrowingRight:
- return verticalGrowingRightKeyword();
- default:
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-}
-
-void VTTCue::setVertical(const String& value, ExceptionCode& ec)
-{
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-vertical
- // On setting, the text track cue writing direction must be set to the value given
- // in the first cell of the row in the table above whose second cell is a
- // case-sensitive match for the new value, if any. If none of the values match, then
- // the user agent must instead throw a SyntaxError exception.
-
- WritingDirection direction = m_writingDirection;
- if (value == horizontalKeyword())
- direction = Horizontal;
- else if (value == verticalGrowingLeftKeyword())
- direction = VerticalGrowingLeft;
- else if (value == verticalGrowingRightKeyword())
- direction = VerticalGrowingRight;
- else
- ec = SYNTAX_ERR;
-
- if (direction == m_writingDirection)
- return;
-
- willChange();
- m_writingDirection = direction;
- didChange();
-}
-
-void VTTCue::setSnapToLines(bool value)
-{
- if (m_snapToLines == value)
- return;
-
- willChange();
- m_snapToLines = value;
- didChange();
-}
-
-void VTTCue::setLine(double position, ExceptionCode& ec)
-{
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-line
- // On setting, if the text track cue snap-to-lines flag is not set, and the new
- // value is negative or greater than 100, then throw an IndexSizeError exception.
- if (!m_snapToLines && (position < 0 || position > 100)) {
- ec = INDEX_SIZE_ERR;
- return;
- }
-
- // Otherwise, set the text track cue line position to the new value.
- if (m_linePosition == position)
- return;
-
- willChange();
- m_linePosition = position;
- m_computedLinePosition = calculateComputedLinePosition();
- didChange();
-}
-
-void VTTCue::setPosition(double position, ExceptionCode& ec)
-{
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-position
- // On setting, if the new value is negative or greater than 100, then throw an IndexSizeError exception.
- // Otherwise, set the text track cue text position to the new value.
- if (position < 0 || position > 100) {
- ec = INDEX_SIZE_ERR;
- return;
- }
-
- // Otherwise, set the text track cue line position to the new value.
- if (m_textPosition == position)
- return;
-
- willChange();
- m_textPosition = position;
- didChange();
-}
-
-void VTTCue::setSize(int size, ExceptionCode& ec)
-{
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-size
- // On setting, if the new value is negative or greater than 100, then throw an IndexSizeError
- // exception. Otherwise, set the text track cue size to the new value.
- if (size < 0 || size > 100) {
- ec = INDEX_SIZE_ERR;
- return;
- }
-
- // Otherwise, set the text track cue line position to the new value.
- if (m_cueSize == size)
- return;
-
- willChange();
- m_cueSize = size;
- didChange();
-}
-
-const String& VTTCue::align() const
-{
- switch (m_cueAlignment) {
- case Start:
- return startKeyword();
- case Middle:
- return middleKeyword();
- case End:
- return endKeyword();
- case Left:
- return leftKeyword();
- case Right:
- return rightKeyword();
- default:
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-}
-
-void VTTCue::setAlign(const String& value, ExceptionCode& ec)
-{
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-align
- // On setting, the text track cue alignment must be set to the value given in the
- // first cell of the row in the table above whose second cell is a case-sensitive
- // match for the new value, if any. If none of the values match, then the user
- // agent must instead throw a SyntaxError exception.
-
- CueAlignment alignment = m_cueAlignment;
- if (value == startKeyword())
- alignment = Start;
- else if (value == middleKeyword())
- alignment = Middle;
- else if (value == endKeyword())
- alignment = End;
- else if (value == leftKeyword())
- alignment = Left;
- else if (value == rightKeyword())
- alignment = Right;
- else
- ec = SYNTAX_ERR;
-
- if (alignment == m_cueAlignment)
- return;
-
- willChange();
- m_cueAlignment = alignment;
- didChange();
-}
-
-void VTTCue::setText(const String& text)
-{
- if (m_content == text)
- return;
-
- willChange();
- // Clear the document fragment but don't bother to create it again just yet as we can do that
- // when it is requested.
- m_webVTTNodeTree = nullptr;
- m_content = text;
- didChange();
-}
-
-void VTTCue::createWebVTTNodeTree()
-{
- if (!m_webVTTNodeTree)
- m_webVTTNodeTree = WebVTTParser::createDocumentFragmentFromCueText(ownerDocument(), m_content);
-}
-
-void VTTCue::copyWebVTTNodeToDOMTree(ContainerNode* webVTTNode, ContainerNode* parent)
-{
- for (Node* node = webVTTNode->firstChild(); node; node = node->nextSibling()) {
- RefPtr<Node> clonedNode;
- if (is<WebVTTElement>(*node))
- clonedNode = downcast<WebVTTElement>(*node).createEquivalentHTMLElement(ownerDocument());
- else
- clonedNode = node->cloneNode(false);
- parent->appendChild(clonedNode, ASSERT_NO_EXCEPTION);
- if (is<ContainerNode>(*node))
- copyWebVTTNodeToDOMTree(downcast<ContainerNode>(node), downcast<ContainerNode>(clonedNode.get()));
- }
-}
-
-PassRefPtr<DocumentFragment> VTTCue::getCueAsHTML()
-{
- createWebVTTNodeTree();
- if (!m_webVTTNodeTree)
- return 0;
-
- RefPtr<DocumentFragment> clonedFragment = DocumentFragment::create(ownerDocument());
- copyWebVTTNodeToDOMTree(m_webVTTNodeTree.get(), clonedFragment.get());
- return clonedFragment.release();
-}
-
-PassRefPtr<DocumentFragment> VTTCue::createCueRenderingTree()
-{
- RefPtr<DocumentFragment> clonedFragment;
- createWebVTTNodeTree();
- if (!m_webVTTNodeTree)
- return 0;
-
- clonedFragment = DocumentFragment::create(ownerDocument());
- m_webVTTNodeTree->cloneChildNodes(clonedFragment.get());
- return clonedFragment.release();
-}
-
-#if ENABLE(WEBVTT_REGIONS)
-void VTTCue::setRegionId(const String& regionId)
-{
- if (m_regionId == regionId)
- return;
-
- willChange();
- m_regionId = regionId;
- didChange();
-}
-
-void VTTCue::notifyRegionWhenRemovingDisplayTree(bool notifyRegion)
-{
- m_notifyRegion = notifyRegion;
-}
-#endif
-
-void VTTCue::setIsActive(bool active)
-{
- TextTrackCue::setIsActive(active);
-
- if (!active) {
- if (!hasDisplayTree())
- return;
-
- // Remove the display tree as soon as the cue becomes inactive.
- removeDisplayTree();
- }
-}
-
-int VTTCue::calculateComputedLinePosition()
-{
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-computed-line-position
-
- // If the text track cue line position is numeric, then that is the text
- // track cue computed line position.
- if (m_linePosition != undefinedPosition)
- return m_linePosition;
-
- // If the text track cue snap-to-lines flag of the text track cue is not
- // set, the text track cue computed line position is the value 100;
- if (!m_snapToLines)
- return 100;
-
- // Otherwise, it is the value returned by the following algorithm:
-
- // If cue is not associated with a text track, return -1 and abort these
- // steps.
- if (!track())
- return -1;
-
- // Let n be the number of text tracks whose text track mode is showing or
- // showing by default and that are in the media element's list of text
- // tracks before track.
- int n = track()->trackIndexRelativeToRenderedTracks();
-
- // Increment n by one.
- n++;
-
- // Negate n.
- n = -n;
-
- return n;
-}
-
-static bool isCueParagraphSeparator(UChar character)
-{
- // Within a cue, paragraph boundaries are only denoted by Type B characters,
- // such as U+000A LINE FEED (LF), U+0085 NEXT LINE (NEL), and U+2029 PARAGRAPH SEPARATOR.
- return u_charType(character) == U_PARAGRAPH_SEPARATOR;
-}
-
-void VTTCue::determineTextDirection()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, rtTag, (ASCIILiteral("rt")));
- createWebVTTNodeTree();
- if (!m_webVTTNodeTree)
- return;
-
- // Apply the Unicode Bidirectional Algorithm's Paragraph Level steps to the
- // concatenation of the values of each WebVTT Text Object in nodes, in a
- // pre-order, depth-first traversal, excluding WebVTT Ruby Text Objects and
- // their descendants.
- StringBuilder paragraphBuilder;
- for (Node* node = m_webVTTNodeTree->firstChild(); node; node = NodeTraversal::next(*node, m_webVTTNodeTree.get())) {
- // FIXME: The code does not match the comment above. This does not actually exclude Ruby Text Object descendant.
- if (!node->isTextNode() || node->localName() == rtTag)
- continue;
-
- paragraphBuilder.append(node->nodeValue());
- }
-
- String paragraph = paragraphBuilder.toString();
- if (!paragraph.length())
- return;
-
- for (size_t i = 0; i < paragraph.length(); ++i) {
- UChar current = paragraph[i];
- if (!current || isCueParagraphSeparator(current))
- return;
-
- if (UChar current = paragraph[i]) {
- UCharDirection charDirection = u_charDirection(current);
- if (charDirection == U_LEFT_TO_RIGHT) {
- m_displayDirection = CSSValueLtr;
- return;
- }
- if (charDirection == U_RIGHT_TO_LEFT || charDirection == U_RIGHT_TO_LEFT_ARABIC) {
- m_displayDirection = CSSValueRtl;
- return;
- }
- }
- }
-}
-
-void VTTCue::calculateDisplayParameters()
-{
- // Steps 10.2, 10.3
- determineTextDirection();
-
- // 10.4 If the text track cue writing direction is horizontal, then let
- // block-flow be 'tb'. Otherwise, if the text track cue writing direction is
- // vertical growing left, then let block-flow be 'lr'. Otherwise, the text
- // track cue writing direction is vertical growing right; let block-flow be
- // 'rl'.
-
- // The above step is done through the writing direction static map.
-
- // 10.5 Determine the value of maximum size for cue as per the appropriate
- // rules from the following list:
- int maximumSize = m_textPosition;
- if ((m_writingDirection == Horizontal && m_cueAlignment == Start && m_displayDirection == CSSValueLtr)
- || (m_writingDirection == Horizontal && m_cueAlignment == End && m_displayDirection == CSSValueRtl)
- || (m_writingDirection == Horizontal && m_cueAlignment == Left)
- || (m_writingDirection == VerticalGrowingLeft && (m_cueAlignment == Start || m_cueAlignment == Left))
- || (m_writingDirection == VerticalGrowingRight && (m_cueAlignment == Start || m_cueAlignment == Left))) {
- maximumSize = 100 - m_textPosition;
- } else if ((m_writingDirection == Horizontal && m_cueAlignment == End && m_displayDirection == CSSValueLtr)
- || (m_writingDirection == Horizontal && m_cueAlignment == Start && m_displayDirection == CSSValueRtl)
- || (m_writingDirection == Horizontal && m_cueAlignment == Right)
- || (m_writingDirection == VerticalGrowingLeft && (m_cueAlignment == End || m_cueAlignment == Right))
- || (m_writingDirection == VerticalGrowingRight && (m_cueAlignment == End || m_cueAlignment == Right))) {
- maximumSize = m_textPosition;
- } else if (m_cueAlignment == Middle) {
- maximumSize = m_textPosition <= 50 ? m_textPosition : (100 - m_textPosition);
- maximumSize = maximumSize * 2;
- } else
- ASSERT_NOT_REACHED();
-
- // 10.6 If the text track cue size is less than maximum size, then let size
- // be text track cue size. Otherwise, let size be maximum size.
- m_displaySize = std::min(m_cueSize, maximumSize);
-
- // FIXME: Understand why step 10.7 is missing (just a copy/paste error?)
- // Could be done within a spec implementation check - http://crbug.com/301580
-
- // 10.8 Determine the value of x-position or y-position for cue as per the
- // appropriate rules from the following list:
- if (m_writingDirection == Horizontal) {
- switch (m_cueAlignment) {
- case Start:
- if (m_displayDirection == CSSValueLtr)
- m_displayPosition.first = m_textPosition;
- else
- m_displayPosition.first = 100 - m_textPosition - m_displaySize;
- break;
- case End:
- if (m_displayDirection == CSSValueRtl)
- m_displayPosition.first = 100 - m_textPosition;
- else
- m_displayPosition.first = m_textPosition - m_displaySize;
- break;
- case Left:
- if (m_displayDirection == CSSValueLtr)
- m_displayPosition.first = m_textPosition;
- else
- m_displayPosition.first = 100 - m_textPosition;
- break;
- case Right:
- if (m_displayDirection == CSSValueLtr)
- m_displayPosition.first = m_textPosition - m_displaySize;
- else
- m_displayPosition.first = 100 - m_textPosition - m_displaySize;
- break;
- case Middle:
- if (m_displayDirection == CSSValueLtr)
- m_displayPosition.first = m_textPosition - m_displaySize / 2;
- else
- m_displayPosition.first = 100 - m_textPosition - m_displaySize / 2;
- break;
- case NumberOfAlignments:
- ASSERT_NOT_REACHED();
- }
- }
-
- // A text track cue has a text track cue computed line position whose value
- // is defined in terms of the other aspects of the cue.
- m_computedLinePosition = calculateComputedLinePosition();
-
- // 10.9 Determine the value of whichever of x-position or y-position is not
- // yet calculated for cue as per the appropriate rules from the following
- // list:
- if (m_snapToLines && m_displayPosition.second == undefinedPosition && m_writingDirection == Horizontal)
- m_displayPosition.second = 0;
-
- if (!m_snapToLines && m_displayPosition.second == undefinedPosition && m_writingDirection == Horizontal)
- m_displayPosition.second = m_computedLinePosition;
-
- if (m_snapToLines && m_displayPosition.first == undefinedPosition
- && (m_writingDirection == VerticalGrowingLeft || m_writingDirection == VerticalGrowingRight))
- m_displayPosition.first = 0;
-
- if (!m_snapToLines && (m_writingDirection == VerticalGrowingLeft || m_writingDirection == VerticalGrowingRight))
- m_displayPosition.first = m_computedLinePosition;
-}
-
-void VTTCue::markFutureAndPastNodes(ContainerNode* root, const MediaTime& previousTimestamp, const MediaTime& movieTime)
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, timestampTag, (ASCIILiteral("timestamp")));
-
- bool isPastNode = true;
- MediaTime currentTimestamp = previousTimestamp;
- if (currentTimestamp > movieTime)
- isPastNode = false;
-
- for (Node* child = root->firstChild(); child; child = NodeTraversal::next(*child, root)) {
- if (child->nodeName() == timestampTag) {
- MediaTime currentTimestamp;
- bool check = WebVTTParser::collectTimeStamp(child->nodeValue(), currentTimestamp);
- ASSERT_UNUSED(check, check);
-
- currentTimestamp += m_originalStartTime;
- if (currentTimestamp > movieTime)
- isPastNode = false;
- }
-
- if (is<WebVTTElement>(*child)) {
- downcast<WebVTTElement>(*child).setIsPastNode(isPastNode);
- // Make an elemenet id match a cue id for style matching purposes.
- if (!id().isEmpty())
- downcast<WebVTTElement>(*child).setIdAttribute(id());
- }
- }
-}
-
-void VTTCue::updateDisplayTree(const MediaTime& movieTime)
-{
- // The display tree may contain WebVTT timestamp objects representing
- // timestamps (processing instructions), along with displayable nodes.
-
- if (!track()->isRendered())
- return;
-
- // Clear the contents of the set.
- m_cueHighlightBox->removeChildren();
-
- // Update the two sets containing past and future WebVTT objects.
- RefPtr<DocumentFragment> referenceTree = createCueRenderingTree();
- if (!referenceTree)
- return;
-
- markFutureAndPastNodes(referenceTree.get(), startMediaTime(), movieTime);
- m_cueHighlightBox->appendChild(referenceTree);
-}
-
-VTTCueBox* VTTCue::getDisplayTree(const IntSize& videoSize, int fontSize)
-{
- RefPtr<VTTCueBox> displayTree = displayTreeInternal();
- if (!m_displayTreeShouldChange || !track()->isRendered())
- return displayTree.get();
-
- // 10.1 - 10.10
- calculateDisplayParameters();
-
- // 10.11. Apply the terms of the CSS specifications to nodes within the
- // following constraints, thus obtaining a set of CSS boxes positioned
- // relative to an initial containing block:
- displayTree->removeChildren();
-
- // The document tree is the tree of WebVTT Node Objects rooted at nodes.
-
- // The children of the nodes must be wrapped in an anonymous box whose
- // 'display' property has the value 'inline'. This is the WebVTT cue
- // background box.
-
- // Note: This is contained by default in m_cueHighlightBox.
- m_cueHighlightBox->setPseudo(cueShadowPseudoId());
-
- m_cueBackdropBox->setPseudo(cueBackdropShadowPseudoId());
- m_cueBackdropBox->appendChild(m_cueHighlightBox, ASSERT_NO_EXCEPTION);
- displayTree->appendChild(m_cueBackdropBox, ASSERT_NO_EXCEPTION);
-
- // FIXME(BUG 79916): Runs of children of WebVTT Ruby Objects that are not
- // WebVTT Ruby Text Objects must be wrapped in anonymous boxes whose
- // 'display' property has the value 'ruby-base'.
-
- displayTree->setFontSizeFromCaptionUserPrefs(fontSize);
- displayTree->applyCSSProperties(videoSize);
-
- m_displayTreeShouldChange = false;
-
- // 10.15. Let cue's text track cue display state have the CSS boxes in
- // boxes.
- return displayTree.get();
-}
-
-void VTTCue::removeDisplayTree()
-{
-#if ENABLE(WEBVTT_REGIONS)
- // The region needs to be informed about the cue removal.
- if (m_notifyRegion && track()) {
- if (VTTRegionList* regions = track()->regions()) {
- if (VTTRegion* region = regions->getRegionById(m_regionId))
- region->willRemoveTextTrackCueBox(m_displayTree.get());
- }
- }
-#endif
-
- if (!hasDisplayTree())
- return;
- displayTreeInternal()->remove(ASSERT_NO_EXCEPTION);
-}
-
-std::pair<double, double> VTTCue::getPositionCoordinates() const
-{
- // This method is used for setting x and y when snap to lines is not set.
- std::pair<double, double> coordinates;
-
- if (m_writingDirection == Horizontal && m_displayDirection == CSSValueLtr) {
- coordinates.first = m_textPosition;
- coordinates.second = m_computedLinePosition;
-
- return coordinates;
- }
-
- if (m_writingDirection == Horizontal && m_displayDirection == CSSValueRtl) {
- coordinates.first = 100 - m_textPosition;
- coordinates.second = m_computedLinePosition;
-
- return coordinates;
- }
-
- if (m_writingDirection == VerticalGrowingLeft) {
- coordinates.first = 100 - m_computedLinePosition;
- coordinates.second = m_textPosition;
-
- return coordinates;
- }
-
- if (m_writingDirection == VerticalGrowingRight) {
- coordinates.first = m_computedLinePosition;
- coordinates.second = m_textPosition;
-
- return coordinates;
- }
-
- ASSERT_NOT_REACHED();
-
- return coordinates;
-}
-
-VTTCue::CueSetting VTTCue::settingName(VTTScanner& input)
-{
- CueSetting parsedSetting = None;
- if (input.scan("vertical"))
- parsedSetting = Vertical;
- else if (input.scan("line"))
- parsedSetting = Line;
- else if (input.scan("position"))
- parsedSetting = Position;
- else if (input.scan("size"))
- parsedSetting = Size;
- else if (input.scan("align"))
- parsedSetting = Align;
-#if ENABLE(WEBVTT_REGIONS)
- else if (input.scan("region"))
- parsedSetting = RegionId;
-#endif
- // Verify that a ':' follows.
- if (parsedSetting != None && input.scan(':'))
- return parsedSetting;
-
- return None;
-}
-
-void VTTCue::setCueSettings(const String& inputString)
-{
- if (inputString.isEmpty())
- return;
-
- VTTScanner input(inputString);
-
- while (!input.isAtEnd()) {
-
- // The WebVTT cue settings part of a WebVTT cue consists of zero or more of the following components, in any order,
- // separated from each other by one or more U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters.
- input.skipWhile<WebVTTParser::isValidSettingDelimiter>();
- if (input.isAtEnd())
- break;
-
- // When the user agent is to parse the WebVTT settings given by a string input for a text track cue cue,
- // the user agent must run the following steps:
- // 1. Let settings be the result of splitting input on spaces.
- // 2. For each token setting in the list settings, run the following substeps:
- // 1. If setting does not contain a U+003A COLON character (:), or if the first U+003A COLON character (:)
- // in setting is either the first or last character of setting, then jump to the step labeled next setting.
- // 2. Let name be the leading substring of setting up to and excluding the first U+003A COLON character (:) in that string.
- CueSetting name = settingName(input);
-
- // 3. Let value be the trailing substring of setting starting from the character immediately after the first U+003A COLON character (:) in that string.
- VTTScanner::Run valueRun = input.collectUntil<WebVTTParser::isValidSettingDelimiter>();
-
- // 4. Run the appropriate substeps that apply for the value of name, as follows:
- switch (name) {
- case Vertical: {
- // If name is a case-sensitive match for "vertical"
- // 1. If value is a case-sensitive match for the string "rl", then let cue's text track cue writing direction
- // be vertical growing left.
- if (input.scanRun(valueRun, verticalGrowingLeftKeyword()))
- m_writingDirection = VerticalGrowingLeft;
-
- // 2. Otherwise, if value is a case-sensitive match for the string "lr", then let cue's text track cue writing
- // direction be vertical growing right.
- else if (input.scanRun(valueRun, verticalGrowingRightKeyword()))
- m_writingDirection = VerticalGrowingRight;
-
- else
- LOG(Media, "VTTCue::setCueSettings, invalid Vertical");
- break;
- }
- case Line: {
- bool isValid = false;
- do {
- // 1-2 - Collect chars that are either '-', '%', or a digit.
- // 1. If value contains any characters other than U+002D HYPHEN-MINUS characters (-), U+0025 PERCENT SIGN
- // characters (%), and characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump
- // to the step labeled next setting.
- float linePosition;
- bool isNegative;
- if (!input.scanFloat(linePosition, &isNegative))
- break;
-
- bool isPercentage = input.scan('%');
- if (!input.isAt(valueRun.end()))
- break;
-
- // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT
- // NINE (9), then jump to the step labeled next setting.
- // 3. If any character in value other than the first character is a U+002D HYPHEN-MINUS character (-), then
- // jump to the step labeled next setting.
- // 4. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%), then
- // jump to the step labeled next setting.
- // 5. If the first character in value is a U+002D HYPHEN-MINUS character (-) and the last character in value is a
- // U+0025 PERCENT SIGN character (%), then jump to the step labeled next setting.
- if (isPercentage && isNegative)
- break;
-
- // 6. Ignoring the trailing percent sign, if any, interpret value as a (potentially signed) integer, and
- // let number be that number.
- // 7. If the last character in value is a U+0025 PERCENT SIGN character (%), but number is not in the range
- // 0 ≤ number ≤ 100, then jump to the step labeled next setting.
- // 8. Let cue's text track cue line position be number.
- // 9. If the last character in value is a U+0025 PERCENT SIGN character (%), then let cue's text track cue
- // snap-to-lines flag be false. Otherwise, let it be true.
- if (isPercentage) {
- if (linePosition < 0 || linePosition > 100)
- break;
-
- // 10 - If '%' then set snap-to-lines flag to false.
- m_snapToLines = false;
- } else {
- if (linePosition - static_cast<int>(linePosition))
- break;
-
- m_snapToLines = true;
- }
-
- m_linePosition = linePosition;
- isValid = true;
- } while (0);
-
- if (!isValid)
- LOG(Media, "VTTCue::setCueSettings, invalid Line");
-
- break;
- }
- case Position: {
- float position;
- if (WebVTTParser::parseFloatPercentageValue(input, position) && input.isAt(valueRun.end()))
- m_textPosition = position;
- else
- LOG(Media, "VTTCue::setCueSettings, invalid Position");
- break;
- }
- case Size: {
- float cueSize;
- if (WebVTTParser::parseFloatPercentageValue(input, cueSize) && input.isAt(valueRun.end()))
- m_cueSize = cueSize;
- else
- LOG(Media, "VTTCue::setCueSettings, invalid Size");
- break;
- }
- case Align: {
- // 1. If value is a case-sensitive match for the string "start", then let cue's text track cue alignment be start alignment.
- if (input.scanRun(valueRun, startKeyword()))
- m_cueAlignment = Start;
-
- // 2. If value is a case-sensitive match for the string "middle", then let cue's text track cue alignment be middle alignment.
- else if (input.scanRun(valueRun, middleKeyword()))
- m_cueAlignment = Middle;
-
- // 3. If value is a case-sensitive match for the string "end", then let cue's text track cue alignment be end alignment.
- else if (input.scanRun(valueRun, endKeyword()))
- m_cueAlignment = End;
-
- // 4. If value is a case-sensitive match for the string "left", then let cue's text track cue alignment be left alignment.
- else if (input.scanRun(valueRun, leftKeyword()))
- m_cueAlignment = Left;
-
- // 5. If value is a case-sensitive match for the string "right", then let cue's text track cue alignment be right alignment.
- else if (input.scanRun(valueRun, rightKeyword()))
- m_cueAlignment = Right;
-
- else
- LOG(Media, "VTTCue::setCueSettings, invalid Align");
-
- break;
- }
-#if ENABLE(WEBVTT_REGIONS)
- case RegionId:
- m_regionId = input.extractString(valueRun);
- break;
-#endif
- case None:
- break;
- }
-
- // Make sure the entire run is consumed.
- input.skipRun(valueRun);
- }
-#if ENABLE(WEBVTT_REGIONS)
- // If cue's line position is not auto or cue's size is not 100 or cue's
- // writing direction is not horizontal, but cue's region identifier is not
- // the empty string, let cue's region identifier be the empty string.
- if (m_regionId.isEmpty())
- return;
-
- if (m_linePosition != undefinedPosition || m_cueSize != 100 || m_writingDirection != Horizontal)
- m_regionId = emptyString();
-#endif
-}
-
-CSSValueID VTTCue::getCSSAlignment() const
-{
- return displayAlignmentMap[m_cueAlignment];
-}
-
-CSSValueID VTTCue::getCSSWritingDirection() const
-{
- return m_displayDirection;
-}
-
-CSSValueID VTTCue::getCSSWritingMode() const
-{
- return displayWritingModeMap[m_writingDirection];
-}
-
-int VTTCue::getCSSSize() const
-{
- return m_displaySize;
-}
-
-std::pair<double, double> VTTCue::getCSSPosition() const
-{
- if (!m_snapToLines)
- return getPositionCoordinates();
-
- return m_displayPosition;
-}
-
-bool VTTCue::cueContentsMatch(const TextTrackCue& cue) const
-{
- const VTTCue* vttCue = toVTTCue(&cue);
- if (text() != vttCue->text())
- return false;
- if (cueSettings() != vttCue->cueSettings())
- return false;
- if (position() != vttCue->position())
- return false;
- if (line() != vttCue->line())
- return false;
- if (size() != vttCue->size())
- return false;
- if (align() != vttCue->align())
- return false;
-
- return true;
-}
-
-bool VTTCue::isEqual(const TextTrackCue& cue, TextTrackCue::CueMatchRules match) const
-{
- if (!TextTrackCue::isEqual(cue, match))
- return false;
-
- if (cue.cueType() != WebVTT)
- return false;
-
- return cueContentsMatch(cue);
-}
-
-bool VTTCue::doesExtendCue(const TextTrackCue& cue) const
-{
- if (!cueContentsMatch(cue))
- return false;
-
- return TextTrackCue::doesExtendCue(cue);
-}
-
-void VTTCue::setFontSize(int fontSize, const IntSize&, bool important)
-{
- if (!hasDisplayTree() || !fontSize)
- return;
-
- LOG(Media, "TextTrackCue::setFontSize - setting cue font size to %i", fontSize);
-
- m_displayTreeShouldChange = true;
- displayTreeInternal()->setInlineStyleProperty(CSSPropertyFontSize, fontSize, CSSPrimitiveValue::CSS_PX, important);
-}
-
-VTTCue* toVTTCue(TextTrackCue* cue)
-{
- return const_cast<VTTCue*>(toVTTCue(const_cast<const TextTrackCue*>(cue)));
-}
-
-const VTTCue* toVTTCue(const TextTrackCue* cue)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(cue->isRenderable());
- return static_cast<const VTTCue*>(cue);
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/html/track/VTTCue.h b/Source/WebCore/html/track/VTTCue.h
deleted file mode 100644
index e3243ea70..000000000
--- a/Source/WebCore/html/track/VTTCue.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2011, 2013 Google Inc. All rights reserved.
- * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef VTTCue_h
-#define VTTCue_h
-
-#if ENABLE(VIDEO_TRACK)
-
-#include "EventTarget.h"
-#include "HTMLElement.h"
-#include "TextTrackCue.h"
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class DocumentFragment;
-class HTMLDivElement;
-class HTMLSpanElement;
-class ScriptExecutionContext;
-class VTTCue;
-class VTTScanner;
-class WebVTTCueData;
-
-// ----------------------------
-
-class VTTCueBox : public HTMLElement {
-public:
- static PassRefPtr<VTTCueBox> create(Document&, VTTCue&);
-
- VTTCue* getCue() const;
- virtual void applyCSSProperties(const IntSize& videoSize);
-
- static const AtomicString& vttCueBoxShadowPseudoId();
- void setFontSizeFromCaptionUserPrefs(int fontSize) { m_fontSizeFromCaptionUserPrefs = fontSize; }
-
-protected:
- VTTCueBox(Document&, VTTCue&);
-
- virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&, const RenderTreePosition&) override final;
-
- VTTCue& m_cue;
- int m_fontSizeFromCaptionUserPrefs;
-};
-
-// ----------------------------
-
-class VTTCue : public TextTrackCue {
-public:
- static Ref<VTTCue> create(ScriptExecutionContext& context, double start, double end, const String& content)
- {
- return create(context, MediaTime::createWithDouble(start), MediaTime::createWithDouble(end), content);
- }
-
- static Ref<VTTCue> create(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, const String& content)
- {
- return adoptRef(*new VTTCue(context, start, end, content));
- }
-
- static Ref<VTTCue> create(ScriptExecutionContext&, const WebVTTCueData&);
-
- static const AtomicString& cueBackdropShadowPseudoId();
-
- virtual ~VTTCue();
-
- const String& vertical() const;
- void setVertical(const String&, ExceptionCode&);
-
- bool snapToLines() const { return m_snapToLines; }
- void setSnapToLines(bool);
-
- double line() const { return m_linePosition; }
- virtual void setLine(double, ExceptionCode&);
-
- double position() const { return m_textPosition; }
- virtual void setPosition(double, ExceptionCode&);
-
- int size() const { return m_cueSize; }
- virtual void setSize(int, ExceptionCode&);
-
- const String& align() const;
- void setAlign(const String&, ExceptionCode&);
-
- const String& text() const { return m_content; }
- void setText(const String&);
-
- const String& cueSettings() const { return m_settings; }
- void setCueSettings(const String&);
-
- PassRefPtr<DocumentFragment> getCueAsHTML();
- PassRefPtr<DocumentFragment> createCueRenderingTree();
-
-#if ENABLE(WEBVTT_REGIONS)
- const String& regionId() const { return m_regionId; }
- void setRegionId(const String&);
- void notifyRegionWhenRemovingDisplayTree(bool);
-#endif
-
- virtual void setIsActive(bool) override;
-
- bool hasDisplayTree() const { return m_displayTree; }
- VTTCueBox* getDisplayTree(const IntSize& videoSize, int fontSize);
- HTMLSpanElement* element() const { return m_cueHighlightBox.get(); }
-
- void updateDisplayTree(const MediaTime&);
- void removeDisplayTree();
- void markFutureAndPastNodes(ContainerNode*, const MediaTime&, const MediaTime&);
-
- int calculateComputedLinePosition();
- std::pair<double, double> getPositionCoordinates() const;
-
- std::pair<double, double> getCSSPosition() const;
-
- CSSValueID getCSSAlignment() const;
- int getCSSSize() const;
- CSSValueID getCSSWritingDirection() const;
- CSSValueID getCSSWritingMode() const;
-
- enum WritingDirection {
- Horizontal = 0,
- VerticalGrowingLeft,
- VerticalGrowingRight,
- NumberOfWritingDirections
- };
- WritingDirection getWritingDirection() const { return m_writingDirection; }
-
- enum CueAlignment {
- Start = 0,
- Middle,
- End,
- Left,
- Right,
- NumberOfAlignments
- };
- CueAlignment getAlignment() const { return m_cueAlignment; }
-
- virtual void setFontSize(int, const IntSize&, bool important);
-
- virtual bool isEqual(const TextTrackCue&, CueMatchRules) const override;
- virtual bool cueContentsMatch(const TextTrackCue&) const override;
- virtual bool doesExtendCue(const TextTrackCue&) const override;
-
- virtual CueType cueType() const override { return WebVTT; }
- virtual bool isRenderable() const override final { return true; }
-
- virtual void didChange() override;
-
-protected:
- VTTCue(ScriptExecutionContext&, const MediaTime& start, const MediaTime& end, const String& content);
- VTTCue(ScriptExecutionContext&, const WebVTTCueData&);
-
- virtual PassRefPtr<VTTCueBox> createDisplayTree();
- VTTCueBox* displayTreeInternal();
-
-private:
- void initialize(ScriptExecutionContext&);
- void createWebVTTNodeTree();
- void copyWebVTTNodeToDOMTree(ContainerNode* WebVTTNode, ContainerNode* root);
-
- void parseSettings(const String&);
-
- void determineTextDirection();
- void calculateDisplayParameters();
-
- enum CueSetting {
- None,
- Vertical,
- Line,
- Position,
- Size,
- Align,
-#if ENABLE(WEBVTT_REGIONS)
- RegionId
-#endif
- };
- CueSetting settingName(VTTScanner&);
-
- String m_content;
- String m_settings;
- double m_linePosition;
- double m_computedLinePosition;
- double m_textPosition;
- int m_cueSize;
-
- WritingDirection m_writingDirection;
- CueAlignment m_cueAlignment;
-#if ENABLE(WEBVTT_REGIONS)
- String m_regionId;
-#endif
-
- RefPtr<DocumentFragment> m_webVTTNodeTree;
- RefPtr<HTMLSpanElement> m_cueHighlightBox;
- RefPtr<HTMLDivElement> m_cueBackdropBox;
- RefPtr<VTTCueBox> m_displayTree;
-
- CSSValueID m_displayDirection;
- int m_displaySize;
- std::pair<float, float> m_displayPosition;
-
- MediaTime m_originalStartTime;
-
- bool m_snapToLines : 1;
- bool m_displayTreeShouldChange : 1;
- bool m_notifyRegion : 1;
-};
-
-VTTCue* toVTTCue(TextTrackCue*);
-const VTTCue* toVTTCue(const TextTrackCue*);
-
-} // namespace WebCore
-
-#endif
-#endif
diff --git a/Source/WebCore/html/track/VTTCue.idl b/Source/WebCore/html/track/VTTCue.idl
deleted file mode 100644
index 5ae89beea..000000000
--- a/Source/WebCore/html/track/VTTCue.idl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-[
- Conditional=VIDEO_TRACK,
- Constructor(unrestricted double startTime, unrestricted double endTime, DOMString text),
- ConstructorCallWith=ScriptExecutionContext,
- JSGenerateToJSObject,
- JSGenerateToNativeObject,
-] interface VTTCue : TextTrackCue {
- [SetterRaisesException] attribute DOMString vertical;
- attribute boolean snapToLines;
- [SetterRaisesException] attribute unrestricted double line;
- [SetterRaisesException] attribute unrestricted double position;
- [SetterRaisesException] attribute unrestricted double size;
- [SetterRaisesException] attribute DOMString align;
- attribute DOMString text;
- DocumentFragment getCueAsHTML();
-
-#if defined(ENABLE_WEBVTT_REGIONS) && ENABLE_WEBVTT_REGIONS
- attribute DOMString regionId;
-#endif
-};
diff --git a/Source/WebCore/html/track/VTTRegion.cpp b/Source/WebCore/html/track/VTTRegion.cpp
deleted file mode 100644
index 08e4b4f19..000000000
--- a/Source/WebCore/html/track/VTTRegion.cpp
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "VTTRegion.h"
-
-#if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS)
-
-#include "ClientRect.h"
-#include "DOMTokenList.h"
-#include "ElementChildIterator.h"
-#include "ExceptionCodePlaceholder.h"
-#include "HTMLDivElement.h"
-#include "HTMLParserIdioms.h"
-#include "Logging.h"
-#include "RenderElement.h"
-#include "VTTCue.h"
-#include "VTTScanner.h"
-#include "WebVTTParser.h"
-#include <wtf/MathExtras.h>
-
-namespace WebCore {
-
-// The following values default values are defined within the WebVTT Regions Spec.
-// https://dvcs.w3.org/hg/text-tracks/raw-file/default/608toVTT/region.html
-
-// The region occupies by default 100% of the width of the video viewport.
-static const float defaultWidth = 100;
-
-// The region has, by default, 3 lines of text.
-static const long defaultHeightInLines = 3;
-
-// The region and viewport are anchored in the bottom left corner.
-static const float defaultAnchorPointX = 0;
-static const float defaultAnchorPointY = 100;
-
-// The region doesn't have scrolling text, by default.
-static const bool defaultScroll = false;
-
-// Default region line-height (vh units)
-static const float lineHeight = 5.33;
-
-// Default scrolling animation time period (s).
-static const float scrollTime = 0.433;
-
-VTTRegion::VTTRegion(ScriptExecutionContext& context)
- : ContextDestructionObserver(&context)
- , m_id(emptyString())
- , m_width(defaultWidth)
- , m_heightInLines(defaultHeightInLines)
- , m_regionAnchor(FloatPoint(defaultAnchorPointX, defaultAnchorPointY))
- , m_viewportAnchor(FloatPoint(defaultAnchorPointX, defaultAnchorPointY))
- , m_scroll(defaultScroll)
- , m_cueContainer(nullptr)
- , m_regionDisplayTree(nullptr)
- , m_track(nullptr)
- , m_currentTop(0)
- , m_scrollTimer(*this, &VTTRegion::scrollTimerFired)
-{
-}
-
-VTTRegion::~VTTRegion()
-{
-}
-
-void VTTRegion::setTrack(TextTrack* track)
-{
- m_track = track;
-}
-
-void VTTRegion::setId(const String& id)
-{
- m_id = id;
-}
-
-void VTTRegion::setWidth(double value, ExceptionCode& ec)
-{
- if (std::isinf(value) || std::isnan(value)) {
- ec = TypeError;
- return;
- }
-
- if (value < 0 || value > 100) {
- ec = INDEX_SIZE_ERR;
- return;
- }
-
- m_width = value;
-}
-
-void VTTRegion::setHeight(long value, ExceptionCode& ec)
-{
- if (value < 0) {
- ec = INDEX_SIZE_ERR;
- return;
- }
-
- m_heightInLines = value;
-}
-
-void VTTRegion::setRegionAnchorX(double value, ExceptionCode& ec)
-{
- if (std::isinf(value) || std::isnan(value)) {
- ec = TypeError;
- return;
- }
-
- if (value < 0 || value > 100) {
- ec = INDEX_SIZE_ERR;
- return;
- }
-
- m_regionAnchor.setX(value);
-}
-
-void VTTRegion::setRegionAnchorY(double value, ExceptionCode& ec)
-{
- if (std::isinf(value) || std::isnan(value)) {
- ec = TypeError;
- return;
- }
-
- if (value < 0 || value > 100) {
- ec = INDEX_SIZE_ERR;
- return;
- }
-
- m_regionAnchor.setY(value);
-}
-
-void VTTRegion::setViewportAnchorX(double value, ExceptionCode& ec)
-{
- if (std::isinf(value) || std::isnan(value)) {
- ec = TypeError;
- return;
- }
-
- if (value < 0 || value > 100) {
- ec = INDEX_SIZE_ERR;
- return;
- }
-
- m_viewportAnchor.setX(value);
-}
-
-void VTTRegion::setViewportAnchorY(double value, ExceptionCode& ec)
-{
- if (std::isinf(value) || std::isnan(value)) {
- ec = TypeError;
- return;
- }
-
- if (value < 0 || value > 100) {
- ec = INDEX_SIZE_ERR;
- return;
- }
-
- m_viewportAnchor.setY(value);
-}
-
-const AtomicString VTTRegion::scroll() const
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, upScrollValueKeyword, ("up", AtomicString::ConstructFromLiteral));
-
- if (m_scroll)
- return upScrollValueKeyword;
-
- return "";
-}
-
-void VTTRegion::setScroll(const AtomicString& value, ExceptionCode& ec)
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, upScrollValueKeyword, ("up", AtomicString::ConstructFromLiteral));
-
- if (value != emptyString() && value != upScrollValueKeyword) {
- ec = SYNTAX_ERR;
- return;
- }
-
- m_scroll = value == upScrollValueKeyword;
-}
-
-void VTTRegion::updateParametersFromRegion(VTTRegion* region)
-{
- m_heightInLines = region->height();
- m_width = region->width();
-
- m_regionAnchor = FloatPoint(region->regionAnchorX(), region->regionAnchorY());
- m_viewportAnchor = FloatPoint(region->viewportAnchorX(), region->viewportAnchorY());
-
- setScroll(region->scroll(), ASSERT_NO_EXCEPTION);
-}
-
-void VTTRegion::setRegionSettings(const String& inputString)
-{
- m_settings = inputString;
- VTTScanner input(inputString);
-
- while (!input.isAtEnd()) {
- input.skipWhile<WebVTTParser::isValidSettingDelimiter>();
- if (input.isAtEnd())
- break;
-
- // Scan the name part.
- RegionSetting name = scanSettingName(input);
-
- // Verify that we're looking at a '='.
- if (name == None || !input.scan('=')) {
- input.skipUntil<isHTMLSpace<UChar>>();
- continue;
- }
-
- // Scan the value part.
- parseSettingValue(name, input);
- }
-}
-
-VTTRegion::RegionSetting VTTRegion::scanSettingName(VTTScanner& input)
-{
- if (input.scan("id"))
- return Id;
- if (input.scan("height"))
- return Height;
- if (input.scan("width"))
- return Width;
- if (input.scan("viewportanchor"))
- return ViewportAnchor;
- if (input.scan("regionanchor"))
- return RegionAnchor;
- if (input.scan("scroll"))
- return Scroll;
-
- return None;
-}
-
-static inline bool parsedEntireRun(const VTTScanner& input, const VTTScanner::Run& run)
-{
- return input.isAt(run.end());
-}
-
-void VTTRegion::parseSettingValue(RegionSetting setting, VTTScanner& input)
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, scrollUpValueKeyword, ("up", AtomicString::ConstructFromLiteral));
-
- VTTScanner::Run valueRun = input.collectUntil<isHTMLSpace<UChar>>();
-
- switch (setting) {
- case Id: {
- String stringValue = input.extractString(valueRun);
- if (stringValue.find("-->") == notFound)
- m_id = stringValue;
- break;
- }
- case Width: {
- float floatWidth;
- if (WebVTTParser::parseFloatPercentageValue(input, floatWidth) && parsedEntireRun(input, valueRun))
- m_width = floatWidth;
- else
- LOG(Media, "VTTRegion::parseSettingValue, invalid Width");
- break;
- }
- case Height: {
- int number;
- if (input.scanDigits(number) && parsedEntireRun(input, valueRun))
- m_heightInLines = number;
- else
- LOG(Media, "VTTRegion::parseSettingValue, invalid Height");
- break;
- }
- case RegionAnchor: {
- FloatPoint anchor;
- if (WebVTTParser::parseFloatPercentageValuePair(input, ',', anchor) && parsedEntireRun(input, valueRun))
- m_regionAnchor = anchor;
- else
- LOG(Media, "VTTRegion::parseSettingValue, invalid RegionAnchor");
- break;
- }
- case ViewportAnchor: {
- FloatPoint anchor;
- if (WebVTTParser::parseFloatPercentageValuePair(input, ',', anchor) && parsedEntireRun(input, valueRun))
- m_viewportAnchor = anchor;
- else
- LOG(Media, "VTTRegion::parseSettingValue, invalid ViewportAnchor");
- break;
- }
- case Scroll:
- if (input.scanRun(valueRun, scrollUpValueKeyword))
- m_scroll = true;
- else
- LOG(Media, "VTTRegion::parseSettingValue, invalid Scroll");
- break;
- case None:
- break;
- }
-
- input.skipRun(valueRun);
-}
-
-const AtomicString& VTTRegion::textTrackCueContainerScrollingClass()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, trackRegionCueContainerScrollingClass, ("scrolling", AtomicString::ConstructFromLiteral));
-
- return trackRegionCueContainerScrollingClass;
-}
-
-const AtomicString& VTTRegion::textTrackCueContainerShadowPseudoId()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, trackRegionCueContainerPseudoId,
- ("-webkit-media-text-track-region-container", AtomicString::ConstructFromLiteral));
-
- return trackRegionCueContainerPseudoId;
-}
-
-const AtomicString& VTTRegion::textTrackRegionShadowPseudoId()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, trackRegionShadowPseudoId,
- ("-webkit-media-text-track-region", AtomicString::ConstructFromLiteral));
-
- return trackRegionShadowPseudoId;
-}
-
-void VTTRegion::appendTextTrackCueBox(PassRefPtr<VTTCueBox> displayBox)
-{
- ASSERT(m_cueContainer);
-
- if (m_cueContainer->contains(displayBox.get()))
- return;
-
- m_cueContainer->appendChild(displayBox, ASSERT_NO_EXCEPTION);
- displayLastTextTrackCueBox();
-}
-
-void VTTRegion::displayLastTextTrackCueBox()
-{
- ASSERT(m_cueContainer);
-
- // The container needs to be rendered, if it is not empty and the region is not currently scrolling.
- if (!m_cueContainer->renderer() || !m_cueContainer->hasChildNodes() || m_scrollTimer.isActive())
- return;
-
- // If it's a scrolling region, add the scrolling class.
- if (isScrollingRegion())
- m_cueContainer->classList().add(textTrackCueContainerScrollingClass(), IGNORE_EXCEPTION);
-
- float regionBottom = m_regionDisplayTree->getBoundingClientRect()->bottom();
-
- // Find first cue that is not entirely displayed and scroll it upwards.
- for (auto& child : childrenOfType<Element>(*m_cueContainer)) {
- Ref<ClientRect> rect = child.getBoundingClientRect();
- float childTop = rect->top();
- float childBottom = rect->bottom();
-
- if (regionBottom >= childBottom)
- continue;
-
- float height = childBottom - childTop;
-
- m_currentTop -= std::min(height, childBottom - regionBottom);
- m_cueContainer->setInlineStyleProperty(CSSPropertyTop, m_currentTop, CSSPrimitiveValue::CSS_PX);
-
- startTimer();
- break;
- }
-}
-
-void VTTRegion::willRemoveTextTrackCueBox(VTTCueBox* box)
-{
- LOG(Media, "VTTRegion::willRemoveTextTrackCueBox");
- ASSERT(m_cueContainer->contains(box));
-
- double boxHeight = box->getBoundingClientRect()->bottom() - box->getBoundingClientRect()->top();
-
- m_cueContainer->classList().remove(textTrackCueContainerScrollingClass(), IGNORE_EXCEPTION);
-
- m_currentTop += boxHeight;
- m_cueContainer->setInlineStyleProperty(CSSPropertyTop, m_currentTop, CSSPrimitiveValue::CSS_PX);
-}
-
-PassRefPtr<HTMLDivElement> VTTRegion::getDisplayTree()
-{
- if (!m_regionDisplayTree) {
- m_regionDisplayTree = HTMLDivElement::create(*ownerDocument());
- prepareRegionDisplayTree();
- }
-
- return m_regionDisplayTree;
-}
-
-void VTTRegion::prepareRegionDisplayTree()
-{
- ASSERT(m_regionDisplayTree);
-
- // 7.2 Prepare region CSS boxes
-
- // FIXME: Change the code below to use viewport units when
- // http://crbug/244618 is fixed.
-
- // Let regionWidth be the text track region width.
- // Let width be 'regionWidth vw' ('vw' is a CSS unit)
- m_regionDisplayTree->setInlineStyleProperty(CSSPropertyWidth, m_width, CSSPrimitiveValue::CSS_PERCENTAGE);
-
- // Let lineHeight be '0.0533vh' ('vh' is a CSS unit) and regionHeight be
- // the text track region height. Let height be 'lineHeight' multiplied
- // by regionHeight.
- double height = lineHeight * m_heightInLines;
- m_regionDisplayTree->setInlineStyleProperty(CSSPropertyHeight, height, CSSPrimitiveValue::CSS_VH);
-
- // Let viewportAnchorX be the x dimension of the text track region viewport
- // anchor and regionAnchorX be the x dimension of the text track region
- // anchor. Let leftOffset be regionAnchorX multiplied by width divided by
- // 100.0. Let left be leftOffset subtracted from 'viewportAnchorX vw'.
- double leftOffset = m_regionAnchor.x() * m_width / 100;
- m_regionDisplayTree->setInlineStyleProperty(CSSPropertyLeft, m_viewportAnchor.x() - leftOffset, CSSPrimitiveValue::CSS_PERCENTAGE);
-
- // Let viewportAnchorY be the y dimension of the text track region viewport
- // anchor and regionAnchorY be the y dimension of the text track region
- // anchor. Let topOffset be regionAnchorY multiplied by height divided by
- // 100.0. Let top be topOffset subtracted from 'viewportAnchorY vh'.
- double topOffset = m_regionAnchor.y() * height / 100;
- m_regionDisplayTree->setInlineStyleProperty(CSSPropertyTop, m_viewportAnchor.y() - topOffset, CSSPrimitiveValue::CSS_PERCENTAGE);
-
- // The cue container is used to wrap the cues and it is the object which is
- // gradually scrolled out as multiple cues are appended to the region.
- m_cueContainer = HTMLDivElement::create(*ownerDocument());
- m_cueContainer->setInlineStyleProperty(CSSPropertyTop, 0.0f, CSSPrimitiveValue::CSS_PX);
-
- m_cueContainer->setPseudo(textTrackCueContainerShadowPseudoId());
- m_regionDisplayTree->appendChild(m_cueContainer);
-
- // 7.5 Every WebVTT region object is initialised with the following CSS
- m_regionDisplayTree->setPseudo(textTrackRegionShadowPseudoId());
-}
-
-void VTTRegion::startTimer()
-{
- LOG(Media, "VTTRegion::startTimer");
-
- if (m_scrollTimer.isActive())
- return;
-
- double duration = isScrollingRegion() ? scrollTime : 0;
- m_scrollTimer.startOneShot(duration);
-}
-
-void VTTRegion::stopTimer()
-{
- LOG(Media, "VTTRegion::stopTimer");
-
- if (m_scrollTimer.isActive())
- m_scrollTimer.stop();
-}
-
-void VTTRegion::scrollTimerFired()
-{
- LOG(Media, "VTTRegion::scrollTimerFired");
-
- stopTimer();
- displayLastTextTrackCueBox();
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/html/track/VTTRegionList.cpp b/Source/WebCore/html/track/VTTRegionList.cpp
deleted file mode 100644
index e786898b1..000000000
--- a/Source/WebCore/html/track/VTTRegionList.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "VTTRegionList.h"
-
-#if ENABLE(VIDEO_TRACK) && ENABLE(WEBVTT_REGIONS)
-
-
-namespace WebCore {
-
-VTTRegionList::VTTRegionList()
-{
-}
-
-unsigned long VTTRegionList::length() const
-{
- return m_list.size();
-}
-
-VTTRegion* VTTRegionList::item(unsigned index) const
-{
- if (index < m_list.size())
- return m_list[index].get();
-
- return 0;
-}
-
-VTTRegion* VTTRegionList::getRegionById(const String& id) const
-{
- if (id.isEmpty())
- return 0;
-
- for (const auto& region : m_list) {
- if (region->id() == id)
- return region.get();
- }
-
- return 0;
-}
-
-void VTTRegionList::add(PassRefPtr<VTTRegion> region)
-{
- m_list.append(region);
-}
-
-bool VTTRegionList::remove(VTTRegion* region)
-{
- size_t index = m_list.find(region);
- if (index == notFound)
- return false;
-
- m_list.remove(index);
- return true;
-}
-
-void VTTRegionList::clear()
-{
- m_list.clear();
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/html/track/VTTScanner.cpp b/Source/WebCore/html/track/VTTScanner.cpp
deleted file mode 100644
index 5fd4d060d..000000000
--- a/Source/WebCore/html/track/VTTScanner.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 2013, Opera Software ASA. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Opera Software ASA nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "VTTScanner.h"
-
-namespace WebCore {
-
-VTTScanner::VTTScanner(const String& line)
- : m_is8Bit(line.is8Bit())
-{
- if (m_is8Bit) {
- m_data.characters8 = line.characters8();
- m_end.characters8 = m_data.characters8 + line.length();
- } else {
- m_data.characters16 = line.characters16();
- m_end.characters16 = m_data.characters16 + line.length();
- }
-}
-
-bool VTTScanner::scan(char c)
-{
- if (!match(c))
- return false;
- advance();
- return true;
-}
-
-bool VTTScanner::scan(const LChar* characters, size_t charactersCount)
-{
- unsigned matchLength = m_is8Bit ? m_end.characters8 - m_data.characters8 : m_end.characters16 - m_data.characters16;
- if (matchLength < charactersCount)
- return false;
- bool matched;
- if (m_is8Bit)
- matched = WTF::equal(m_data.characters8, characters, charactersCount);
- else
- matched = WTF::equal(m_data.characters16, characters, charactersCount);
- if (matched)
- advance(charactersCount);
- return matched;
-}
-
-bool VTTScanner::scanRun(const Run& run, const String& toMatch)
-{
- ASSERT(run.start() == position());
- ASSERT(run.start() <= end());
- ASSERT(run.end() >= run.start());
- ASSERT(run.end() <= end());
- size_t matchLength = run.length();
- if (toMatch.length() > matchLength)
- return false;
- bool matched;
- if (m_is8Bit)
- matched = WTF::equal(toMatch.impl(), m_data.characters8, matchLength);
- else
- matched = WTF::equal(toMatch.impl(), m_data.characters16, matchLength);
- if (matched)
- seekTo(run.end());
- return matched;
-}
-
-void VTTScanner::skipRun(const Run& run)
-{
- ASSERT(run.start() <= end());
- ASSERT(run.end() >= run.start());
- ASSERT(run.end() <= end());
- seekTo(run.end());
-}
-
-String VTTScanner::extractString(const Run& run)
-{
- ASSERT(run.start() == position());
- ASSERT(run.start() <= end());
- ASSERT(run.end() >= run.start());
- ASSERT(run.end() <= end());
- String s;
- if (m_is8Bit)
- s = String(m_data.characters8, run.length());
- else
- s = String(m_data.characters16, run.length());
- seekTo(run.end());
- return s;
-}
-
-String VTTScanner::restOfInputAsString()
-{
- Run rest(position(), end(), m_is8Bit);
- return extractString(rest);
-}
-
-unsigned VTTScanner::scanDigits(int& number)
-{
- Run runOfDigits = collectWhile<isASCIIDigit>();
- if (runOfDigits.isEmpty()) {
- number = 0;
- return 0;
- }
- bool validNumber;
- size_t numDigits = runOfDigits.length();
- if (m_is8Bit)
- number = charactersToIntStrict(m_data.characters8, numDigits, &validNumber);
- else
- number = charactersToIntStrict(m_data.characters16, numDigits, &validNumber);
-
- // Since we know that scanDigits only scanned valid (ASCII) digits (and
- // hence that's what got passed to charactersToInt()), the remaining
- // failure mode for charactersToInt() is overflow, so if |validNumber| is
- // not true, then set |number| to the maximum int value.
- if (!validNumber)
- number = std::numeric_limits<int>::max();
- // Consume the digits.
- seekTo(runOfDigits.end());
- return numDigits;
-}
-
-bool VTTScanner::scanFloat(float& number, bool* isNegative)
-{
- bool negative = scan('-');
- Run integerRun = collectWhile<isASCIIDigit>();
-
- seekTo(integerRun.end());
- Run decimalRun(position(), position(), m_is8Bit);
- if (scan('.')) {
- decimalRun = collectWhile<isASCIIDigit>();
- seekTo(decimalRun.end());
- }
-
- // At least one digit required.
- if (integerRun.isEmpty() && decimalRun.isEmpty()) {
- // Restore to starting position.
- seekTo(integerRun.start());
- return false;
- }
-
- size_t lengthOfFloat = Run(integerRun.start(), position(), m_is8Bit).length();
- bool validNumber;
- if (m_is8Bit)
- number = charactersToFloat(integerRun.start(), lengthOfFloat, &validNumber);
- else
- number = charactersToFloat(reinterpret_cast<const UChar*>(integerRun.start()), lengthOfFloat, &validNumber);
-
- if (!validNumber)
- number = std::numeric_limits<float>::max();
- else if (negative)
- number = -number;
-
- if (isNegative)
- *isNegative = negative;
-
- return true;
-}
-
-}
diff --git a/Source/WebCore/html/track/VTTScanner.h b/Source/WebCore/html/track/VTTScanner.h
deleted file mode 100644
index d16439e6d..000000000
--- a/Source/WebCore/html/track/VTTScanner.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (c) 2013, Opera Software ASA. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Opera Software ASA nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef VTTScanner_h
-#define VTTScanner_h
-
-#include "ParsingUtilities.h"
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-// Helper class for "scanning" an input string and performing parsing of
-// "micro-syntax"-like constructs.
-//
-// There's two primary operations: match and scan.
-//
-// The 'match' operation matches an explicitly or implicitly specified sequence
-// against the characters ahead of the current input pointer, and returns true
-// if the sequence can be matched.
-//
-// The 'scan' operation performs a 'match', and if the match is successful it
-// advance the input pointer past the matched sequence.
-class VTTScanner {
- WTF_MAKE_NONCOPYABLE(VTTScanner);
-public:
- explicit VTTScanner(const String& line);
-
- typedef const LChar* Position;
-
- class Run {
- public:
- Run(Position start, Position end, bool is8Bit)
- : m_start(start), m_end(end), m_is8Bit(is8Bit) { }
-
- Position start() const { return m_start; }
- Position end() const { return m_end; }
-
- bool isEmpty() const { return m_start == m_end; }
- size_t length() const;
-
- private:
- Position m_start;
- Position m_end;
- bool m_is8Bit;
- };
-
- // Check if the input pointer points at the specified position.
- bool isAt(Position checkPosition) const { return position() == checkPosition; }
- // Check if the input pointer points at the end of the input.
- bool isAtEnd() const { return position() == end(); }
- // Match the character |c| against the character at the input pointer (~lookahead).
- bool match(char c) const { return !isAtEnd() && currentChar() == c; }
- // Scan the character |c|.
- bool scan(char);
- // Scan the first |charactersCount| characters of the string |characters|.
- bool scan(const LChar* characters, size_t charactersCount);
-
- // Scan the literal |characters|.
- template<unsigned charactersCount>
- bool scan(const char (&characters)[charactersCount]);
-
- // Skip (advance the input pointer) as long as the specified
- // |characterPredicate| returns true, and the input pointer is not passed
- // the end of the input.
- template<bool characterPredicate(UChar)>
- void skipWhile();
-
- // Like skipWhile, but using a negated predicate.
- template<bool characterPredicate(UChar)>
- void skipUntil();
-
- // Return the run of characters for which the specified
- // |characterPredicate| returns true. The start of the run will be the
- // current input pointer.
- template<bool characterPredicate(UChar)>
- Run collectWhile();
-
- // Like collectWhile, but using a negated predicate.
- template<bool characterPredicate(UChar)>
- Run collectUntil();
-
- // Scan the string |toMatch|, using the specified |run| as the sequence to
- // match against.
- bool scanRun(const Run&, const String& toMatch);
-
- // Skip to the end of the specified |run|.
- void skipRun(const Run&);
-
- // Return the String made up of the characters in |run|, and advance the
- // input pointer to the end of the run.
- String extractString(const Run&);
-
- // Return a String constructed from the rest of the input (between input
- // pointer and end of input), and advance the input pointer accordingly.
- String restOfInputAsString();
-
- // Scan a set of ASCII digits from the input. Return the number of digits
- // scanned, and set |number| to the computed value. If the digits make up a
- // number that does not fit the 'int' type, |number| is set to INT_MAX.
- // Note: Does not handle sign.
- unsigned scanDigits(int& number);
-
- // Scan a floating point value on one of the forms: \d+\.? \d+\.\d+ \.\d+
- bool scanFloat(float& number, bool* isNegative = nullptr);
-
-protected:
- Position position() const { return m_data.characters8; }
- Position end() const { return m_end.characters8; }
- void seekTo(Position);
- UChar currentChar() const;
- void advance(unsigned amount = 1);
- // Adapt a UChar-predicate to an LChar-predicate.
- // (For use with skipWhile/Until from ParsingUtilities.h).
- template<bool characterPredicate(UChar)>
- static inline bool LCharPredicateAdapter(LChar c) { return characterPredicate(c); }
- union {
- const LChar* characters8;
- const UChar* characters16;
- } m_data;
- union {
- const LChar* characters8;
- const UChar* characters16;
- } m_end;
- bool m_is8Bit;
-};
-
-inline size_t VTTScanner::Run::length() const
-{
- if (m_is8Bit)
- return m_end - m_start;
- return reinterpret_cast<const UChar*>(m_end) - reinterpret_cast<const UChar*>(m_start);
-}
-
-template<unsigned charactersCount>
-inline bool VTTScanner::scan(const char (&characters)[charactersCount])
-{
- return scan(reinterpret_cast<const LChar*>(characters), charactersCount - 1);
-}
-
-template<bool characterPredicate(UChar)>
-inline void VTTScanner::skipWhile()
-{
- if (m_is8Bit)
- ::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(m_data.characters8, m_end.characters8);
- else
- ::skipWhile<UChar, characterPredicate>(m_data.characters16, m_end.characters16);
-}
-
-template<bool characterPredicate(UChar)>
-inline void VTTScanner::skipUntil()
-{
- if (m_is8Bit)
- ::skipUntil<LChar, LCharPredicateAdapter<characterPredicate> >(m_data.characters8, m_end.characters8);
- else
- ::skipUntil<UChar, characterPredicate>(m_data.characters16, m_end.characters16);
-}
-
-template<bool characterPredicate(UChar)>
-inline VTTScanner::Run VTTScanner::collectWhile()
-{
- if (m_is8Bit) {
- const LChar* current = m_data.characters8;
- ::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(current, m_end.characters8);
- return Run(position(), current, m_is8Bit);
- }
- const UChar* current = m_data.characters16;
- ::skipWhile<UChar, characterPredicate>(current, m_end.characters16);
- return Run(position(), reinterpret_cast<Position>(current), m_is8Bit);
-}
-
-template<bool characterPredicate(UChar)>
-inline VTTScanner::Run VTTScanner::collectUntil()
-{
- if (m_is8Bit) {
- const LChar* current = m_data.characters8;
- ::skipUntil<LChar, LCharPredicateAdapter<characterPredicate> >(current, m_end.characters8);
- return Run(position(), current, m_is8Bit);
- }
- const UChar* current = m_data.characters16;
- ::skipUntil<UChar, characterPredicate>(current, m_end.characters16);
- return Run(position(), reinterpret_cast<Position>(current), m_is8Bit);
-}
-
-inline void VTTScanner::seekTo(Position position)
-{
- ASSERT(position <= end());
- m_data.characters8 = position;
-}
-
-inline UChar VTTScanner::currentChar() const
-{
- ASSERT(position() < end());
- return m_is8Bit ? *m_data.characters8 : *m_data.characters16;
-}
-
-inline void VTTScanner::advance(unsigned amount)
-{
- ASSERT(position() < end());
- if (m_is8Bit)
- m_data.characters8 += amount;
- else
- m_data.characters16 += amount;
-}
-
-}
-
-#endif
diff --git a/Source/WebCore/html/track/VideoTrack.cpp b/Source/WebCore/html/track/VideoTrack.cpp
index 974e49787..c0480fee2 100644
--- a/Source/WebCore/html/track/VideoTrack.cpp
+++ b/Source/WebCore/html/track/VideoTrack.cpp
@@ -47,37 +47,37 @@ namespace WebCore {
const AtomicString& VideoTrack::alternativeKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, alternative, ("alternative", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, alternative, ("alternative", AtomicString::ConstructFromLiteral));
return alternative;
}
const AtomicString& VideoTrack::captionsKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, captions, ("captions", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, captions, ("captions", AtomicString::ConstructFromLiteral));
return captions;
}
const AtomicString& VideoTrack::mainKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, captions, ("main", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, captions, ("main", AtomicString::ConstructFromLiteral));
return captions;
}
const AtomicString& VideoTrack::signKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, sign, ("sign", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, sign, ("sign", AtomicString::ConstructFromLiteral));
return sign;
}
const AtomicString& VideoTrack::subtitlesKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, subtitles, ("subtitles", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, subtitles, ("subtitles", AtomicString::ConstructFromLiteral));
return subtitles;
}
const AtomicString& VideoTrack::commentaryKeyword()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, commentary, ("commentary", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, commentary, ("commentary", AtomicString::ConstructFromLiteral));
return commentary;
}
@@ -88,7 +88,33 @@ VideoTrack::VideoTrack(VideoTrackClient* client, PassRefPtr<VideoTrackPrivate> t
, m_private(trackPrivate)
{
m_private->setClient(this);
- updateKindFromPrivate();
+
+ switch (m_private->kind()) {
+ case VideoTrackPrivate::Alternative:
+ setKindInternal(VideoTrack::alternativeKeyword());
+ break;
+ case VideoTrackPrivate::Captions:
+ setKindInternal(VideoTrack::captionsKeyword());
+ break;
+ case VideoTrackPrivate::Main:
+ setKindInternal(VideoTrack::mainKeyword());
+ break;
+ case VideoTrackPrivate::Sign:
+ setKindInternal(VideoTrack::signKeyword());
+ break;
+ case VideoTrackPrivate::Subtitles:
+ setKindInternal(VideoTrack::subtitlesKeyword());
+ break;
+ case VideoTrackPrivate::Commentary:
+ setKindInternal(VideoTrack::commentaryKeyword());
+ break;
+ case VideoTrackPrivate::None:
+ setKindInternal(emptyString());
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
}
VideoTrack::~VideoTrack()
@@ -96,22 +122,6 @@ VideoTrack::~VideoTrack()
m_private->setClient(0);
}
-void VideoTrack::setPrivate(PassRefPtr<VideoTrackPrivate> trackPrivate)
-{
- ASSERT(m_private);
- ASSERT(trackPrivate);
-
- if (m_private == trackPrivate)
- return;
-
- m_private->setClient(nullptr);
- m_private = trackPrivate;
- m_private->setClient(this);
-
- m_private->setSelected(m_selected);
- updateKindFromPrivate();
-}
-
bool VideoTrack::isValidKind(const AtomicString& value) const
{
if (value == alternativeKeyword())
@@ -154,19 +164,19 @@ void VideoTrack::selectedChanged(VideoTrackPrivate* trackPrivate, bool selected)
setSelected(selected);
}
-void VideoTrack::idChanged(TrackPrivateBase* trackPrivate, const AtomicString& id)
+void VideoTrack::idChanged(TrackPrivateBase* trackPrivate, const String& id)
{
ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
setId(id);
}
-void VideoTrack::labelChanged(TrackPrivateBase* trackPrivate, const AtomicString& label)
+void VideoTrack::labelChanged(TrackPrivateBase* trackPrivate, const String& label)
{
ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
setLabel(label);
}
-void VideoTrack::languageChanged(TrackPrivateBase* trackPrivate, const AtomicString& language)
+void VideoTrack::languageChanged(TrackPrivateBase* trackPrivate, const String& language)
{
ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
setLanguage(language);
@@ -217,41 +227,10 @@ void VideoTrack::setLanguage(const AtomicString& language)
// 4. Queue a task to fire a simple event named change at the VideoTrackList object referenced by
// the videoTracks attribute on the HTMLMediaElement.
- if (mediaElement()->videoTracks())
- mediaElement()->videoTracks()->scheduleChangeEvent();
+ mediaElement()->videoTracks()->scheduleChangeEvent();
}
#endif
-void VideoTrack::updateKindFromPrivate()
-{
- switch (m_private->kind()) {
- case VideoTrackPrivate::Alternative:
- setKindInternal(VideoTrack::alternativeKeyword());
- break;
- case VideoTrackPrivate::Captions:
- setKindInternal(VideoTrack::captionsKeyword());
- break;
- case VideoTrackPrivate::Main:
- setKindInternal(VideoTrack::mainKeyword());
- break;
- case VideoTrackPrivate::Sign:
- setKindInternal(VideoTrack::signKeyword());
- break;
- case VideoTrackPrivate::Subtitles:
- setKindInternal(VideoTrack::subtitlesKeyword());
- break;
- case VideoTrackPrivate::Commentary:
- setKindInternal(VideoTrack::commentaryKeyword());
- break;
- case VideoTrackPrivate::None:
- setKindInternal(emptyString());
- break;
- default:
- ASSERT_NOT_REACHED();
- break;
- }
-}
-
} // namespace WebCore
#endif
diff --git a/Source/WebCore/html/track/VideoTrack.h b/Source/WebCore/html/track/VideoTrack.h
index 1672daff7..6343a0743 100644
--- a/Source/WebCore/html/track/VideoTrack.h
+++ b/Source/WebCore/html/track/VideoTrack.h
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -32,6 +32,7 @@
#include "ExceptionCode.h"
#include "TrackBase.h"
#include "VideoTrackPrivate.h"
+#include <wtf/PassOwnPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
@@ -46,11 +47,11 @@ public:
virtual void videoTrackSelectedChanged(VideoTrack*) = 0;
};
-class VideoTrack final : public TrackBase, public VideoTrackPrivateClient {
+class VideoTrack : public TrackBase, public VideoTrackPrivateClient {
public:
- static Ref<VideoTrack> create(VideoTrackClient* client, PassRefPtr<VideoTrackPrivate> trackPrivate)
+ static PassRefPtr<VideoTrack> create(VideoTrackClient* client, PassRefPtr<VideoTrackPrivate> trackPrivate)
{
- return adoptRef(*new VideoTrack(client, trackPrivate));
+ return adoptRef(new VideoTrack(client, trackPrivate));
}
virtual ~VideoTrack();
@@ -77,8 +78,6 @@ public:
const MediaDescription& description() const;
- void setPrivate(PassRefPtr<VideoTrackPrivate>);
-
protected:
VideoTrack(VideoTrackClient*, PassRefPtr<VideoTrackPrivate> privateTrack);
@@ -86,15 +85,13 @@ private:
virtual bool isValidKind(const AtomicString&) const override;
virtual void selectedChanged(VideoTrackPrivate*, bool) override;
- virtual void idChanged(TrackPrivateBase*, const AtomicString&) override;
- virtual void labelChanged(TrackPrivateBase*, const AtomicString&) override;
- virtual void languageChanged(TrackPrivateBase*, const AtomicString&) override;
+ virtual void idChanged(TrackPrivateBase*, const String&) override;
+ virtual void labelChanged(TrackPrivateBase*, const String&) override;
+ virtual void languageChanged(TrackPrivateBase*, const String&) override;
virtual void willRemove(TrackPrivateBase*) override;
virtual bool enabled() const override { return selected(); }
- void updateKindFromPrivate();
-
bool m_selected;
VideoTrackClient* m_client;
diff --git a/Source/WebCore/html/track/VideoTrack.idl b/Source/WebCore/html/track/VideoTrack.idl
index e0c4d7e0c..53e0da62f 100644
--- a/Source/WebCore/html/track/VideoTrack.idl
+++ b/Source/WebCore/html/track/VideoTrack.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/html/track/VideoTrackList.cpp b/Source/WebCore/html/track/VideoTrackList.cpp
index 2cd545369..594ca1b3a 100644
--- a/Source/WebCore/html/track/VideoTrackList.cpp
+++ b/Source/WebCore/html/track/VideoTrackList.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -49,13 +49,7 @@ void VideoTrackList::append(PassRefPtr<VideoTrack> prpTrack)
// Insert tracks in the media file order.
size_t index = track->inbandTrackIndex();
- size_t insertionIndex;
- for (insertionIndex = 0; insertionIndex < m_inbandTracks.size(); ++insertionIndex) {
- VideoTrack* otherTrack = static_cast<VideoTrack*>(m_inbandTracks[insertionIndex].get());
- if (otherTrack->inbandTrackIndex() > index)
- break;
- }
- m_inbandTracks.insert(insertionIndex, track);
+ m_inbandTracks.insert(index, track);
ASSERT(!track->mediaElement() || track->mediaElement() == mediaElement());
track->setMediaElement(mediaElement());
diff --git a/Source/WebCore/html/track/VideoTrackList.h b/Source/WebCore/html/track/VideoTrackList.h
index 4d1d67e74..de7b845a1 100644
--- a/Source/WebCore/html/track/VideoTrackList.h
+++ b/Source/WebCore/html/track/VideoTrackList.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -34,13 +34,13 @@ namespace WebCore {
class VideoTrack;
-class VideoTrackList final : public TrackListBase {
+class VideoTrackList : public TrackListBase {
public:
- static Ref<VideoTrackList> create(HTMLMediaElement* owner, ScriptExecutionContext* context)
+ static PassRefPtr<VideoTrackList> create(HTMLMediaElement* owner, ScriptExecutionContext* context)
{
- return adoptRef(*new VideoTrackList(owner, context));
+ return adoptRef(new VideoTrackList(owner, context));
}
- virtual ~VideoTrackList();
+ ~VideoTrackList();
VideoTrack* getTrackById(const AtomicString&) const;
long selectedIndex() const;
diff --git a/Source/WebCore/html/track/VideoTrackList.idl b/Source/WebCore/html/track/VideoTrackList.idl
index a91f778ac..1058bd97b 100644
--- a/Source/WebCore/html/track/VideoTrackList.idl
+++ b/Source/WebCore/html/track/VideoTrackList.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -33,14 +33,17 @@
readonly attribute unsigned long length;
getter VideoTrack item(unsigned long index);
VideoTrack getTrackById(DOMString id);
- readonly attribute long selectedIndex;
- attribute EventHandler onchange;
- attribute EventHandler onaddtrack;
- attribute EventHandler onremovetrack;
+ attribute EventListener onchange;
+ attribute EventListener onaddtrack;
+ attribute EventListener onremovetrack;
- void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
- void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
- [RaisesException] boolean dispatchEvent(Event event);
+ void addEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ void removeEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ [RaisesException] boolean dispatchEvent(Event evt);
};
diff --git a/Source/WebCore/html/track/WebVTTElement.cpp b/Source/WebCore/html/track/WebVTTElement.cpp
index 4a2f31b3e..6a76d6078 100644
--- a/Source/WebCore/html/track/WebVTTElement.cpp
+++ b/Source/WebCore/html/track/WebVTTElement.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -36,14 +36,14 @@ namespace WebCore {
static const QualifiedName& nodeTypeToTagName(WebVTTNodeType nodeType)
{
- DEPRECATED_DEFINE_STATIC_LOCAL(QualifiedName, cTag, (nullAtom, "c", nullAtom));
- DEPRECATED_DEFINE_STATIC_LOCAL(QualifiedName, vTag, (nullAtom, "v", nullAtom));
- DEPRECATED_DEFINE_STATIC_LOCAL(QualifiedName, langTag, (nullAtom, "lang", nullAtom));
- DEPRECATED_DEFINE_STATIC_LOCAL(QualifiedName, bTag, (nullAtom, "b", nullAtom));
- DEPRECATED_DEFINE_STATIC_LOCAL(QualifiedName, uTag, (nullAtom, "u", nullAtom));
- DEPRECATED_DEFINE_STATIC_LOCAL(QualifiedName, iTag, (nullAtom, "i", nullAtom));
- DEPRECATED_DEFINE_STATIC_LOCAL(QualifiedName, rubyTag, (nullAtom, "ruby", nullAtom));
- DEPRECATED_DEFINE_STATIC_LOCAL(QualifiedName, rtTag, (nullAtom, "rt", nullAtom));
+ DEFINE_STATIC_LOCAL(QualifiedName, cTag, (nullAtom, "c", nullAtom));
+ DEFINE_STATIC_LOCAL(QualifiedName, vTag, (nullAtom, "v", nullAtom));
+ DEFINE_STATIC_LOCAL(QualifiedName, langTag, (nullAtom, "lang", nullAtom));
+ DEFINE_STATIC_LOCAL(QualifiedName, bTag, (nullAtom, "b", nullAtom));
+ DEFINE_STATIC_LOCAL(QualifiedName, uTag, (nullAtom, "u", nullAtom));
+ DEFINE_STATIC_LOCAL(QualifiedName, iTag, (nullAtom, "i", nullAtom));
+ DEFINE_STATIC_LOCAL(QualifiedName, rubyTag, (nullAtom, "ruby", nullAtom));
+ DEFINE_STATIC_LOCAL(QualifiedName, rtTag, (nullAtom, "rt", nullAtom));
switch (nodeType) {
case WebVTTNodeTypeClass:
return cTag;
@@ -75,14 +75,14 @@ WebVTTElement::WebVTTElement(WebVTTNodeType nodeType, Document& document)
{
}
-Ref<WebVTTElement> WebVTTElement::create(WebVTTNodeType nodeType, Document& document)
+PassRefPtr<WebVTTElement> WebVTTElement::create(WebVTTNodeType nodeType, Document& document)
{
- return adoptRef(*new WebVTTElement(nodeType, document));
+ return adoptRef(new WebVTTElement(nodeType, document));
}
-RefPtr<Element> WebVTTElement::cloneElementWithoutAttributesAndChildren(Document& targetDocument)
+PassRefPtr<Element> WebVTTElement::cloneElementWithoutAttributesAndChildren()
{
- RefPtr<WebVTTElement> clone = create(static_cast<WebVTTNodeType>(m_webVTTNodeType), targetDocument);
+ RefPtr<WebVTTElement> clone = create(static_cast<WebVTTNodeType>(m_webVTTNodeType), document());
clone->setLanguage(m_language);
return clone;
}
diff --git a/Source/WebCore/html/track/WebVTTElement.h b/Source/WebCore/html/track/WebVTTElement.h
index 1be7636c3..f49412c26 100644
--- a/Source/WebCore/html/track/WebVTTElement.h
+++ b/Source/WebCore/html/track/WebVTTElement.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -23,9 +23,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebVTTElement_h
-#define WebVTTElement_h
-
#if ENABLE(VIDEO_TRACK)
#include "HTMLElement.h"
@@ -46,10 +43,10 @@ enum WebVTTNodeType {
class WebVTTElement final : public Element {
public:
- static Ref<WebVTTElement> create(const WebVTTNodeType, Document&);
+ static PassRefPtr<WebVTTElement> create(const WebVTTNodeType, Document&);
PassRefPtr<HTMLElement> createEquivalentHTMLElement(Document&);
- virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren(Document&) override;
+ virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() override;
void setWebVTTNodeType(WebVTTNodeType type) { m_webVTTNodeType = static_cast<unsigned>(type); }
WebVTTNodeType webVTTNodeType() const { return static_cast<WebVTTNodeType>(m_webVTTNodeType); }
@@ -62,13 +59,13 @@ public:
static const QualifiedName& voiceAttributeName()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(QualifiedName, voiceAttr, (nullAtom, "voice", nullAtom));
+ DEFINE_STATIC_LOCAL(QualifiedName, voiceAttr, (nullAtom, "voice", nullAtom));
return voiceAttr;
}
static const QualifiedName& langAttributeName()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(QualifiedName, voiceAttr, (nullAtom, "lang", nullAtom));
+ DEFINE_STATIC_LOCAL(QualifiedName, voiceAttr, (nullAtom, "lang", nullAtom));
return voiceAttr;
}
@@ -83,12 +80,10 @@ private:
AtomicString m_language;
};
-} // namespace WebCore
+void isWebVTTElement(const WebVTTElement&); // Catch unnecessary runtime check of type known at compile time.
+inline bool isWebVTTElement(const Node& node) { return node.isWebVTTElement(); }
+NODE_TYPE_CASTS(WebVTTElement)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WebVTTElement)
- static bool isType(const WebCore::Node& node) { return node.isWebVTTElement(); }
-SPECIALIZE_TYPE_TRAITS_END()
+} // namespace WebCore
#endif
-
-#endif // WebVTTElement_h
diff --git a/Source/WebCore/html/track/WebVTTParser.cpp b/Source/WebCore/html/track/WebVTTParser.cpp
index 7ff7565e3..48d729fb6 100644
--- a/Source/WebCore/html/track/WebVTTParser.cpp
+++ b/Source/WebCore/html/track/WebVTTParser.cpp
@@ -1,7 +1,6 @@
/*
- * Copyright (C) 2011, 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2013 Cable Television Labs, Inc.
- * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -36,11 +35,8 @@
#include "WebVTTParser.h"
-#include "HTMLParserIdioms.h"
-#include "ISOVTTCue.h"
#include "ProcessingInstruction.h"
#include "Text.h"
-#include "VTTScanner.h"
#include "WebVTTElement.h"
namespace WebCore {
@@ -48,48 +44,83 @@ namespace WebCore {
const double secondsPerHour = 3600;
const double secondsPerMinute = 60;
const double secondsPerMillisecond = 0.001;
+const double malformedTime = -1;
+const UChar bom = 0xFEFF;
const char* fileIdentifier = "WEBVTT";
const unsigned fileIdentifierLength = 6;
-bool WebVTTParser::parseFloatPercentageValue(VTTScanner& valueScanner, float& percentage)
+String WebVTTParser::collectDigits(const String& input, unsigned* position)
+{
+ StringBuilder digits;
+ while (*position < input.length() && isASCIIDigit(input[*position]))
+ digits.append(input[(*position)++]);
+ return digits.toString();
+}
+
+String WebVTTParser::collectWord(const String& input, unsigned* position)
+{
+ StringBuilder string;
+ while (*position < input.length() && !isASpace(input[*position]))
+ string.append(input[(*position)++]);
+ return string.toString();
+}
+
+#if ENABLE(WEBVTT_REGIONS)
+float WebVTTParser::parseFloatPercentageValue(const String& value, bool& isValidSetting)
{
- float number;
- if (!valueScanner.scanFloat(number))
- return false;
// '%' must be present and at the end of the setting value.
- if (!valueScanner.scan('%'))
- return false;
+ if (value.find('%', 1) != value.length() - 1) {
+ isValidSetting = false;
+ return 0;
+ }
- if (number < 0 || number > 100)
- return false;
+ unsigned position = 0;
- percentage = number;
- return true;
+ StringBuilder floatNumberAsString;
+ floatNumberAsString.append(WebVTTParser::collectDigits(value, &position));
+
+ if (value[position] == '.') {
+ floatNumberAsString.append(".");
+ position++;
+
+ floatNumberAsString.append(WebVTTParser::collectDigits(value, &position));
+ }
+ float number = floatNumberAsString.toString().toFloat(&isValidSetting);
+
+ if (isValidSetting && (number <= 0 || number >= 100))
+ isValidSetting = false;
+
+ return number;
}
-#if ENABLE(WEBVTT_REGIONS)
-bool WebVTTParser::parseFloatPercentageValuePair(VTTScanner& valueScanner, char delimiter, FloatPoint& valuePair)
+FloatPoint WebVTTParser::parseFloatPercentageValuePair(const String& value, char delimiter, bool& isValidSetting)
{
- float firstCoord;
- if (!parseFloatPercentageValue(valueScanner, firstCoord))
- return false;
+ // The delimiter can't be the first or second value because a pair of
+ // percentages (x%,y%) implies that at least the first two characters
+ // are the first percentage value.
+ size_t delimiterOffset = value.find(delimiter, 2);
+ if (delimiterOffset == notFound || delimiterOffset == value.length() - 1) {
+ isValidSetting = false;
+ return FloatPoint(0, 0);
+ }
- if (!valueScanner.scan(delimiter))
- return false;
+ bool isFirstValueValid;
+ float firstCoord = parseFloatPercentageValue(value.substring(0, delimiterOffset), isFirstValueValid);
- float secondCoord;
- if (!parseFloatPercentageValue(valueScanner, secondCoord))
- return false;
+ bool isSecondValueValid;
+ float secondCoord = parseFloatPercentageValue(value.substring(delimiterOffset + 1, value.length() - 1), isSecondValueValid);
- valuePair = FloatPoint(firstCoord, secondCoord);
- return true;
+ isValidSetting = isFirstValueValid && isSecondValueValid;
+ return FloatPoint(firstCoord, secondCoord);
}
#endif
WebVTTParser::WebVTTParser(WebVTTParserClient* client, ScriptExecutionContext* context)
: m_scriptExecutionContext(context)
, m_state(Initial)
- , m_decoder(TextResourceDecoder::create("text/plain", UTF8Encoding()))
+ , m_currentStartTime(0)
+ , m_currentEndTime(0)
+ , m_tokenizer(WebVTTTokenizer::create())
, m_client(client)
{
}
@@ -101,70 +132,30 @@ void WebVTTParser::getNewCues(Vector<RefPtr<WebVTTCueData>>& outputCues)
}
#if ENABLE(WEBVTT_REGIONS)
-void WebVTTParser::getNewRegions(Vector<RefPtr<VTTRegion>>& outputRegions)
+void WebVTTParser::getNewRegions(Vector<RefPtr<TextTrackRegion>>& outputRegions)
{
outputRegions = m_regionList;
m_regionList.clear();
}
#endif
-void WebVTTParser::parseFileHeader(const String& data)
-{
- m_state = Initial;
- m_lineReader.reset();
- m_lineReader.append(data);
- parse();
-}
-
void WebVTTParser::parseBytes(const char* data, unsigned length)
{
- String textData = m_decoder->decode(data, length);
- m_lineReader.append(textData);
- parse();
-}
-
-void WebVTTParser::parseCueData(const ISOWebVTTCue& data)
-{
- RefPtr<WebVTTCueData> cue = WebVTTCueData::create();
-
- MediaTime startTime = data.presentationTime();
- cue->setStartTime(startTime);
- cue->setEndTime(startTime + data.duration());
-
- cue->setContent(data.cueText());
- cue->setId(data.id());
- cue->setSettings(data.settings());
-
- MediaTime originalStartTime;
- if (WebVTTParser::collectTimeStamp(data.originalStartTime(), originalStartTime))
- cue->setOriginalStartTime(originalStartTime);
-
- m_cuelist.append(cue);
- if (m_client)
- m_client->newCuesParsed();
-}
-
-void WebVTTParser::flush()
-{
- String textData = m_decoder->flush();
- m_lineReader.append(textData);
- m_lineReader.setEndOfStream();
- parse();
- flushPendingCue();
-}
-
-void WebVTTParser::parse()
-{
- // WebVTT parser algorithm. (5.1 WebVTT file parsing.)
- // Steps 1 - 3 - Initial setup.
- String line;
- while (m_lineReader.getLine(line)) {
- if (line.isNull())
+ // 4.8.10.13.3 WHATWG WebVTT Parser algorithm.
+ // 1-3 - Initial setup.
+ unsigned position = 0;
+
+ while (position < length) {
+ String line = collectNextLine(data, length, &position);
+ if (line.isNull()) {
+ m_buffer.append(data + position, length - position);
return;
+ }
switch (m_state) {
case Initial:
- // Steps 4 - 9 - Check for a valid WebVTT signature.
+
+ // 4-12 - Collect the first line and check for "WEBVTT".
if (!hasRequiredFileIdentifier(line)) {
if (m_client)
m_client->fileFailedToParse();
@@ -175,54 +166,47 @@ void WebVTTParser::parse()
break;
case Header:
- collectMetadataHeader(line);
-
- if (line.isEmpty()) {
+ // 13-18 - Allow a header (comment area) under the WEBVTT line.
#if ENABLE(WEBVTT_REGIONS)
- // Steps 10-14 - Allow a header (comment area) under the WEBVTT line.
+ if (line.isEmpty()) {
if (m_client && m_regionList.size())
m_client->newRegionsParsed();
-#endif
+
m_state = Id;
break;
}
- // Step 15 - Break out of header loop if the line could be a timestamp line.
- if (line.contains("-->"))
- m_state = recoverCue(line);
+ collectHeader(line);
- // Step 16 - Line is not the empty string and does not contain "-->".
+ break;
+
+ case Metadata:
+#endif
+ if (line.isEmpty())
+ m_state = Id;
break;
case Id:
- // Steps 17 - 20 - Allow any number of line terminators, then initialize new cue values.
+ // 19-29 - Allow any number of line terminators, then initialize new cue values.
if (line.isEmpty())
break;
-
- // Step 21 - Cue creation (start a new cue).
resetCueValues();
- // Steps 22 - 25 - Check if this line contains an optional identifier or timing data.
+ // 30-39 - Check if this line contains an optional identifier or timing data.
m_state = collectCueId(line);
break;
case TimingsAndSettings:
- // Steps 26 - 27 - Discard current cue if the line is empty.
- if (line.isEmpty()) {
- m_state = Id;
- break;
- }
-
- // Steps 28 - 29 - Collect cue timings and settings.
+ // 40 - Collect cue timings and settings.
m_state = collectTimingsAndSettings(line);
break;
case CueText:
- // Steps 31 - 41 - Collect the cue text, create a cue, and add it to the output.
+ // 41-53 - Collect the cue text, create a cue, and add it to the output.
m_state = collectCueText(line);
break;
case BadCue:
- // Steps 42 - 48 - Discard lines until an empty line or a potential timing line is seen.
+ // 54-62 - Collect and discard the remaining cue.
m_state = ignoreBadCue(line);
break;
@@ -240,55 +224,55 @@ void WebVTTParser::fileFinished()
m_state = Finished;
}
-void WebVTTParser::flushPendingCue()
-{
- ASSERT(m_lineReader.isAtEndOfStream());
- // If we're in the CueText state when we run out of data, we emit the pending cue.
- if (m_state == CueText)
- createNewCue();
-}
-
bool WebVTTParser::hasRequiredFileIdentifier(const String& line)
{
// A WebVTT file identifier consists of an optional BOM character,
// the string "WEBVTT" followed by an optional space or tab character,
// and any number of characters that are not line terminators ...
+ unsigned linePos = 0;
+
if (line.isEmpty())
return false;
- if (!line.startsWith(fileIdentifier, fileIdentifierLength))
+ if (line[0] == bom)
+ ++linePos;
+
+ if (line.length() < fileIdentifierLength + linePos)
return false;
- if (line.length() > fileIdentifierLength && !isHTMLSpace(line[fileIdentifierLength]))
+ for (unsigned i = 0; i < fileIdentifierLength; ++i, ++linePos) {
+ if (line[linePos] != fileIdentifier[i])
+ return false;
+ }
+
+ if (linePos < line.length() && line[linePos] != ' ' && line[linePos] != '\t')
return false;
return true;
}
-void WebVTTParser::collectMetadataHeader(const String& line)
-{
#if ENABLE(WEBVTT_REGIONS)
- // WebVTT header parsing (WebVTT parser algorithm step 12)
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, regionHeaderName, ("Region", AtomicString::ConstructFromLiteral));
+void WebVTTParser::collectHeader(const String& line)
+{
+ // 4.1 Extension of WebVTT header parsing (11 - 15)
+ DEFINE_STATIC_LOCAL(const AtomicString, regionHeaderName, ("Region", AtomicString::ConstructFromLiteral));
- // Step 12.4 If line contains the character ":" (A U+003A COLON), then set metadata's
+ // 15.4 If line contains the character ":" (A U+003A COLON), then set metadata's
// name to the substring of line before the first ":" character and
// metadata's value to the substring after this character.
- size_t colonPosition = line.find(':');
- if (colonPosition == notFound)
+ if (!line.contains(":"))
return;
- String headerName = line.substring(0, colonPosition);
+ unsigned colonPosition = line.find(":");
+ m_currentHeaderName = line.substring(0, colonPosition);
- // Step 12.5 If metadata's name equals "Region":
- if (headerName == regionHeaderName) {
- String headerValue = line.substring(colonPosition + 1, line.length() - 1);
- // Steps 12.5.1 - 12.5.11 Region creation: Let region be a new text track region [...]
- createNewRegion(headerValue);
+ // 15.5 If metadata's name equals "Region":
+ if (m_currentHeaderName == regionHeaderName) {
+ m_currentHeaderValue = line.substring(colonPosition + 1, line.length() - 1);
+ // 15.5.1 - 15.5.8 Region creation: Let region be a new text track region [...]
+ createNewRegion();
}
-#else
- UNUSED_PARAM(line);
-#endif
}
+#endif
WebVTTParser::ParseState WebVTTParser::collectCueId(const String& line)
{
@@ -300,126 +284,97 @@ WebVTTParser::ParseState WebVTTParser::collectCueId(const String& line)
WebVTTParser::ParseState WebVTTParser::collectTimingsAndSettings(const String& line)
{
- if (line.isEmpty())
+ // 4.8.10.13.3 Collect WebVTT cue timings and settings.
+ // 1-3 - Let input be the string being parsed and position be a pointer into input
+ unsigned position = 0;
+ skipWhiteSpace(line, &position);
+
+ // 4-5 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue start time be the collected time.
+ m_currentStartTime = collectTimeStamp(line, &position);
+ if (m_currentStartTime == malformedTime)
return BadCue;
-
- VTTScanner input(line);
-
- // Collect WebVTT cue timings and settings. (5.3 WebVTT cue timings and settings parsing.)
- // Steps 1 - 3 - Let input be the string being parsed and position be a pointer into input
- input.skipWhile<isHTMLSpace<UChar>>();
-
- // Steps 4 - 5 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue start time be the collected time.
- if (!collectTimeStamp(input, m_currentStartTime))
+ if (position >= line.length())
return BadCue;
-
- input.skipWhile<isHTMLSpace<UChar>>();
-
- // Steps 6 - 9 - If the next three characters are not "-->", abort and return failure.
- if (!input.scan("-->"))
+ char nextChar = line[position++];
+ if (nextChar != ' ' && nextChar != '\t')
return BadCue;
-
- input.skipWhile<isHTMLSpace<UChar>>();
+ skipWhiteSpace(line, &position);
- // Steps 10 - 11 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue end time be the collected time.
- if (!collectTimeStamp(input, m_currentEndTime))
+ // 6-9 - If the next three characters are not "-->", abort and return failure.
+ if (line.find("-->", position) == notFound)
return BadCue;
+ position += 3;
+ if (position >= line.length())
+ return BadCue;
+ nextChar = line[position++];
+ if (nextChar != ' ' && nextChar != '\t')
+ return BadCue;
+ skipWhiteSpace(line, &position);
- input.skipWhile<isHTMLSpace<UChar>>();
+ // 10-11 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue end time be the collected time.
+ m_currentEndTime = collectTimeStamp(line, &position);
+ if (m_currentEndTime == malformedTime)
+ return BadCue;
+ skipWhiteSpace(line, &position);
- // Step 12 - Parse the WebVTT settings for the cue (conducted in TextTrackCue).
- m_currentSettings = input.restOfInputAsString();
+ // 12 - Parse the WebVTT settings for the cue (conducted in TextTrackCue).
+ m_currentSettings = line.substring(position, line.length()-1);
return CueText;
}
WebVTTParser::ParseState WebVTTParser::collectCueText(const String& line)
{
- // Step 34.
if (line.isEmpty()) {
createNewCue();
return Id;
}
- // Step 35.
- if (line.contains("-->")) {
- // Step 39-40.
- createNewCue();
-
- // Step 41 - New iteration of the cue loop.
- return recoverCue(line);
- }
if (!m_currentContent.isEmpty())
- m_currentContent.append('\n');
+ m_currentContent.append("\n");
m_currentContent.append(line);
-
+
return CueText;
}
-WebVTTParser::ParseState WebVTTParser::recoverCue(const String& line)
-{
- // Step 17 and 21.
- resetCueValues();
-
- // Step 22.
- return collectTimingsAndSettings(line);
-}
-
WebVTTParser::ParseState WebVTTParser::ignoreBadCue(const String& line)
{
- if (line.isEmpty())
- return Id;
- if (line.contains("-->"))
- return recoverCue(line);
- return BadCue;
+ if (!line.isEmpty())
+ return BadCue;
+ return Id;
}
-// A helper class for the construction of a "cue fragment" from the cue text.
-class WebVTTTreeBuilder {
-public:
- WebVTTTreeBuilder(Document& document)
- : m_document(document) { }
-
- PassRefPtr<DocumentFragment> buildFromString(const String& cueText);
-
-private:
- void constructTreeFromToken(Document&);
-
- WebVTTToken m_token;
- RefPtr<ContainerNode> m_currentNode;
- Vector<AtomicString> m_languageStack;
- Document& m_document;
-};
-
-PassRefPtr<DocumentFragment> WebVTTTreeBuilder::buildFromString(const String& cueText)
+PassRefPtr<DocumentFragment> WebVTTParser::createDocumentFragmentFromCueText(const String& text)
{
// Cue text processing based on
- // 5.4 WebVTT cue text parsing rules, and
- // 5.5 WebVTT cue text DOM construction rules.
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document);
+ // 4.8.10.13.4 WebVTT cue text parsing rules and
+ // 4.8.10.13.5 WebVTT cue text DOM construction rules.
+
+ ASSERT(m_scriptExecutionContext->isDocument());
+ Document* document = toDocument(m_scriptExecutionContext);
+
+ RefPtr<DocumentFragment> fragment = DocumentFragment::create(*document);
- if (cueText.isEmpty()) {
- fragment->parserAppendChild(Text::create(m_document, emptyString()));
+ if (text.isEmpty()) {
+ fragment->parserAppendChild(Text::create(*document, emptyString()));
return fragment.release();
}
m_currentNode = fragment;
-
- WebVTTTokenizer tokenizer(cueText);
+ m_tokenizer->reset();
+ m_token.clear();
+
m_languageStack.clear();
-
- while (tokenizer.nextToken(m_token))
- constructTreeFromToken(m_document);
+ SegmentedString content(text);
+ while (m_tokenizer->nextToken(content, m_token))
+ constructTreeFromToken(document);
return fragment.release();
}
-PassRefPtr<DocumentFragment> WebVTTParser::createDocumentFragmentFromCueText(Document& document, const String& cueText)
-{
- WebVTTTreeBuilder treeBuilder(document);
- return treeBuilder.buildFromString(cueText);
-}
-
void WebVTTParser::createNewCue()
{
+ if (!m_currentContent.length())
+ return;
+
RefPtr<WebVTTCueData> cue = WebVTTCueData::create();
cue->setStartTime(m_currentStartTime);
cue->setEndTime(m_currentEndTime);
@@ -436,22 +391,21 @@ void WebVTTParser::resetCueValues()
{
m_currentId = emptyString();
m_currentSettings = emptyString();
- m_currentStartTime = MediaTime::zeroTime();
- m_currentEndTime = MediaTime::zeroTime();
+ m_currentStartTime = 0;
+ m_currentEndTime = 0;
m_currentContent.clear();
}
#if ENABLE(WEBVTT_REGIONS)
-void WebVTTParser::createNewRegion(const String& headerValue)
+void WebVTTParser::createNewRegion()
{
- if (headerValue.isEmpty())
+ if (!m_currentHeaderValue.length())
return;
- // Steps 12.5.1 - 12.5.9 - Construct and initialize a WebVTT Region object.
- RefPtr<VTTRegion> region = VTTRegion::create(*m_scriptExecutionContext);
- region->setRegionSettings(headerValue);
+ RefPtr<TextTrackRegion> region = TextTrackRegion::create();
+ region->setRegionSettings(m_currentHeaderValue);
- // Step 12.5.10 If the text track list of regions regions contains a region
+ // 15.5.10 If the text track list of regions regions contains a region
// with the same region identifier value as region, remove that region.
for (size_t i = 0; i < m_regionList.size(); ++i)
if (m_regionList[i]->id() == region->id()) {
@@ -459,67 +413,73 @@ void WebVTTParser::createNewRegion(const String& headerValue)
break;
}
- // Step 12.5.11
m_regionList.append(region);
}
#endif
-bool WebVTTParser::collectTimeStamp(const String& line, MediaTime& timeStamp)
-{
- if (line.isEmpty())
- return false;
-
- VTTScanner input(line);
- return collectTimeStamp(input, timeStamp);
-}
-
-bool WebVTTParser::collectTimeStamp(VTTScanner& input, MediaTime& timeStamp)
+double WebVTTParser::collectTimeStamp(const String& line, unsigned* position)
{
- // Collect a WebVTT timestamp (5.3 WebVTT cue timings and settings parsing.)
- // Steps 1 - 4 - Initial checks, let most significant units be minutes.
+ // 4.8.10.13.3 Collect a WebVTT timestamp.
+ // 1-4 - Initial checks, let most significant units be minutes.
enum Mode { minutes, hours };
Mode mode = minutes;
+ if (*position >= line.length() || !isASCIIDigit(line[*position]))
+ return malformedTime;
- // Steps 5 - 7 - Collect a sequence of characters that are 0-9.
- // If not 2 characters or value is greater than 59, interpret as hours.
- int value1;
- unsigned value1Digits = input.scanDigits(value1);
- if (!value1Digits)
- return false;
- if (value1Digits != 2 || value1 > 59)
- mode = hours;
+ // 5-6 - Collect a sequence of characters that are 0-9.
+ String digits1 = collectDigits(line, position);
+ int value1 = digits1.toInt();
- // Steps 8 - 11 - Collect the next sequence of 0-9 after ':' (must be 2 chars).
- int value2;
- if (!input.scan(':') || input.scanDigits(value2) != 2)
- return false;
+ // 7 - If not 2 characters or value is greater than 59, interpret as hours.
+ if (digits1.length() != 2 || value1 > 59)
+ mode = hours;
- // Step 12 - Detect whether this timestamp includes hours.
+ // 8-12 - Collect the next sequence of 0-9 after ':' (must be 2 chars).
+ if (*position >= line.length() || line[(*position)++] != ':')
+ return malformedTime;
+ if (*position >= line.length() || !isASCIIDigit(line[(*position)]))
+ return malformedTime;
+ String digits2 = collectDigits(line, position);
+ int value2 = digits2.toInt();
+ if (digits2.length() != 2)
+ return malformedTime;
+
+ // 13 - Detect whether this timestamp includes hours.
int value3;
- if (mode == hours || input.match(':')) {
- if (!input.scan(':') || input.scanDigits(value3) != 2)
- return false;
+ if (mode == hours || (*position < line.length() && line[*position] == ':')) {
+ if (*position >= line.length() || line[(*position)++] != ':')
+ return malformedTime;
+ if (*position >= line.length() || !isASCIIDigit(line[*position]))
+ return malformedTime;
+ String digits3 = collectDigits(line, position);
+ if (digits3.length() != 2)
+ return malformedTime;
+ value3 = digits3.toInt();
} else {
value3 = value2;
value2 = value1;
value1 = 0;
}
- // Steps 13 - 17 - Collect next sequence of 0-9 after '.' (must be 3 chars).
- int value4;
- if (!input.scan('.') || input.scanDigits(value4) != 3)
- return false;
+ // 14-19 - Collect next sequence of 0-9 after '.' (must be 3 chars).
+ if (*position >= line.length() || line[(*position)++] != '.')
+ return malformedTime;
+ if (*position >= line.length() || !isASCIIDigit(line[*position]))
+ return malformedTime;
+ String digits4 = collectDigits(line, position);
+ if (digits4.length() != 3)
+ return malformedTime;
+ int value4 = digits4.toInt();
if (value2 > 59 || value3 > 59)
- return false;
+ return malformedTime;
- // Steps 18 - 19 - Calculate result.
- timeStamp = MediaTime::createWithDouble((value1 * secondsPerHour) + (value2 * secondsPerMinute) + value3 + (value4 * secondsPerMillisecond));
- return true;
+ // 20-21 - Calculate result.
+ return (value1 * secondsPerHour) + (value2 * secondsPerMinute) + value3 + (value4 * secondsPerMillisecond);
}
static WebVTTNodeType tokenToNodeType(WebVTTToken& token)
{
- switch (token.name().length()) {
+ switch (token.name().size()) {
case 1:
if (token.name()[0] == 'c')
return WebVTTNodeTypeClass;
@@ -546,78 +506,91 @@ static WebVTTNodeType tokenToNodeType(WebVTTToken& token)
return WebVTTNodeTypeNone;
}
-void WebVTTTreeBuilder::constructTreeFromToken(Document& document)
+void WebVTTParser::constructTreeFromToken(Document* document)
{
+ QualifiedName tagName(nullAtom, AtomicString(m_token.name()), xhtmlNamespaceURI);
+
// http://dev.w3.org/html5/webvtt/#webvtt-cue-text-dom-construction-rules
switch (m_token.type()) {
case WebVTTTokenTypes::Character: {
- RefPtr<Text> child = Text::create(document, m_token.characters());
+ String content(m_token.characters()); // FIXME: This should be 8bit if possible.
+ RefPtr<Text> child = Text::create(*document, content);
m_currentNode->parserAppendChild(child);
break;
}
case WebVTTTokenTypes::StartTag: {
+ RefPtr<WebVTTElement> child;
WebVTTNodeType nodeType = tokenToNodeType(m_token);
- if (nodeType == WebVTTNodeTypeNone)
- break;
-
- WebVTTNodeType currentType = is<WebVTTElement>(*m_currentNode) ? downcast<WebVTTElement>(*m_currentNode).webVTTNodeType() : WebVTTNodeTypeNone;
- // <rt> is only allowed if the current node is <ruby>.
- if (nodeType == WebVTTNodeTypeRubyText && currentType != WebVTTNodeTypeRuby)
- break;
-
- RefPtr<WebVTTElement> child = WebVTTElement::create(nodeType, document);
- if (!m_token.classes().isEmpty())
- child->setAttribute(classAttr, m_token.classes());
-
- if (nodeType == WebVTTNodeTypeVoice)
- child->setAttribute(WebVTTElement::voiceAttributeName(), m_token.annotation());
- else if (nodeType == WebVTTNodeTypeLanguage) {
- m_languageStack.append(m_token.annotation());
- child->setAttribute(WebVTTElement::langAttributeName(), m_languageStack.last());
+ if (nodeType != WebVTTNodeTypeNone)
+ child = WebVTTElement::create(nodeType, *document);
+ if (child) {
+ if (m_token.classes().size() > 0)
+ child->setAttribute(classAttr, AtomicString(m_token.classes()));
+
+ if (child->webVTTNodeType() == WebVTTNodeTypeVoice)
+ child->setAttribute(WebVTTElement::voiceAttributeName(), AtomicString(m_token.annotation()));
+ else if (child->webVTTNodeType() == WebVTTNodeTypeLanguage) {
+ m_languageStack.append(AtomicString(m_token.annotation()));
+ child->setAttribute(WebVTTElement::langAttributeName(), m_languageStack.last());
+ }
+ if (!m_languageStack.isEmpty())
+ child->setLanguage(m_languageStack.last());
+ m_currentNode->parserAppendChild(child);
+ m_currentNode = child;
}
- if (!m_languageStack.isEmpty())
- child->setLanguage(m_languageStack.last());
- m_currentNode->parserAppendChild(child);
- m_currentNode = child;
break;
}
case WebVTTTokenTypes::EndTag: {
WebVTTNodeType nodeType = tokenToNodeType(m_token);
- if (nodeType == WebVTTNodeTypeNone)
- break;
-
- // The only non-VTTElement would be the DocumentFragment root. (Text
- // nodes and PIs will never appear as m_currentNode.)
- if (!is<WebVTTElement>(*m_currentNode))
- break;
-
- WebVTTNodeType currentType = downcast<WebVTTElement>(*m_currentNode).webVTTNodeType();
- bool matchesCurrent = nodeType == currentType;
- if (!matchesCurrent) {
- // </ruby> auto-closes <rt>
- if (currentType == WebVTTNodeTypeRubyText && nodeType == WebVTTNodeTypeRuby) {
- if (m_currentNode->parentNode())
- m_currentNode = m_currentNode->parentNode();
- } else
- break;
+ if (nodeType != WebVTTNodeTypeNone) {
+ if (nodeType == WebVTTNodeTypeLanguage && m_currentNode->isWebVTTElement() && toWebVTTElement(m_currentNode.get())->webVTTNodeType() == WebVTTNodeTypeLanguage)
+ m_languageStack.removeLast();
+ if (m_currentNode->parentNode())
+ m_currentNode = m_currentNode->parentNode();
}
- if (nodeType == WebVTTNodeTypeLanguage)
- m_languageStack.removeLast();
- if (m_currentNode->parentNode())
- m_currentNode = m_currentNode->parentNode();
break;
}
case WebVTTTokenTypes::TimestampTag: {
- String charactersString = m_token.characters();
- MediaTime parsedTimeStamp;
- if (WebVTTParser::collectTimeStamp(charactersString, parsedTimeStamp))
- m_currentNode->parserAppendChild(ProcessingInstruction::create(document, "timestamp", charactersString));
+ unsigned position = 0;
+ String charactersString(StringImpl::create8BitIfPossible(m_token.characters()));
+ double time = collectTimeStamp(charactersString, &position);
+ if (time != malformedTime)
+ m_currentNode->parserAppendChild(ProcessingInstruction::create(*document, "timestamp", charactersString));
break;
}
default:
break;
}
+ m_token.clear();
+}
+
+void WebVTTParser::skipWhiteSpace(const String& line, unsigned* position)
+{
+ while (*position < line.length() && isASpace(line[*position]))
+ (*position)++;
+}
+
+String WebVTTParser::collectNextLine(const char* data, unsigned length, unsigned* position)
+{
+ unsigned currentPosition = *position;
+ while (currentPosition < length && data[currentPosition] != '\r' && data[currentPosition] != '\n')
+ currentPosition++;
+ if (currentPosition >= length)
+ return String();
+ String line = String::fromUTF8(data + *position , currentPosition - *position);
+ if (data[currentPosition] == '\r')
+ currentPosition++;
+ if (currentPosition < length && data[currentPosition] == '\n')
+ currentPosition++;
+ *position = currentPosition;
+ if (m_buffer.isEmpty())
+ return line;
+
+ String lineWithBuffer = String::fromUTF8(m_buffer.data(), m_buffer.size());
+ lineWithBuffer.append(line);
+ m_buffer.clear();
+ return lineWithBuffer;
}
}
diff --git a/Source/WebCore/html/track/WebVTTParser.h b/Source/WebCore/html/track/WebVTTParser.h
index cfaf0183a..eb27d7930 100644
--- a/Source/WebCore/html/track/WebVTTParser.h
+++ b/Source/WebCore/html/track/WebVTTParser.h
@@ -1,7 +1,6 @@
/*
- * Copyright (C) 2011, 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2013 Cable Television Labs, Inc.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -35,14 +34,11 @@
#if ENABLE(VIDEO_TRACK)
-#include "BufferedLineReader.h"
#include "DocumentFragment.h"
#include "HTMLNames.h"
-#include "TextResourceDecoder.h"
-#include "VTTRegion.h"
+#include "TextTrackRegion.h"
#include "WebVTTTokenizer.h"
-#include <memory>
-#include <wtf/MediaTime.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -50,8 +46,6 @@ namespace WebCore {
using namespace HTMLNames;
class Document;
-class ISOWebVTTCue;
-class VTTScanner;
class WebVTTParserClient {
public:
@@ -64,17 +58,17 @@ public:
virtual void fileFailedToParse() = 0;
};
-class WebVTTCueData final : public RefCounted<WebVTTCueData> {
+class WebVTTCueData : public RefCounted<WebVTTCueData> {
public:
- static Ref<WebVTTCueData> create() { return adoptRef(*new WebVTTCueData()); }
- ~WebVTTCueData() { }
+ static PassRefPtr<WebVTTCueData> create() { return adoptRef(new WebVTTCueData()); }
+ virtual ~WebVTTCueData() { }
- MediaTime startTime() const { return m_startTime; }
- void setStartTime(const MediaTime& startTime) { m_startTime = startTime; }
+ double startTime() const { return m_startTime; }
+ void setStartTime(double startTime) { m_startTime = startTime; }
- MediaTime endTime() const { return m_endTime; }
- void setEndTime(const MediaTime& endTime) { m_endTime = endTime; }
+ double endTime() const { return m_endTime; }
+ void setEndTime(double endTime) { m_endTime = endTime; }
String id() const { return m_id; }
void setId(String id) { m_id = id; }
@@ -85,25 +79,30 @@ public:
String settings() const { return m_settings; }
void setSettings(String settings) { m_settings = settings; }
- MediaTime originalStartTime() const { return m_originalStartTime; }
- void setOriginalStartTime(const MediaTime& time) { m_originalStartTime = time; }
-
private:
- WebVTTCueData() { }
+ WebVTTCueData()
+ : m_startTime(0)
+ , m_endTime(0)
+ {
+ }
- MediaTime m_startTime;
- MediaTime m_endTime;
- MediaTime m_originalStartTime;
+ double m_startTime;
+ double m_endTime;
String m_id;
String m_content;
String m_settings;
};
-class WebVTTParser final {
+class WebVTTParser {
public:
+ virtual ~WebVTTParser() { }
+
enum ParseState {
Initial,
Header,
+#if ENABLE(WEBVTT_REGIONS)
+ Metadata,
+#endif
Id,
TimingsAndSettings,
CueText,
@@ -111,8 +110,11 @@ public:
Finished
};
- WebVTTParser(WebVTTParserClient*, ScriptExecutionContext*);
-
+ static OwnPtr<WebVTTParser> create(WebVTTParserClient* client, ScriptExecutionContext* context)
+ {
+ return adoptPtr(new WebVTTParser(client, context));
+ }
+
static inline bool isRecognizedTag(const AtomicString& tagName)
{
return tagName == iTag
@@ -122,74 +124,87 @@ public:
|| tagName == rtTag;
}
- static inline bool isValidSettingDelimiter(UChar c)
+ static inline bool isASpace(char c)
+ {
+ // WebVTT space characters are U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF), U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN (CR).
+ return c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r';
+ }
+ static inline bool isValidSettingDelimiter(char c)
{
// ... a WebVTT cue consists of zero or more of the following components, in any order, separated from each other by one or more
// U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters.
return c == ' ' || c == '\t';
}
- static bool collectTimeStamp(const String&, MediaTime&);
+ static String collectDigits(const String&, unsigned*);
+ static String collectWord(const String&, unsigned*);
- // Useful functions for parsing percentage settings.
- static bool parseFloatPercentageValue(VTTScanner& valueScanner, float&);
#if ENABLE(WEBVTT_REGIONS)
- static bool parseFloatPercentageValuePair(VTTScanner& valueScanner, char, FloatPoint&);
+ // Useful functions for parsing percentage settings.
+ static float parseFloatPercentageValue(const String&, bool&);
+ static FloatPoint parseFloatPercentageValuePair(const String&, char, bool&);
#endif
// Input data to the parser to parse.
- void parseBytes(const char*, unsigned);
- void parseFileHeader(const String&);
- void parseCueData(const ISOWebVTTCue&);
- void flush();
+ void parseBytes(const char* data, unsigned length);
void fileFinished();
// Transfers ownership of last parsed cues to caller.
void getNewCues(Vector<RefPtr<WebVTTCueData>>&);
#if ENABLE(WEBVTT_REGIONS)
- void getNewRegions(Vector<RefPtr<VTTRegion>>&);
+ void getNewRegions(Vector<RefPtr<TextTrackRegion>>&);
#endif
- // Create the DocumentFragment representation of the WebVTT cue text.
- static PassRefPtr<DocumentFragment> createDocumentFragmentFromCueText(Document&, const String&);
+ PassRefPtr<DocumentFragment> createDocumentFragmentFromCueText(const String&);
+ double collectTimeStamp(const String&, unsigned*);
protected:
+ WebVTTParser(WebVTTParserClient*, ScriptExecutionContext*);
+
ScriptExecutionContext* m_scriptExecutionContext;
ParseState m_state;
private:
- void parse();
- void flushPendingCue();
bool hasRequiredFileIdentifier(const String&);
ParseState collectCueId(const String&);
ParseState collectTimingsAndSettings(const String&);
ParseState collectCueText(const String&);
- ParseState recoverCue(const String&);
ParseState ignoreBadCue(const String&);
void createNewCue();
void resetCueValues();
- void collectMetadataHeader(const String&);
#if ENABLE(WEBVTT_REGIONS)
- void createNewRegion(const String& headerValue);
+ void collectHeader(const String&);
+ void createNewRegion();
#endif
- static bool collectTimeStamp(VTTScanner& input, MediaTime& timeStamp);
+ void skipWhiteSpace(const String&, unsigned*);
+ String collectNextLine(const char* data, unsigned length, unsigned*);
+
+ void constructTreeFromToken(Document*);
- BufferedLineReader m_lineReader;
- RefPtr<TextResourceDecoder> m_decoder;
+ String m_currentHeaderName;
+ String m_currentHeaderValue;
+
+ Vector<char> m_buffer;
String m_currentId;
- MediaTime m_currentStartTime;
- MediaTime m_currentEndTime;
+ double m_currentStartTime;
+ double m_currentEndTime;
StringBuilder m_currentContent;
String m_currentSettings;
+
+ WebVTTToken m_token;
+ OwnPtr<WebVTTTokenizer> m_tokenizer;
+
+ RefPtr<ContainerNode> m_currentNode;
WebVTTParserClient* m_client;
+ Vector<AtomicString> m_languageStack;
Vector<RefPtr<WebVTTCueData>> m_cuelist;
#if ENABLE(WEBVTT_REGIONS)
- Vector<RefPtr<VTTRegion>> m_regionList;
+ Vector<RefPtr<TextTrackRegion>> m_regionList;
#endif
};
diff --git a/Source/WebCore/html/track/WebVTTToken.h b/Source/WebCore/html/track/WebVTTToken.h
index 1752b5510..7cf1a27d3 100644
--- a/Source/WebCore/html/track/WebVTTToken.h
+++ b/Source/WebCore/html/track/WebVTTToken.h
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2011, 2013 Google Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -44,54 +43,167 @@ public:
StartTag,
EndTag,
TimestampTag,
+ EndOfFile,
};
};
class WebVTTToken {
+ WTF_MAKE_NONCOPYABLE(WebVTTToken);
+ WTF_MAKE_FAST_ALLOCATED;
public:
typedef WebVTTTokenTypes Type;
+ typedef WTF::Vector<UChar, 1024> DataVector; // FIXME: Is this too large for WebVTT?
- WebVTTToken()
- : m_type(Type::Uninitialized) { }
+ WebVTTToken() { clear(); }
- static WebVTTToken StringToken(const String& characterData)
+ void appendToName(UChar character)
{
- return WebVTTToken(Type::Character, characterData);
+ ASSERT(m_type == WebVTTTokenTypes::StartTag || m_type == WebVTTTokenTypes::EndTag);
+ ASSERT(character);
+ m_data.append(character);
}
- static WebVTTToken StartTag(const String& tagName, const AtomicString& classes = emptyAtom, const AtomicString& annotation = emptyAtom)
+ Type::Type type() const { return m_type; }
+
+ const DataVector& name() const
{
- WebVTTToken token(Type::StartTag, tagName);
- token.m_classes = classes;
- token.m_annotation = annotation;
- return token;
+ return m_data;
}
- static WebVTTToken EndTag(const String& tagName)
+ const DataVector& characters() const
{
- return WebVTTToken(Type::EndTag, tagName);
+ ASSERT(m_type == Type::Character || m_type == Type::TimestampTag);
+ return m_data;
}
- static WebVTTToken TimestampTag(const String& timestampData)
+ // Starting a character token works slightly differently than starting
+ // other types of tokens because we want to save a per-character branch.
+ void ensureIsCharacterToken()
{
- return WebVTTToken(Type::TimestampTag, timestampData);
+ ASSERT(m_type == Type::Uninitialized || m_type == Type::Character);
+ m_type = Type::Character;
}
- Type::Type type() const { return m_type; }
- const String& name() const { return m_data; }
- const String& characters() const { return m_data; }
- const AtomicString& classes() const { return m_classes; }
- const AtomicString& annotation() const { return m_annotation; }
+ void appendToCharacter(char character)
+ {
+ ASSERT(m_type == Type::Character);
+ m_data.append(character);
+ }
+
+ void appendToCharacter(UChar character)
+ {
+ ASSERT(m_type == Type::Character);
+ m_data.append(character);
+ }
+
+ void appendToCharacter(const Vector<LChar, 32>& characters)
+ {
+ ASSERT(m_type == Type::Character);
+ m_data.appendVector(characters);
+ }
+
+ void beginEmptyStartTag()
+ {
+ ASSERT(m_type == Type::Uninitialized);
+ m_type = Type::StartTag;
+ m_data.clear();
+ }
+
+ void beginStartTag(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == Type::Uninitialized);
+ m_type = Type::StartTag;
+ m_data.append(character);
+ }
+
+ void beginEndTag(LChar character)
+ {
+ ASSERT(m_type == Type::Uninitialized);
+ m_type = Type::EndTag;
+ m_data.append(character);
+ }
+
+ void beginTimestampTag(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == Type::Uninitialized);
+ m_type = Type::TimestampTag;
+ m_data.append(character);
+ }
+
+ void appendToTimestamp(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == Type::TimestampTag);
+ m_data.append(character);
+ }
+
+ void appendToClass(UChar character)
+ {
+ appendToStartType(character);
+ }
+
+ void addNewClass()
+ {
+ ASSERT(m_type == Type::StartTag);
+ if (!m_classes.isEmpty())
+ m_classes.append(' ');
+ m_classes.appendVector(m_currentBuffer);
+ m_currentBuffer.clear();
+ }
+
+ const DataVector& classes() const
+ {
+ return m_classes;
+ }
+
+ void appendToAnnotation(UChar character)
+ {
+ appendToStartType(character);
+ }
+
+ void addNewAnnotation()
+ {
+ ASSERT(m_type == Type::StartTag);
+ m_annotation.clear();
+ m_annotation.appendVector(m_currentBuffer);
+ m_currentBuffer.clear();
+ }
+
+ const DataVector& annotation() const
+ {
+ return m_annotation;
+ }
+
+ void makeEndOfFile()
+ {
+ ASSERT(m_type == Type::Uninitialized);
+ m_type = Type::EndOfFile;
+ }
+
+ void clear()
+ {
+ m_type = Type::Uninitialized;
+ m_data.clear();
+ m_annotation.clear();
+ m_classes.clear();
+ m_currentBuffer.clear();
+ }
private:
- WebVTTToken(Type::Type type, const String& data)
- : m_type(type)
- , m_data(data) { }
+ void appendToStartType(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == Type::StartTag);
+ m_currentBuffer.append(character);
+ }
Type::Type m_type;
- String m_data;
- AtomicString m_annotation;
- AtomicString m_classes;
+ DataVector m_data;
+ DataVector m_annotation;
+ DataVector m_classes;
+ DataVector m_currentBuffer;
};
}
diff --git a/Source/WebCore/html/track/WebVTTTokenizer.cpp b/Source/WebCore/html/track/WebVTTTokenizer.cpp
index 0cb19e85f..9bde924c8 100644
--- a/Source/WebCore/html/track/WebVTTTokenizer.cpp
+++ b/Source/WebCore/html/track/WebVTTTokenizer.cpp
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2011, 2013 Google Inc. All rights reserved.
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -36,196 +35,200 @@
#include "WebVTTTokenizer.h"
#include "MarkupTokenizerInlines.h"
-#include <wtf/text/StringBuilder.h>
#include <wtf/unicode/CharacterNames.h>
namespace WebCore {
-#define WEBVTT_ADVANCE_TO(stateName) \
- do { \
- ASSERT(!m_input.isEmpty()); \
- m_preprocessor.advance(m_input); \
- character = m_preprocessor.nextInputCharacter(); \
- goto stateName; \
- } while (false)
-
-template<unsigned charactersCount> ALWAYS_INLINE bool equalLiteral(const StringBuilder& s, const char (&characters)[charactersCount])
-{
- return WTF::equal(s, reinterpret_cast<const LChar*>(characters), charactersCount - 1);
-}
+#define WEBVTT_BEGIN_STATE(stateName) BEGIN_STATE(WebVTTTokenizerState, stateName)
+#define WEBVTT_ADVANCE_TO(stateName) ADVANCE_TO(WebVTTTokenizerState, stateName)
-static void addNewClass(StringBuilder& classes, const StringBuilder& newClass)
+WebVTTTokenizer::WebVTTTokenizer()
+ : m_inputStreamPreprocessor(this)
{
- if (!classes.isEmpty())
- classes.append(' ');
- classes.append(newClass);
+ reset();
}
-inline bool emitToken(WebVTTToken& resultToken, const WebVTTToken& token)
+template <typename CharacterType>
+inline bool vectorEqualsString(const Vector<CharacterType, 32>& vector, const String& string)
{
- resultToken = token;
- return true;
-}
+ if (vector.size() != string.length())
+ return false;
-inline bool advanceAndEmitToken(SegmentedString& source, WebVTTToken& resultToken, const WebVTTToken& token)
-{
- source.advanceAndUpdateLineNumber();
- return emitToken(resultToken, token);
+ if (!string.length())
+ return true;
+
+ return equal(string.impl(), vector.data(), vector.size());
}
-WebVTTTokenizer::WebVTTTokenizer(const String& input)
- : m_input(input)
- , m_preprocessor(*this)
+void WebVTTTokenizer::reset()
{
- // Append an EOF marker and close the input "stream".
- ASSERT(!m_input.isClosed());
- m_input.append(SegmentedString(String(&kEndOfFileMarker, 1)));
- m_input.close();
+ m_state = WebVTTTokenizerState::DataState;
+ m_token = 0;
+ m_buffer.clear();
}
-
-bool WebVTTTokenizer::nextToken(WebVTTToken& token)
+
+bool WebVTTTokenizer::nextToken(SegmentedString& source, WebVTTToken& token)
{
- if (m_input.isEmpty() || !m_preprocessor.peek(m_input))
- return false;
+ // If we have a token in progress, then we're supposed to be called back
+ // with the same token so we can finish it.
+ ASSERT(!m_token || m_token == &token || token.type() == WebVTTTokenTypes::Uninitialized);
+ m_token = &token;
- UChar character = m_preprocessor.nextInputCharacter();
- if (character == kEndOfFileMarker) {
- m_preprocessor.advance(m_input);
- return false;
- }
+ if (source.isEmpty() || !m_inputStreamPreprocessor.peek(source))
+ return haveBufferedCharacterToken();
+
+ UChar cc = m_inputStreamPreprocessor.nextInputCharacter();
- StringBuilder buffer;
- StringBuilder result;
- StringBuilder classes;
-
-// 4.8.10.13.4 WebVTT cue text tokenizer
-DataState:
- if (character == '&') {
- buffer.append('&');
- WEBVTT_ADVANCE_TO(EscapeState);
- } else if (character == '<') {
- if (result.isEmpty())
- WEBVTT_ADVANCE_TO(TagState);
+ // 4.8.10.13.4 WebVTT cue text tokenizer
+ switch (m_state) {
+ WEBVTT_BEGIN_STATE(DataState) {
+ if (cc == '&') {
+ m_buffer.append(static_cast<LChar>(cc));
+ WEBVTT_ADVANCE_TO(EscapeState);
+ } else if (cc == '<') {
+ if (m_token->type() == WebVTTTokenTypes::Uninitialized
+ || vectorEqualsString<UChar>(m_token->characters(), emptyString()))
+ WEBVTT_ADVANCE_TO(TagState);
+ else
+ return emitAndResumeIn(source, WebVTTTokenizerState::TagState);
+ } else if (cc == kEndOfFileMarker)
+ return emitEndOfFile(source);
else {
- // We don't want to advance input or perform a state transition - just return a (new) token.
- // (On the next call to nextToken we will see '<' again, but take the other branch in this if instead.)
- return emitToken(token, WebVTTToken::StringToken(result.toString()));
+ bufferCharacter(cc);
+ WEBVTT_ADVANCE_TO(DataState);
}
- } else if (character == kEndOfFileMarker)
- return advanceAndEmitToken(m_input, token, WebVTTToken::StringToken(result.toString()));
- else {
- result.append(character);
- WEBVTT_ADVANCE_TO(DataState);
}
-
-EscapeState:
- if (character == ';') {
- if (equalLiteral(buffer, "&amp"))
- result.append('&');
- else if (equalLiteral(buffer, "&lt"))
- result.append('<');
- else if (equalLiteral(buffer, "&gt"))
- result.append('>');
- else if (equalLiteral(buffer, "&lrm"))
- result.append(leftToRightMark);
- else if (equalLiteral(buffer, "&rlm"))
- result.append(rightToLeftMark);
- else if (equalLiteral(buffer, "&nbsp"))
- result.append(noBreakSpace);
+ END_STATE()
+
+ WEBVTT_BEGIN_STATE(EscapeState) {
+ if (cc == ';') {
+ if (vectorEqualsString(m_buffer, "&amp"))
+ bufferCharacter('&');
+ else if (vectorEqualsString(m_buffer, "&lt"))
+ bufferCharacter('<');
+ else if (vectorEqualsString(m_buffer, "&gt"))
+ bufferCharacter('>');
+ else if (vectorEqualsString(m_buffer, "&lrm"))
+ bufferCharacter(leftToRightMark);
+ else if (vectorEqualsString(m_buffer, "&rlm"))
+ bufferCharacter(rightToLeftMark);
+ else if (vectorEqualsString(m_buffer, "&nbsp"))
+ bufferCharacter(noBreakSpace);
+ else {
+ m_buffer.append(static_cast<LChar>(cc));
+ m_token->appendToCharacter(m_buffer);
+ }
+ m_buffer.clear();
+ WEBVTT_ADVANCE_TO(DataState);
+ } else if (isASCIIAlphanumeric(cc)) {
+ m_buffer.append(static_cast<LChar>(cc));
+ WEBVTT_ADVANCE_TO(EscapeState);
+ } else if (cc == kEndOfFileMarker) {
+ m_token->appendToCharacter(m_buffer);
+ return emitEndOfFile(source);
+ } else {
+ if (!vectorEqualsString(m_buffer, "&"))
+ m_token->appendToCharacter(m_buffer);
+ m_buffer.clear();
+ WEBVTT_ADVANCE_TO(DataState);
+ }
+ }
+ END_STATE()
+
+ WEBVTT_BEGIN_STATE(TagState) {
+ if (isTokenizerWhitespace(cc)) {
+ m_token->beginEmptyStartTag();
+ WEBVTT_ADVANCE_TO(StartTagAnnotationState);
+ } else if (cc == '.') {
+ m_token->beginEmptyStartTag();
+ WEBVTT_ADVANCE_TO(StartTagClassState);
+ } else if (cc == '/') {
+ WEBVTT_ADVANCE_TO(EndTagOpenState);
+ } else if (WTF::isASCIIDigit(cc)) {
+ m_token->beginTimestampTag(cc);
+ WEBVTT_ADVANCE_TO(TimestampTagState);
+ } else if (cc == '>' || cc == kEndOfFileMarker) {
+ m_token->beginEmptyStartTag();
+ return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
+ } else {
+ m_token->beginStartTag(cc);
+ WEBVTT_ADVANCE_TO(StartTagState);
+ }
+ }
+ END_STATE()
+
+ WEBVTT_BEGIN_STATE(StartTagState) {
+ if (isTokenizerWhitespace(cc))
+ WEBVTT_ADVANCE_TO(StartTagAnnotationState);
+ else if (cc == '.')
+ WEBVTT_ADVANCE_TO(StartTagClassState);
+ else if (cc == '>' || cc == kEndOfFileMarker)
+ return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
else {
- buffer.append(character);
- result.append(buffer);
+ m_token->appendToName(cc);
+ WEBVTT_ADVANCE_TO(StartTagState);
}
- buffer.clear();
- WEBVTT_ADVANCE_TO(DataState);
- } else if (isASCIIAlphanumeric(character)) {
- buffer.append(character);
- WEBVTT_ADVANCE_TO(EscapeState);
- } else if (character == '<') {
- result.append(buffer);
- return emitToken(token, WebVTTToken::StringToken(result.toString()));
- } else if (character == kEndOfFileMarker) {
- result.append(buffer);
- return advanceAndEmitToken(m_input, token, WebVTTToken::StringToken(result.toString()));
- } else {
- result.append(buffer);
- buffer.clear();
-
- if (character == '&') {
- buffer.append('&');
- WEBVTT_ADVANCE_TO(EscapeState);
+ }
+ END_STATE()
+
+ WEBVTT_BEGIN_STATE(StartTagClassState) {
+ if (isTokenizerWhitespace(cc)) {
+ m_token->addNewClass();
+ WEBVTT_ADVANCE_TO(StartTagAnnotationState);
+ } else if (cc == '.') {
+ m_token->addNewClass();
+ WEBVTT_ADVANCE_TO(StartTagClassState);
+ } else if (cc == '>' || cc == kEndOfFileMarker) {
+ m_token->addNewClass();
+ return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
+ } else {
+ m_token->appendToClass(cc);
+ WEBVTT_ADVANCE_TO(StartTagClassState);
}
- result.append(character);
- WEBVTT_ADVANCE_TO(DataState);
+
}
+ END_STATE()
-TagState:
- if (isTokenizerWhitespace(character)) {
- ASSERT(result.isEmpty());
+ WEBVTT_BEGIN_STATE(StartTagAnnotationState) {
+ if (cc == '>' || cc == kEndOfFileMarker) {
+ m_token->addNewAnnotation();
+ return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
+ }
+ m_token->appendToAnnotation(cc);
WEBVTT_ADVANCE_TO(StartTagAnnotationState);
- } else if (character == '.') {
- ASSERT(result.isEmpty());
- WEBVTT_ADVANCE_TO(StartTagClassState);
- } else if (character == '/') {
+ }
+ END_STATE()
+
+ WEBVTT_BEGIN_STATE(EndTagOpenState) {
+ if (cc == '>' || cc == kEndOfFileMarker) {
+ m_token->beginEndTag('\0');
+ return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
+ }
+ m_token->beginEndTag(cc);
WEBVTT_ADVANCE_TO(EndTagState);
- } else if (WTF::isASCIIDigit(character)) {
- result.append(character);
- WEBVTT_ADVANCE_TO(TimestampTagState);
- } else if (character == '>' || character == kEndOfFileMarker) {
- ASSERT(result.isEmpty());
- return advanceAndEmitToken(m_input, token, WebVTTToken::StartTag(result.toString()));
- } else {
- result.append(character);
- WEBVTT_ADVANCE_TO(StartTagState);
}
+ END_STATE()
-StartTagState:
- if (isTokenizerWhitespace(character))
- WEBVTT_ADVANCE_TO(StartTagAnnotationState);
- else if (character == '.')
- WEBVTT_ADVANCE_TO(StartTagClassState);
- else if (character == '>' || character == kEndOfFileMarker)
- return advanceAndEmitToken(m_input, token, WebVTTToken::StartTag(result.toString()));
- else {
- result.append(character);
- WEBVTT_ADVANCE_TO(StartTagState);
+ WEBVTT_BEGIN_STATE(EndTagState) {
+ if (cc == '>' || cc == kEndOfFileMarker)
+ return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
+ m_token->appendToName(cc);
+ WEBVTT_ADVANCE_TO(EndTagState);
}
+ END_STATE()
+
+ WEBVTT_BEGIN_STATE(TimestampTagState) {
+ if (cc == '>' || cc == kEndOfFileMarker)
+ return emitAndResumeIn(source, WebVTTTokenizerState::DataState);
+ m_token->appendToTimestamp(cc);
+ WEBVTT_ADVANCE_TO(TimestampTagState);
+ }
+ END_STATE()
-StartTagClassState:
- if (isTokenizerWhitespace(character)) {
- addNewClass(classes, buffer);
- buffer.clear();
- WEBVTT_ADVANCE_TO(StartTagAnnotationState);
- } else if (character == '.') {
- addNewClass(classes, buffer);
- buffer.clear();
- WEBVTT_ADVANCE_TO(StartTagClassState);
- } else if (character == '>' || character == kEndOfFileMarker) {
- addNewClass(classes, buffer);
- buffer.clear();
- return advanceAndEmitToken(m_input, token, WebVTTToken::StartTag(result.toString(), classes.toAtomicString()));
- } else {
- buffer.append(character);
- WEBVTT_ADVANCE_TO(StartTagClassState);
}
-StartTagAnnotationState:
- if (character == '>' || character == kEndOfFileMarker)
- return advanceAndEmitToken(m_input, token, WebVTTToken::StartTag(result.toString(), classes.toAtomicString(), buffer.toAtomicString()));
- buffer.append(character);
- WEBVTT_ADVANCE_TO(StartTagAnnotationState);
-
-EndTagState:
- if (character == '>' || character == kEndOfFileMarker)
- return advanceAndEmitToken(m_input, token, WebVTTToken::EndTag(result.toString()));
- result.append(character);
- WEBVTT_ADVANCE_TO(EndTagState);
-
-TimestampTagState:
- if (character == '>' || character == kEndOfFileMarker)
- return advanceAndEmitToken(m_input, token, WebVTTToken::TimestampTag(result.toString()));
- result.append(character);
- WEBVTT_ADVANCE_TO(TimestampTagState);
+ ASSERT_NOT_REACHED();
+ return false;
}
}
diff --git a/Source/WebCore/html/track/WebVTTTokenizer.h b/Source/WebCore/html/track/WebVTTTokenizer.h
index 6c1dda3ea..79ee06b26 100644
--- a/Source/WebCore/html/track/WebVTTTokenizer.h
+++ b/Source/WebCore/html/track/WebVTTTokenizer.h
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2011, 2013 Google Inc. All rights reserved.
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -36,19 +35,81 @@
#include "InputStreamPreprocessor.h"
#include "WebVTTToken.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
+class WebVTTTokenizerState {
+public:
+ enum State {
+ DataState,
+ EscapeState,
+ TagState,
+ StartTagState,
+ StartTagClassState,
+ StartTagAnnotationState,
+ EndTagState,
+ EndTagOpenState,
+ TimestampTagState,
+ };
+};
+
class WebVTTTokenizer {
+ WTF_MAKE_NONCOPYABLE(WebVTTTokenizer);
+ WTF_MAKE_FAST_ALLOCATED;
public:
- explicit WebVTTTokenizer(const String&);
- bool nextToken(WebVTTToken&);
+ static OwnPtr<WebVTTTokenizer> create() { return adoptPtr(new WebVTTTokenizer); }
+
+ typedef WebVTTTokenizerState State;
+
+ void reset();
+
+ bool nextToken(SegmentedString&, WebVTTToken&);
+
+ inline bool haveBufferedCharacterToken()
+ {
+ return m_token->type() == WebVTTToken::Type::Character;
+ }
- static bool neverSkipNullCharacters() { return false; }
+ inline void bufferCharacter(UChar character)
+ {
+ ASSERT(character != kEndOfFileMarker);
+ m_token->ensureIsCharacterToken();
+ m_token->appendToCharacter(character);
+ }
+
+ inline bool emitAndResumeIn(SegmentedString& source, State::State state)
+ {
+ m_state = state;
+ source.advanceAndUpdateLineNumber();
+ return true;
+ }
+
+ inline bool emitEndOfFile(SegmentedString& source)
+ {
+ if (haveBufferedCharacterToken())
+ return true;
+ m_state = State::DataState;
+ source.advanceAndUpdateLineNumber();
+ m_token->clear();
+ m_token->makeEndOfFile();
+ return true;
+ }
+
+ bool shouldSkipNullCharacters() const { return true; }
private:
- SegmentedString m_input;
- InputStreamPreprocessor<WebVTTTokenizer> m_preprocessor;
+ WebVTTTokenizer();
+
+ // m_token is owned by the caller. If nextToken is not on the stack,
+ // this member might be pointing to unallocated memory.
+ WebVTTToken* m_token;
+ WebVTTTokenizerState::State m_state;
+
+ Vector<LChar, 32> m_buffer;
+
+ // ://www.whatwg.org/specs/web-apps/current-work/#preprocessing-the-input-stream
+ InputStreamPreprocessor<WebVTTTokenizer> m_inputStreamPreprocessor;
};
}