summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/html
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-06 11:45:16 +0100
committerSteve Block <steveblock@google.com>2011-05-12 13:44:10 +0100
commitcad810f21b803229eb11403f9209855525a25d57 (patch)
tree29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /Source/WebCore/html
parent121b0cf4517156d0ac5111caf9830c51b69bae8f (diff)
downloadexternal_webkit-cad810f21b803229eb11403f9209855525a25d57.zip
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'Source/WebCore/html')
-rw-r--r--Source/WebCore/html/AsyncImageResizer.cpp77
-rw-r--r--Source/WebCore/html/AsyncImageResizer.h108
-rw-r--r--Source/WebCore/html/BaseButtonInputType.cpp100
-rw-r--r--Source/WebCore/html/BaseButtonInputType.h55
-rw-r--r--Source/WebCore/html/BaseCheckableInputType.cpp110
-rw-r--r--Source/WebCore/html/BaseCheckableInputType.h58
-rw-r--r--Source/WebCore/html/BaseDateAndTimeInputType.cpp182
-rw-r--r--Source/WebCore/html/BaseDateAndTimeInputType.h69
-rw-r--r--Source/WebCore/html/BaseTextInputType.cpp52
-rw-r--r--Source/WebCore/html/BaseTextInputType.h51
-rw-r--r--Source/WebCore/html/ButtonInputType.cpp58
-rw-r--r--Source/WebCore/html/ButtonInputType.h51
-rw-r--r--Source/WebCore/html/CheckboxInputType.cpp104
-rw-r--r--Source/WebCore/html/CheckboxInputType.h55
-rw-r--r--Source/WebCore/html/ClassList.cpp146
-rw-r--r--Source/WebCore/html/ClassList.h74
-rw-r--r--Source/WebCore/html/CollectionCache.cpp96
-rw-r--r--Source/WebCore/html/CollectionCache.h70
-rw-r--r--Source/WebCore/html/CollectionType.h68
-rw-r--r--Source/WebCore/html/ColorInputType.cpp87
-rw-r--r--Source/WebCore/html/ColorInputType.h52
-rw-r--r--Source/WebCore/html/DOMDataGridDataSource.cpp44
-rw-r--r--Source/WebCore/html/DOMDataGridDataSource.h69
-rw-r--r--Source/WebCore/html/DOMFormData.cpp72
-rw-r--r--Source/WebCore/html/DOMFormData.h60
-rw-r--r--Source/WebCore/html/DOMFormData.idl44
-rw-r--r--Source/WebCore/html/DOMSettableTokenList.cpp101
-rw-r--r--Source/WebCore/html/DOMSettableTokenList.h71
-rw-r--r--Source/WebCore/html/DOMSettableTokenList.idl35
-rw-r--r--Source/WebCore/html/DOMTokenList.cpp108
-rw-r--r--Source/WebCore/html/DOMTokenList.h62
-rw-r--r--Source/WebCore/html/DOMTokenList.idl43
-rw-r--r--Source/WebCore/html/DataGridColumn.cpp53
-rw-r--r--Source/WebCore/html/DataGridColumn.h117
-rw-r--r--Source/WebCore/html/DataGridColumn.idl48
-rw-r--r--Source/WebCore/html/DataGridColumnList.cpp126
-rw-r--r--Source/WebCore/html/DataGridColumnList.h63
-rw-r--r--Source/WebCore/html/DataGridColumnList.idl45
-rw-r--r--Source/WebCore/html/DataGridDataSource.h49
-rw-r--r--Source/WebCore/html/DateComponents.cpp728
-rw-r--r--Source/WebCore/html/DateComponents.h202
-rw-r--r--Source/WebCore/html/DateInputType.cpp94
-rw-r--r--Source/WebCore/html/DateInputType.h56
-rw-r--r--Source/WebCore/html/DateTimeInputType.cpp100
-rw-r--r--Source/WebCore/html/DateTimeInputType.h57
-rw-r--r--Source/WebCore/html/DateTimeLocalInputType.cpp106
-rw-r--r--Source/WebCore/html/DateTimeLocalInputType.h58
-rw-r--r--Source/WebCore/html/DocTypeStrings.gperf103
-rw-r--r--Source/WebCore/html/EmailInputType.cpp93
-rw-r--r--Source/WebCore/html/EmailInputType.h53
-rw-r--r--Source/WebCore/html/FTPDirectoryDocument.cpp452
-rw-r--r--Source/WebCore/html/FTPDirectoryDocument.h48
-rw-r--r--Source/WebCore/html/FileInputType.cpp196
-rw-r--r--Source/WebCore/html/FileInputType.h68
-rw-r--r--Source/WebCore/html/FormAssociatedElement.cpp162
-rw-r--r--Source/WebCore/html/FormAssociatedElement.h85
-rw-r--r--Source/WebCore/html/FormDataList.cpp49
-rw-r--r--Source/WebCore/html/FormDataList.h84
-rw-r--r--Source/WebCore/html/HTMLAllCollection.cpp47
-rw-r--r--Source/WebCore/html/HTMLAllCollection.h44
-rw-r--r--Source/WebCore/html/HTMLAllCollection.idl42
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.cpp559
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.h140
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.idl70
-rw-r--r--Source/WebCore/html/HTMLAppletElement.cpp183
-rw-r--r--Source/WebCore/html/HTMLAppletElement.h58
-rw-r--r--Source/WebCore/html/HTMLAppletElement.idl49
-rw-r--r--Source/WebCore/html/HTMLAreaElement.cpp240
-rw-r--r--Source/WebCore/html/HTMLAreaElement.h74
-rw-r--r--Source/WebCore/html/HTMLAreaElement.idl47
-rw-r--r--Source/WebCore/html/HTMLAttributeNames.in298
-rw-r--r--Source/WebCore/html/HTMLAudioElement.cpp61
-rw-r--r--Source/WebCore/html/HTMLAudioElement.h52
-rw-r--r--Source/WebCore/html/HTMLAudioElement.idl30
-rw-r--r--Source/WebCore/html/HTMLBRElement.cpp85
-rw-r--r--Source/WebCore/html/HTMLBRElement.h47
-rw-r--r--Source/WebCore/html/HTMLBRElement.idl26
-rw-r--r--Source/WebCore/html/HTMLBaseElement.cpp75
-rw-r--r--Source/WebCore/html/HTMLBaseElement.h46
-rw-r--r--Source/WebCore/html/HTMLBaseElement.idl27
-rw-r--r--Source/WebCore/html/HTMLBaseFontElement.cpp43
-rw-r--r--Source/WebCore/html/HTMLBaseFontElement.h40
-rw-r--r--Source/WebCore/html/HTMLBaseFontElement.idl31
-rw-r--r--Source/WebCore/html/HTMLBlockquoteElement.cpp53
-rw-r--r--Source/WebCore/html/HTMLBlockquoteElement.h43
-rw-r--r--Source/WebCore/html/HTMLBlockquoteElement.idl26
-rw-r--r--Source/WebCore/html/HTMLBodyElement.cpp379
-rw-r--r--Source/WebCore/html/HTMLBodyElement.h102
-rw-r--r--Source/WebCore/html/HTMLBodyElement.idl61
-rw-r--r--Source/WebCore/html/HTMLButtonElement.cpp187
-rw-r--r--Source/WebCore/html/HTMLButtonElement.h70
-rw-r--r--Source/WebCore/html/HTMLButtonElement.idl50
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.cpp453
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.h183
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.idl49
-rw-r--r--Source/WebCore/html/HTMLCollection.cpp407
-rw-r--r--Source/WebCore/html/HTMLCollection.h87
-rw-r--r--Source/WebCore/html/HTMLCollection.idl39
-rw-r--r--Source/WebCore/html/HTMLDListElement.cpp43
-rw-r--r--Source/WebCore/html/HTMLDListElement.h40
-rw-r--r--Source/WebCore/html/HTMLDListElement.idl26
-rw-r--r--Source/WebCore/html/HTMLDataGridCellElement.cpp100
-rw-r--r--Source/WebCore/html/HTMLDataGridCellElement.h62
-rw-r--r--Source/WebCore/html/HTMLDataGridCellElement.idl41
-rw-r--r--Source/WebCore/html/HTMLDataGridColElement.cpp176
-rw-r--r--Source/WebCore/html/HTMLDataGridColElement.h79
-rw-r--r--Source/WebCore/html/HTMLDataGridColElement.idl40
-rw-r--r--Source/WebCore/html/HTMLDataGridElement.cpp116
-rw-r--r--Source/WebCore/html/HTMLDataGridElement.h69
-rw-r--r--Source/WebCore/html/HTMLDataGridElement.idl40
-rw-r--r--Source/WebCore/html/HTMLDataGridRowElement.cpp80
-rw-r--r--Source/WebCore/html/HTMLDataGridRowElement.h56
-rw-r--r--Source/WebCore/html/HTMLDataGridRowElement.idl37
-rw-r--r--Source/WebCore/html/HTMLDataListElement.cpp57
-rw-r--r--Source/WebCore/html/HTMLDataListElement.h56
-rw-r--r--Source/WebCore/html/HTMLDataListElement.idl37
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.cpp47
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.h41
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.idl26
-rw-r--r--Source/WebCore/html/HTMLDirectoryElement.cpp43
-rw-r--r--Source/WebCore/html/HTMLDirectoryElement.h40
-rw-r--r--Source/WebCore/html/HTMLDirectoryElement.idl26
-rw-r--r--Source/WebCore/html/HTMLDivElement.cpp76
-rw-r--r--Source/WebCore/html/HTMLDivElement.h45
-rw-r--r--Source/WebCore/html/HTMLDivElement.idl26
-rw-r--r--Source/WebCore/html/HTMLDocument.cpp467
-rw-r--r--Source/WebCore/html/HTMLDocument.h120
-rw-r--r--Source/WebCore/html/HTMLDocument.idl64
-rw-r--r--Source/WebCore/html/HTMLElement.cpp833
-rw-r--r--Source/WebCore/html/HTMLElement.h113
-rw-r--r--Source/WebCore/html/HTMLElement.idl72
-rw-r--r--Source/WebCore/html/HTMLElementsAllInOne.cpp110
-rw-r--r--Source/WebCore/html/HTMLEmbedElement.cpp275
-rw-r--r--Source/WebCore/html/HTMLEmbedElement.h59
-rw-r--r--Source/WebCore/html/HTMLEmbedElement.idl50
-rw-r--r--Source/WebCore/html/HTMLFieldSetElement.cpp63
-rw-r--r--Source/WebCore/html/HTMLFieldSetElement.h47
-rw-r--r--Source/WebCore/html/HTMLFieldSetElement.idl31
-rw-r--r--Source/WebCore/html/HTMLFontElement.cpp185
-rw-r--r--Source/WebCore/html/HTMLFontElement.h46
-rw-r--r--Source/WebCore/html/HTMLFontElement.idl28
-rw-r--r--Source/WebCore/html/HTMLFormCollection.cpp250
-rw-r--r--Source/WebCore/html/HTMLFormCollection.h66
-rw-r--r--Source/WebCore/html/HTMLFormControlElement.cpp635
-rw-r--r--Source/WebCore/html/HTMLFormControlElement.h232
-rw-r--r--Source/WebCore/html/HTMLFormElement.cpp669
-rw-r--r--Source/WebCore/html/HTMLFormElement.h176
-rw-r--r--Source/WebCore/html/HTMLFormElement.idl48
-rw-r--r--Source/WebCore/html/HTMLFrameElement.cpp98
-rw-r--r--Source/WebCore/html/HTMLFrameElement.h57
-rw-r--r--Source/WebCore/html/HTMLFrameElement.idl54
-rw-r--r--Source/WebCore/html/HTMLFrameElementBase.cpp286
-rw-r--r--Source/WebCore/html/HTMLFrameElementBase.h97
-rw-r--r--Source/WebCore/html/HTMLFrameOwnerElement.cpp104
-rw-r--r--Source/WebCore/html/HTMLFrameOwnerElement.h77
-rw-r--r--Source/WebCore/html/HTMLFrameSetElement.cpp226
-rw-r--r--Source/WebCore/html/HTMLFrameSetElement.h102
-rw-r--r--Source/WebCore/html/HTMLFrameSetElement.idl59
-rw-r--r--Source/WebCore/html/HTMLHRElement.cpp109
-rw-r--r--Source/WebCore/html/HTMLHRElement.h44
-rw-r--r--Source/WebCore/html/HTMLHRElement.idl29
-rw-r--r--Source/WebCore/html/HTMLHeadElement.cpp50
-rw-r--r--Source/WebCore/html/HTMLHeadElement.h42
-rw-r--r--Source/WebCore/html/HTMLHeadElement.idl26
-rw-r--r--Source/WebCore/html/HTMLHeadingElement.cpp38
-rw-r--r--Source/WebCore/html/HTMLHeadingElement.h40
-rw-r--r--Source/WebCore/html/HTMLHeadingElement.idl26
-rw-r--r--Source/WebCore/html/HTMLHtmlElement.cpp81
-rw-r--r--Source/WebCore/html/HTMLHtmlElement.h48
-rw-r--r--Source/WebCore/html/HTMLHtmlElement.idl27
-rw-r--r--Source/WebCore/html/HTMLIFrameElement.cpp165
-rw-r--r--Source/WebCore/html/HTMLIFrameElement.h54
-rw-r--r--Source/WebCore/html/HTMLIFrameElement.idl50
-rw-r--r--Source/WebCore/html/HTMLImageElement.cpp403
-rw-r--r--Source/WebCore/html/HTMLImageElement.h113
-rw-r--r--Source/WebCore/html/HTMLImageElement.idl54
-rw-r--r--Source/WebCore/html/HTMLImageLoader.cpp89
-rw-r--r--Source/WebCore/html/HTMLImageLoader.h43
-rw-r--r--Source/WebCore/html/HTMLInputElement.cpp1572
-rw-r--r--Source/WebCore/html/HTMLInputElement.h319
-rw-r--r--Source/WebCore/html/HTMLInputElement.idl112
-rw-r--r--Source/WebCore/html/HTMLIsIndexElement.cpp64
-rw-r--r--Source/WebCore/html/HTMLIsIndexElement.h46
-rw-r--r--Source/WebCore/html/HTMLIsIndexElement.idl27
-rw-r--r--Source/WebCore/html/HTMLKeygenElement.cpp94
-rw-r--r--Source/WebCore/html/HTMLKeygenElement.h51
-rw-r--r--Source/WebCore/html/HTMLLIElement.cpp119
-rw-r--r--Source/WebCore/html/HTMLLIElement.h48
-rw-r--r--Source/WebCore/html/HTMLLIElement.idl27
-rw-r--r--Source/WebCore/html/HTMLLabelElement.cpp168
-rw-r--r--Source/WebCore/html/HTMLLabelElement.h59
-rw-r--r--Source/WebCore/html/HTMLLabelElement.idl30
-rw-r--r--Source/WebCore/html/HTMLLegendElement.cpp96
-rw-r--r--Source/WebCore/html/HTMLLegendElement.h49
-rw-r--r--Source/WebCore/html/HTMLLegendElement.idl29
-rw-r--r--Source/WebCore/html/HTMLLinkElement.cpp520
-rw-r--r--Source/WebCore/html/HTMLLinkElement.h156
-rw-r--r--Source/WebCore/html/HTMLLinkElement.idl43
-rw-r--r--Source/WebCore/html/HTMLMapElement.cpp146
-rw-r--r--Source/WebCore/html/HTMLMapElement.h60
-rw-r--r--Source/WebCore/html/HTMLMapElement.idl28
-rw-r--r--Source/WebCore/html/HTMLMarqueeElement.cpp200
-rw-r--r--Source/WebCore/html/HTMLMarqueeElement.h71
-rw-r--r--Source/WebCore/html/HTMLMarqueeElement.idl44
-rw-r--r--Source/WebCore/html/HTMLMediaElement.cpp2521
-rw-r--r--Source/WebCore/html/HTMLMediaElement.h395
-rw-r--r--Source/WebCore/html/HTMLMediaElement.idl85
-rw-r--r--Source/WebCore/html/HTMLMenuElement.cpp43
-rw-r--r--Source/WebCore/html/HTMLMenuElement.h40
-rw-r--r--Source/WebCore/html/HTMLMenuElement.idl26
-rw-r--r--Source/WebCore/html/HTMLMetaElement.cpp137
-rw-r--r--Source/WebCore/html/HTMLMetaElement.h52
-rw-r--r--Source/WebCore/html/HTMLMetaElement.idl29
-rw-r--r--Source/WebCore/html/HTMLMeterElement.cpp207
-rw-r--r--Source/WebCore/html/HTMLMeterElement.h75
-rw-r--r--Source/WebCore/html/HTMLMeterElement.idl40
-rw-r--r--Source/WebCore/html/HTMLModElement.cpp47
-rw-r--r--Source/WebCore/html/HTMLModElement.h43
-rw-r--r--Source/WebCore/html/HTMLModElement.idl27
-rw-r--r--Source/WebCore/html/HTMLNameCollection.cpp96
-rw-r--r--Source/WebCore/html/HTMLNameCollection.h50
-rw-r--r--Source/WebCore/html/HTMLNoScriptElement.cpp83
-rw-r--r--Source/WebCore/html/HTMLNoScriptElement.h46
-rw-r--r--Source/WebCore/html/HTMLOListElement.cpp97
-rw-r--r--Source/WebCore/html/HTMLOListElement.h50
-rw-r--r--Source/WebCore/html/HTMLOListElement.idl28
-rw-r--r--Source/WebCore/html/HTMLObjectElement.cpp505
-rw-r--r--Source/WebCore/html/HTMLObjectElement.h110
-rw-r--r--Source/WebCore/html/HTMLObjectElement.idl66
-rw-r--r--Source/WebCore/html/HTMLOptGroupElement.cpp144
-rw-r--r--Source/WebCore/html/HTMLOptGroupElement.h67
-rw-r--r--Source/WebCore/html/HTMLOptGroupElement.idl27
-rw-r--r--Source/WebCore/html/HTMLOptionElement.cpp254
-rw-r--r--Source/WebCore/html/HTMLOptionElement.h97
-rw-r--r--Source/WebCore/html/HTMLOptionElement.idl40
-rw-r--r--Source/WebCore/html/HTMLOptionsCollection.cpp90
-rw-r--r--Source/WebCore/html/HTMLOptionsCollection.h55
-rw-r--r--Source/WebCore/html/HTMLOptionsCollection.idl42
-rw-r--r--Source/WebCore/html/HTMLOutputElement.cpp137
-rw-r--r--Source/WebCore/html/HTMLOutputElement.h72
-rw-r--r--Source/WebCore/html/HTMLOutputElement.idl43
-rw-r--r--Source/WebCore/html/HTMLParagraphElement.cpp72
-rw-r--r--Source/WebCore/html/HTMLParagraphElement.h43
-rw-r--r--Source/WebCore/html/HTMLParagraphElement.idl26
-rw-r--r--Source/WebCore/html/HTMLParamElement.cpp86
-rw-r--r--Source/WebCore/html/HTMLParamElement.h54
-rw-r--r--Source/WebCore/html/HTMLParamElement.idl29
-rw-r--r--Source/WebCore/html/HTMLParserErrorCodes.cpp70
-rw-r--r--Source/WebCore/html/HTMLParserErrorCodes.h60
-rw-r--r--Source/WebCore/html/HTMLParserQuirks.h49
-rw-r--r--Source/WebCore/html/HTMLPlugInElement.cpp194
-rw-r--r--Source/WebCore/html/HTMLPlugInElement.h88
-rw-r--r--Source/WebCore/html/HTMLPlugInImageElement.cpp196
-rw-r--r--Source/WebCore/html/HTMLPlugInImageElement.h76
-rw-r--r--Source/WebCore/html/HTMLPreElement.cpp68
-rw-r--r--Source/WebCore/html/HTMLPreElement.h43
-rw-r--r--Source/WebCore/html/HTMLPreElement.idl32
-rw-r--r--Source/WebCore/html/HTMLProgressElement.cpp125
-rw-r--r--Source/WebCore/html/HTMLProgressElement.h58
-rw-r--r--Source/WebCore/html/HTMLProgressElement.idl33
-rw-r--r--Source/WebCore/html/HTMLQuoteElement.cpp56
-rw-r--r--Source/WebCore/html/HTMLQuoteElement.h45
-rw-r--r--Source/WebCore/html/HTMLQuoteElement.idl25
-rw-r--r--Source/WebCore/html/HTMLScriptElement.cpp181
-rw-r--r--Source/WebCore/html/HTMLScriptElement.h71
-rw-r--r--Source/WebCore/html/HTMLScriptElement.idl32
-rw-r--r--Source/WebCore/html/HTMLSelectElement.cpp534
-rw-r--r--Source/WebCore/html/HTMLSelectElement.h154
-rw-r--r--Source/WebCore/html/HTMLSelectElement.idl72
-rw-r--r--Source/WebCore/html/HTMLSourceElement.cpp124
-rw-r--r--Source/WebCore/html/HTMLSourceElement.h64
-rw-r--r--Source/WebCore/html/HTMLSourceElement.idl32
-rw-r--r--Source/WebCore/html/HTMLStyleElement.cpp107
-rw-r--r--Source/WebCore/html/HTMLStyleElement.h64
-rw-r--r--Source/WebCore/html/HTMLStyleElement.idl32
-rw-r--r--Source/WebCore/html/HTMLTableCaptionElement.cpp66
-rw-r--r--Source/WebCore/html/HTMLTableCaptionElement.h46
-rw-r--r--Source/WebCore/html/HTMLTableCaptionElement.idl29
-rw-r--r--Source/WebCore/html/HTMLTableCellElement.cpp190
-rw-r--r--Source/WebCore/html/HTMLTableCellElement.h73
-rw-r--r--Source/WebCore/html/HTMLTableCellElement.idl41
-rw-r--r--Source/WebCore/html/HTMLTableColElement.cpp103
-rw-r--r--Source/WebCore/html/HTMLTableColElement.h55
-rw-r--r--Source/WebCore/html/HTMLTableColElement.idl32
-rw-r--r--Source/WebCore/html/HTMLTableElement.cpp665
-rw-r--r--Source/WebCore/html/HTMLTableElement.h107
-rw-r--r--Source/WebCore/html/HTMLTableElement.idl53
-rw-r--r--Source/WebCore/html/HTMLTablePartElement.cpp100
-rw-r--r--Source/WebCore/html/HTMLTablePartElement.h46
-rw-r--r--Source/WebCore/html/HTMLTableRowElement.cpp167
-rw-r--r--Source/WebCore/html/HTMLTableRowElement.h56
-rw-r--r--Source/WebCore/html/HTMLTableRowElement.idl36
-rw-r--r--Source/WebCore/html/HTMLTableRowsCollection.cpp167
-rw-r--r--Source/WebCore/html/HTMLTableRowsCollection.h54
-rw-r--r--Source/WebCore/html/HTMLTableSectionElement.cpp157
-rw-r--r--Source/WebCore/html/HTMLTableSectionElement.h65
-rw-r--r--Source/WebCore/html/HTMLTableSectionElement.idl35
-rw-r--r--Source/WebCore/html/HTMLTagNames.in143
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.cpp436
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.h115
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.idl55
-rw-r--r--Source/WebCore/html/HTMLTitleElement.cpp101
-rw-r--r--Source/WebCore/html/HTMLTitleElement.h48
-rw-r--r--Source/WebCore/html/HTMLTitleElement.idl26
-rw-r--r--Source/WebCore/html/HTMLUListElement.cpp68
-rw-r--r--Source/WebCore/html/HTMLUListElement.h44
-rw-r--r--Source/WebCore/html/HTMLUListElement.idl27
-rw-r--r--Source/WebCore/html/HTMLVideoElement.cpp268
-rw-r--r--Source/WebCore/html/HTMLVideoElement.h93
-rw-r--r--Source/WebCore/html/HTMLVideoElement.idl46
-rw-r--r--Source/WebCore/html/HTMLViewSourceDocument.cpp317
-rw-r--r--Source/WebCore/html/HTMLViewSourceDocument.h72
-rw-r--r--Source/WebCore/html/HiddenInputType.cpp83
-rw-r--r--Source/WebCore/html/HiddenInputType.h56
-rw-r--r--Source/WebCore/html/ImageData.cpp57
-rw-r--r--Source/WebCore/html/ImageData.h60
-rw-r--r--Source/WebCore/html/ImageData.idl41
-rw-r--r--Source/WebCore/html/ImageDocument.cpp420
-rw-r--r--Source/WebCore/html/ImageDocument.h76
-rw-r--r--Source/WebCore/html/ImageInputType.cpp168
-rw-r--r--Source/WebCore/html/ImageInputType.h71
-rw-r--r--Source/WebCore/html/ImageResizerThread.cpp97
-rw-r--r--Source/WebCore/html/ImageResizerThread.h70
-rw-r--r--Source/WebCore/html/InputType.cpp767
-rw-r--r--Source/WebCore/html/InputType.h263
-rw-r--r--Source/WebCore/html/IsIndexInputType.cpp79
-rw-r--r--Source/WebCore/html/IsIndexInputType.h53
-rw-r--r--Source/WebCore/html/LabelsNodeList.cpp50
-rw-r--r--Source/WebCore/html/LabelsNodeList.h52
-rw-r--r--Source/WebCore/html/MediaDocument.cpp220
-rw-r--r--Source/WebCore/html/MediaDocument.h61
-rw-r--r--Source/WebCore/html/MediaError.h53
-rw-r--r--Source/WebCore/html/MediaError.idl34
-rw-r--r--Source/WebCore/html/MonthInputType.cpp142
-rw-r--r--Source/WebCore/html/MonthInputType.h60
-rw-r--r--Source/WebCore/html/NumberInputType.cpp281
-rw-r--r--Source/WebCore/html/NumberInputType.h77
-rw-r--r--Source/WebCore/html/PasswordInputType.cpp89
-rw-r--r--Source/WebCore/html/PasswordInputType.h56
-rw-r--r--Source/WebCore/html/PluginDocument.cpp176
-rw-r--r--Source/WebCore/html/PluginDocument.h82
-rw-r--r--Source/WebCore/html/RadioInputType.cpp196
-rw-r--r--Source/WebCore/html/RadioInputType.h60
-rw-r--r--Source/WebCore/html/RangeInputType.cpp250
-rw-r--r--Source/WebCore/html/RangeInputType.h72
-rw-r--r--Source/WebCore/html/ResetInputType.cpp76
-rw-r--r--Source/WebCore/html/ResetInputType.h53
-rw-r--r--Source/WebCore/html/SearchInputType.cpp58
-rw-r--r--Source/WebCore/html/SearchInputType.h51
-rw-r--r--Source/WebCore/html/StepRange.cpp85
-rw-r--r--Source/WebCore/html/StepRange.h68
-rw-r--r--Source/WebCore/html/SubmitInputType.cpp98
-rw-r--r--Source/WebCore/html/SubmitInputType.h56
-rw-r--r--Source/WebCore/html/TelephoneInputType.cpp58
-rw-r--r--Source/WebCore/html/TelephoneInputType.h51
-rw-r--r--Source/WebCore/html/TextDocument.cpp44
-rw-r--r--Source/WebCore/html/TextDocument.h47
-rw-r--r--Source/WebCore/html/TextFieldInputType.cpp123
-rw-r--r--Source/WebCore/html/TextFieldInputType.h60
-rw-r--r--Source/WebCore/html/TextInputType.cpp59
-rw-r--r--Source/WebCore/html/TextInputType.h51
-rw-r--r--Source/WebCore/html/TextMetrics.h51
-rw-r--r--Source/WebCore/html/TextMetrics.idl32
-rw-r--r--Source/WebCore/html/TimeInputType.cpp112
-rw-r--r--Source/WebCore/html/TimeInputType.h57
-rw-r--r--Source/WebCore/html/TimeRanges.cpp137
-rw-r--r--Source/WebCore/html/TimeRanges.h113
-rw-r--r--Source/WebCore/html/TimeRanges.idl38
-rw-r--r--Source/WebCore/html/URLInputType.cpp71
-rw-r--r--Source/WebCore/html/URLInputType.h53
-rw-r--r--Source/WebCore/html/ValidationMessage.cpp70
-rw-r--r--Source/WebCore/html/ValidationMessage.h61
-rw-r--r--Source/WebCore/html/ValidityState.cpp216
-rw-r--r--Source/WebCore/html/ValidityState.h68
-rw-r--r--Source/WebCore/html/ValidityState.idl36
-rw-r--r--Source/WebCore/html/VoidCallback.h45
-rw-r--r--Source/WebCore/html/VoidCallback.idl30
-rw-r--r--Source/WebCore/html/WeekInputType.cpp100
-rw-r--r--Source/WebCore/html/WeekInputType.h57
-rw-r--r--Source/WebCore/html/canvas/ArrayBuffer.cpp104
-rw-r--r--Source/WebCore/html/canvas/ArrayBuffer.h56
-rw-r--r--Source/WebCore/html/canvas/ArrayBuffer.idl38
-rw-r--r--Source/WebCore/html/canvas/ArrayBufferView.cpp109
-rw-r--r--Source/WebCore/html/canvas/ArrayBufferView.h132
-rw-r--r--Source/WebCore/html/canvas/ArrayBufferView.idl32
-rw-r--r--Source/WebCore/html/canvas/CanvasContextAttributes.cpp41
-rw-r--r--Source/WebCore/html/canvas/CanvasContextAttributes.h48
-rw-r--r--Source/WebCore/html/canvas/CanvasGradient.cpp66
-rw-r--r--Source/WebCore/html/canvas/CanvasGradient.h70
-rw-r--r--Source/WebCore/html/canvas/CanvasGradient.idl39
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.cpp66
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.h62
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.idl36
-rw-r--r--Source/WebCore/html/canvas/CanvasPixelArray.cpp54
-rw-r--r--Source/WebCore/html/canvas/CanvasPixelArray.h78
-rw-r--r--Source/WebCore/html/canvas/CanvasPixelArray.idl42
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.cpp98
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.h80
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.idl38
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp1902
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.h304
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.idl181
-rw-r--r--Source/WebCore/html/canvas/CanvasStyle.cpp300
-rw-r--r--Source/WebCore/html/canvas/CanvasStyle.h104
-rw-r--r--Source/WebCore/html/canvas/CheckedInt.h527
-rwxr-xr-xSource/WebCore/html/canvas/DataView.cpp235
-rwxr-xr-xSource/WebCore/html/canvas/DataView.h92
-rwxr-xr-xSource/WebCore/html/canvas/DataView.idl83
-rw-r--r--Source/WebCore/html/canvas/Float32Array.cpp67
-rw-r--r--Source/WebCore/html/canvas/Float32Array.h75
-rw-r--r--Source/WebCore/html/canvas/Float32Array.idl49
-rw-r--r--Source/WebCore/html/canvas/Int16Array.cpp66
-rw-r--r--Source/WebCore/html/canvas/Int16Array.h60
-rw-r--r--Source/WebCore/html/canvas/Int16Array.idl48
-rw-r--r--Source/WebCore/html/canvas/Int32Array.cpp67
-rw-r--r--Source/WebCore/html/canvas/Int32Array.h61
-rw-r--r--Source/WebCore/html/canvas/Int32Array.idl49
-rw-r--r--Source/WebCore/html/canvas/Int8Array.cpp67
-rw-r--r--Source/WebCore/html/canvas/Int8Array.h61
-rw-r--r--Source/WebCore/html/canvas/Int8Array.idl49
-rw-r--r--Source/WebCore/html/canvas/IntegralTypedArrayBase.h72
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloat.cpp54
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloat.h48
-rw-r--r--Source/WebCore/html/canvas/OESTextureFloat.idl29
-rw-r--r--Source/WebCore/html/canvas/TypedArrayBase.h124
-rw-r--r--Source/WebCore/html/canvas/Uint16Array.cpp67
-rw-r--r--Source/WebCore/html/canvas/Uint16Array.h61
-rw-r--r--Source/WebCore/html/canvas/Uint16Array.idl49
-rw-r--r--Source/WebCore/html/canvas/Uint32Array.cpp67
-rw-r--r--Source/WebCore/html/canvas/Uint32Array.h61
-rw-r--r--Source/WebCore/html/canvas/Uint32Array.idl49
-rw-r--r--Source/WebCore/html/canvas/Uint8Array.cpp67
-rw-r--r--Source/WebCore/html/canvas/Uint8Array.h63
-rw-r--r--Source/WebCore/html/canvas/Uint8Array.idl49
-rw-r--r--Source/WebCore/html/canvas/WebGLActiveInfo.h62
-rw-r--r--Source/WebCore/html/canvas/WebGLActiveInfo.idl36
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.cpp207
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.h105
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.idl29
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.cpp117
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.h82
-rw-r--r--Source/WebCore/html/canvas/WebGLContextAttributes.idl38
-rw-r--r--Source/WebCore/html/canvas/WebGLContextEvent.cpp54
-rw-r--r--Source/WebCore/html/canvas/WebGLContextEvent.h58
-rw-r--r--Source/WebCore/html/canvas/WebGLContextEvent.idl36
-rw-r--r--Source/WebCore/html/canvas/WebGLExtension.cpp44
-rw-r--r--Source/WebCore/html/canvas/WebGLExtension.h50
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.cpp357
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.h99
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.idl29
-rw-r--r--Source/WebCore/html/canvas/WebGLGetInfo.cpp232
-rw-r--r--Source/WebCore/html/canvas/WebGLGetInfo.h133
-rw-r--r--Source/WebCore/html/canvas/WebGLObject.cpp71
-rw-r--r--Source/WebCore/html/canvas/WebGLObject.h97
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.cpp160
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.h89
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.idl29
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.cpp60
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.h85
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.idl29
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.cpp4424
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.h607
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.idl669
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.cpp55
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.h56
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.idl29
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.cpp355
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.h128
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.idl29
-rw-r--r--Source/WebCore/html/canvas/WebGLUniformLocation.cpp67
-rw-r--r--Source/WebCore/html/canvas/WebGLUniformLocation.h59
-rw-r--r--Source/WebCore/html/canvas/WebGLUniformLocation.idl30
-rw-r--r--Source/WebCore/html/canvas/WebKitLoseContext.cpp63
-rw-r--r--Source/WebCore/html/canvas/WebKitLoseContext.h54
-rw-r--r--Source/WebCore/html/canvas/WebKitLoseContext.idl30
-rw-r--r--Source/WebCore/html/parser/CSSPreloadScanner.cpp195
-rw-r--r--Source/WebCore/html/parser/CSSPreloadScanner.h71
-rw-r--r--Source/WebCore/html/parser/HTMLConstructionSite.cpp464
-rw-r--r--Source/WebCore/html/parser/HTMLConstructionSite.h148
-rw-r--r--Source/WebCore/html/parser/HTMLDocumentParser.cpp549
-rw-r--r--Source/WebCore/html/parser/HTMLDocumentParser.h150
-rw-r--r--Source/WebCore/html/parser/HTMLElementStack.cpp569
-rw-r--r--Source/WebCore/html/parser/HTMLElementStack.h156
-rw-r--r--Source/WebCore/html/parser/HTMLEntityNames.in2138
-rw-r--r--Source/WebCore/html/parser/HTMLEntityParser.cpp272
-rw-r--r--Source/WebCore/html/parser/HTMLEntityParser.h41
-rw-r--r--Source/WebCore/html/parser/HTMLEntitySearch.cpp134
-rw-r--r--Source/WebCore/html/parser/HTMLEntitySearch.h75
-rw-r--r--Source/WebCore/html/parser/HTMLEntityTable.h52
-rw-r--r--Source/WebCore/html/parser/HTMLFormattingElementList.cpp134
-rw-r--r--Source/WebCore/html/parser/HTMLFormattingElementList.h134
-rw-r--r--Source/WebCore/html/parser/HTMLInputStream.h164
-rw-r--r--Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp200
-rw-r--r--Source/WebCore/html/parser/HTMLMetaCharsetParser.h73
-rw-r--r--Source/WebCore/html/parser/HTMLParserIdioms.cpp221
-rw-r--r--Source/WebCore/html/parser/HTMLParserIdioms.h76
-rw-r--r--Source/WebCore/html/parser/HTMLParserScheduler.cpp114
-rw-r--r--Source/WebCore/html/parser/HTMLParserScheduler.h94
-rw-r--r--Source/WebCore/html/parser/HTMLPreloadScanner.cpp194
-rw-r--r--Source/WebCore/html/parser/HTMLPreloadScanner.h64
-rw-r--r--Source/WebCore/html/parser/HTMLScriptRunner.cpp321
-rw-r--r--Source/WebCore/html/parser/HTMLScriptRunner.h102
-rw-r--r--Source/WebCore/html/parser/HTMLScriptRunnerHost.h54
-rw-r--r--Source/WebCore/html/parser/HTMLToken.h526
-rw-r--r--Source/WebCore/html/parser/HTMLTokenizer.cpp1698
-rw-r--r--Source/WebCore/html/parser/HTMLTokenizer.h316
-rw-r--r--Source/WebCore/html/parser/HTMLTreeBuilder.cpp2822
-rw-r--r--Source/WebCore/html/parser/HTMLTreeBuilder.h267
-rw-r--r--Source/WebCore/html/parser/HTMLViewSourceParser.cpp106
-rw-r--r--Source/WebCore/html/parser/HTMLViewSourceParser.h79
-rw-r--r--Source/WebCore/html/parser/NestingLevelIncrementer.h50
-rw-r--r--Source/WebCore/html/parser/TextDocumentParser.cpp72
-rw-r--r--Source/WebCore/html/parser/TextDocumentParser.h52
-rw-r--r--Source/WebCore/html/parser/TextViewSourceParser.cpp43
-rw-r--r--Source/WebCore/html/parser/TextViewSourceParser.h47
-rwxr-xr-xSource/WebCore/html/parser/create-html-entity-table178
-rw-r--r--Source/WebCore/html/shadow/SliderThumbElement.cpp142
-rw-r--r--Source/WebCore/html/shadow/SliderThumbElement.h75
518 files changed, 72354 insertions, 0 deletions
diff --git a/Source/WebCore/html/AsyncImageResizer.cpp b/Source/WebCore/html/AsyncImageResizer.cpp
new file mode 100644
index 0000000..4bb74c9
--- /dev/null
+++ b/Source/WebCore/html/AsyncImageResizer.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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:
+ *
+ * * 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(IMAGE_RESIZER)
+
+#include "AsyncImageResizer.h"
+
+#include "CachedImage.h"
+#include "ImageResizerThread.h"
+#include "SharedBuffer.h"
+#include <utility>
+
+namespace WebCore {
+
+PassRefPtr<AsyncImageResizer> AsyncImageResizer::create(CachedImage* cachedImage, OutputType outputType, IntSize desiredBounds, ScriptValue successCallback, ScriptValue errorCallback, float quality, AspectRatioOption aspectRatioOption, OrientationOption orientationOption)
+{
+ return adoptRef(new AsyncImageResizer(cachedImage, outputType, desiredBounds, successCallback, errorCallback, quality, aspectRatioOption, orientationOption));
+}
+
+AsyncImageResizer::AsyncImageResizer(CachedImage* cachedImage, OutputType outputType, IntSize desiredBounds, ScriptValue successCallback, ScriptValue errorCallback, float quality, AspectRatioOption aspectRatioOption, OrientationOption orientationOption)
+ : m_cachedImage(cachedImage)
+ , m_successCallback(successCallback)
+ , m_errorCallback(errorCallback)
+ , m_outputType(outputType)
+ , m_desiredBounds(desiredBounds)
+ , m_quality(quality)
+ , m_aspectRatioOption(aspectRatioOption)
+ , m_orientationOption(orientationOption)
+{
+ ASSERT(m_successCallback.isObject());
+ m_cachedImage->addClient(this);
+}
+
+AsyncImageResizer::~AsyncImageResizer()
+{
+}
+
+void AsyncImageResizer::notifyFinished(CachedResource* cachedResource)
+{
+ RefPtr<SharedBuffer> imageData = cachedResource->data()->copy();
+ cachedResource->removeClient(this);
+ CallbackInfo* callbackInfo = new CallbackInfo(this);
+ if (!ImageResizerThread::start(imageData, callbackInfo, m_outputType, m_desiredBounds, m_quality, m_aspectRatioOption, m_orientationOption))
+ resizeError();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(IMAGE_RESIZER)
diff --git a/Source/WebCore/html/AsyncImageResizer.h b/Source/WebCore/html/AsyncImageResizer.h
new file mode 100644
index 0000000..add070a
--- /dev/null
+++ b/Source/WebCore/html/AsyncImageResizer.h
@@ -0,0 +1,108 @@
+/*
+ * 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:
+ *
+ * * 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 AsyncImageResizer_h
+#define AsyncImageResizer_h
+
+#if ENABLE(IMAGE_RESIZER)
+
+#include "Blob.h"
+#include "CachedResourceClient.h"
+#include "IntSize.h"
+#include "ScriptValue.h"
+
+namespace WebCore {
+
+class CachedImage;
+class ImageResizerThread;
+
+// AsyncImageResizer waits for the CachedImage that is passed in to load completely,
+// then starts an ImageResizerThread to resize the image. Once created, ImageResizerThread
+// becomes in charge of its own lifetime and that of AsyncImageResizer. After the callbacks
+// occur, both objects are destroyed. If the document is destroyed during resizing,
+// AsyncImageResizer will receive a notification and subsequently block the callbacks from
+// occurring.
+class AsyncImageResizer : public CachedResourceClient, public RefCounted<AsyncImageResizer> {
+public:
+ struct CallbackInfo {
+ CallbackInfo(PassRefPtr<AsyncImageResizer> asyncImageResizer)
+ : asyncImageResizer(asyncImageResizer)
+ , blob(0)
+ {
+ }
+
+ RefPtr<AsyncImageResizer> asyncImageResizer;
+ RefPtr<Blob> blob;
+ };
+
+ enum OutputType {
+ JPEG,
+ PNG
+ };
+
+ enum AspectRatioOption {
+ PreserveAspectRatio,
+ IgnoreAspectRatio
+ };
+
+ enum OrientationOption {
+ CorrectOrientation,
+ IgnoreOrientation
+ };
+
+ static PassRefPtr<AsyncImageResizer> create(CachedImage*, OutputType, IntSize desiredBounds, ScriptValue successCallback, ScriptValue errorCallback, float quality, AspectRatioOption, OrientationOption);
+ ~AsyncImageResizer();
+
+ // FIXME: Insert override function for notification of document destruction (change m_callbacksOk).
+
+ void resizeComplete(RefPtr<Blob>) { /* FIXME: Not yet implemented. */ }
+ void resizeError() { /* FIXME: Not yet implemented. */ }
+
+private:
+ AsyncImageResizer(CachedImage*, OutputType, IntSize desiredBounds, ScriptValue successCallback, ScriptValue errorCallback, float quality, AspectRatioOption, OrientationOption);
+ virtual void notifyFinished(CachedResource*);
+
+ CachedImage* m_cachedImage;
+ ScriptValue m_successCallback;
+ ScriptValue m_errorCallback;
+
+ // Parameters to pass into ImageResizerThread.
+ OutputType m_outputType;
+ IntSize m_desiredBounds;
+ float m_quality;
+ AspectRatioOption m_aspectRatioOption;
+ OrientationOption m_orientationOption;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(IMAGE_RESIZER)
+
+#endif // AsyncImageResizer_h
diff --git a/Source/WebCore/html/BaseButtonInputType.cpp b/Source/WebCore/html/BaseButtonInputType.cpp
new file mode 100644
index 0000000..93fe873
--- /dev/null
+++ b/Source/WebCore/html/BaseButtonInputType.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 "BaseButtonInputType.h"
+
+#include "HTMLInputElement.h"
+#include "KeyboardEvent.h"
+#include "RenderButton.h"
+
+namespace WebCore {
+
+bool BaseButtonInputType::appendFormData(FormDataList&, bool) const
+{
+ // Buttons except overridden types are never successful.
+ return false;
+}
+
+void BaseButtonInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+ const String& key = event->keyIdentifier();
+ if (key == "U+0020") {
+ element()->setActive(true, true);
+ // No setDefaultHandled(), because IE dispatches a keypress in this case
+ // and the caller will only dispatch a keypress if we don't call setDefaultHandled().
+ }
+}
+
+void BaseButtonInputType::handleKeypressEvent(KeyboardEvent* event)
+{
+ int charCode = event->charCode();
+ if (charCode == '\r') {
+ element()->dispatchSimulatedClick(event);
+ event->setDefaultHandled();
+ return;
+ }
+ if (charCode == ' ') {
+ // Prevent scrolling down the page.
+ event->setDefaultHandled();
+ }
+}
+
+void BaseButtonInputType::handleKeyupEvent(KeyboardEvent* event)
+{
+ const String& key = event->keyIdentifier();
+ if (key != "U+0020")
+ return;
+ // Simulate mouse click for spacebar for button types.
+ dispatchSimulatedClickIfActive(event);
+}
+
+RenderObject* BaseButtonInputType::createRenderer(RenderArena* arena, RenderStyle*) const
+{
+ return new (arena) RenderButton(element());
+}
+
+// FIXME: Could share this with BaseCheckableInputType and RangeInputType if we had a common base class.
+void BaseButtonInputType::accessKeyAction(bool sendToAnyElement)
+{
+ InputType::accessKeyAction(sendToAnyElement);
+
+ // Send mouse button events if the caller specified sendToAnyElement.
+ // FIXME: The comment above is no good. It says what we do, but not why.
+ element()->dispatchSimulatedClick(0, sendToAnyElement);
+}
+
+bool BaseButtonInputType::storesValueSeparateFromAttribute()
+{
+ return false;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/BaseButtonInputType.h b/Source/WebCore/html/BaseButtonInputType.h
new file mode 100644
index 0000000..1607f3c
--- /dev/null
+++ b/Source/WebCore/html/BaseButtonInputType.h
@@ -0,0 +1,55 @@
+/*
+ * 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:
+ *
+ * * 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 BaseButtonInputType_h
+#define BaseButtonInputType_h
+
+#include "InputType.h"
+
+namespace WebCore {
+
+// Base of button, file, image, reset, and submit types.
+class BaseButtonInputType : public InputType {
+protected:
+ BaseButtonInputType(HTMLInputElement* element) : InputType(element) { }
+
+private:
+ virtual bool appendFormData(FormDataList&, bool) const;
+ virtual void handleKeydownEvent(KeyboardEvent*);
+ virtual void handleKeypressEvent(KeyboardEvent*);
+ virtual void handleKeyupEvent(KeyboardEvent*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
+ virtual void accessKeyAction(bool sendToAnyElement);
+ virtual bool storesValueSeparateFromAttribute();
+};
+
+} // namespace WebCore
+
+#endif // BaseButtonInputType_h
diff --git a/Source/WebCore/html/BaseCheckableInputType.cpp b/Source/WebCore/html/BaseCheckableInputType.cpp
new file mode 100644
index 0000000..b08bae3
--- /dev/null
+++ b/Source/WebCore/html/BaseCheckableInputType.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 "BaseCheckableInputType.h"
+
+#include "FormDataList.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "KeyboardEvent.h"
+#include "RegularExpression.h"
+
+namespace WebCore {
+
+bool BaseCheckableInputType::saveFormControlState(String& result) const
+{
+ result = element()->checked() ? "on" : "off";
+ return true;
+}
+
+void BaseCheckableInputType::restoreFormControlState(const String& state) const
+{
+ element()->setChecked(state == "on");
+}
+
+bool BaseCheckableInputType::appendFormData(FormDataList& encoding, bool) const
+{
+ if (!element()->checked())
+ return false;
+ encoding.appendData(element()->name(), element()->value());
+ return true;
+}
+
+void BaseCheckableInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+ const String& key = event->keyIdentifier();
+ if (key == "U+0020") {
+ element()->setActive(true, true);
+ // No setDefaultHandled(), because IE dispatches a keypress in this case
+ // and the caller will only dispatch a keypress if we don't call setDefaultHandled().
+ }
+}
+
+void BaseCheckableInputType::handleKeypressEvent(KeyboardEvent* event)
+{
+ if (event->charCode() == ' ') {
+ // Prevent scrolling down the page.
+ event->setDefaultHandled();
+ }
+}
+
+bool BaseCheckableInputType::canSetStringValue() const
+{
+ return false;
+}
+
+// FIXME: Could share this with BaseButtonInputType and RangeInputType if we had a common base class.
+void BaseCheckableInputType::accessKeyAction(bool sendToAnyElement)
+{
+ InputType::accessKeyAction(sendToAnyElement);
+
+ // Send mouse button events if the caller specified sendToAnyElement.
+ // FIXME: The comment above is no good. It says what we do, but not why.
+ element()->dispatchSimulatedClick(0, sendToAnyElement);
+}
+
+String BaseCheckableInputType::fallbackValue()
+{
+ return element()->checked() ? "on" : "";
+}
+
+bool BaseCheckableInputType::storesValueSeparateFromAttribute()
+{
+ return false;
+}
+
+bool BaseCheckableInputType::isCheckable()
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/BaseCheckableInputType.h b/Source/WebCore/html/BaseCheckableInputType.h
new file mode 100644
index 0000000..2515003
--- /dev/null
+++ b/Source/WebCore/html/BaseCheckableInputType.h
@@ -0,0 +1,58 @@
+/*
+ * 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:
+ *
+ * * 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 BaseCheckableInputType_h
+#define BaseCheckableInputType_h
+
+#include "InputType.h"
+
+namespace WebCore {
+
+// Base of checkbox and radio types.
+class BaseCheckableInputType : public InputType {
+protected:
+ BaseCheckableInputType(HTMLInputElement* element) : InputType(element) { }
+ virtual void handleKeydownEvent(KeyboardEvent*);
+
+private:
+ virtual bool saveFormControlState(String&) const;
+ virtual void restoreFormControlState(const String&) const;
+ virtual bool appendFormData(FormDataList&, bool) const;
+ virtual void handleKeypressEvent(KeyboardEvent*);
+ virtual bool canSetStringValue() const;
+ virtual void accessKeyAction(bool sendToAnyElement);
+ virtual String fallbackValue();
+ virtual bool storesValueSeparateFromAttribute();
+ virtual bool isCheckable();
+};
+
+} // namespace WebCore
+
+#endif // BaseCheckableInputType_h
diff --git a/Source/WebCore/html/BaseDateAndTimeInputType.cpp b/Source/WebCore/html/BaseDateAndTimeInputType.cpp
new file mode 100644
index 0000000..b672e51
--- /dev/null
+++ b/Source/WebCore/html/BaseDateAndTimeInputType.cpp
@@ -0,0 +1,182 @@
+/*
+ * 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:
+ *
+ * * 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 "BaseDateAndTimeInputType.h"
+
+#include "DateComponents.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "KeyboardEvent.h"
+#include <limits>
+#include <wtf/CurrentTime.h>
+#include <wtf/DateMath.h>
+#include <wtf/MathExtras.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+using namespace std;
+
+static const double msecPerMinute = 60 * 1000;
+static const double msecPerSecond = 1000;
+
+double BaseDateAndTimeInputType::valueAsDate() const
+{
+ return parseToDouble(element()->value(), DateComponents::invalidMilliseconds());
+}
+
+void BaseDateAndTimeInputType::setValueAsDate(double value, ExceptionCode&) const
+{
+ element()->setValue(serialize(value));
+}
+
+double BaseDateAndTimeInputType::valueAsNumber() const
+{
+ return parseToDouble(element()->value(), numeric_limits<double>::quiet_NaN());
+}
+
+void BaseDateAndTimeInputType::setValueAsNumber(double newValue, ExceptionCode&) const
+{
+ element()->setValue(serialize(newValue));
+}
+
+bool BaseDateAndTimeInputType::typeMismatchFor(const String& value) const
+{
+ return !value.isEmpty() && !parseToDateComponents(value, 0);
+}
+
+bool BaseDateAndTimeInputType::typeMismatch() const
+{
+ return typeMismatchFor(element()->value());
+}
+
+bool BaseDateAndTimeInputType::rangeUnderflow(const String& value) const
+{
+ const double nan = numeric_limits<double>::quiet_NaN();
+ double doubleValue = parseToDouble(value, nan);
+ return isfinite(doubleValue) && doubleValue < minimum();
+}
+
+bool BaseDateAndTimeInputType::rangeOverflow(const String& value) const
+{
+ const double nan = numeric_limits<double>::quiet_NaN();
+ double doubleValue = parseToDouble(value, nan);
+ return isfinite(doubleValue) && doubleValue > maximum();
+}
+
+bool BaseDateAndTimeInputType::supportsRangeLimitation() const
+{
+ return true;
+}
+
+double BaseDateAndTimeInputType::defaultValueForStepUp() const
+{
+ double ms = currentTimeMS();
+ double utcOffset = calculateUTCOffset();
+ double dstOffset = calculateDSTOffset(ms, utcOffset);
+ int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
+ return ms + (offset * msPerMinute);
+}
+
+bool BaseDateAndTimeInputType::stepMismatch(const String& value, double step) const
+{
+ const double nan = numeric_limits<double>::quiet_NaN();
+ double doubleValue = parseToDouble(value, nan);
+ doubleValue = fabs(doubleValue - stepBase());
+ if (!isfinite(doubleValue))
+ return false;
+ ASSERT(round(doubleValue) == doubleValue);
+ ASSERT(round(step) == step);
+ return fmod(doubleValue, step);
+}
+
+double BaseDateAndTimeInputType::stepBase() const
+{
+ return parseToDouble(element()->fastGetAttribute(minAttr), defaultStepBase());
+}
+
+void BaseDateAndTimeInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+ handleKeydownEventForSpinButton(event);
+ if (!event->defaultHandled())
+ TextFieldInputType::handleKeydownEvent(event);
+}
+
+void BaseDateAndTimeInputType::handleWheelEvent(WheelEvent* event)
+{
+ handleWheelEventForSpinButton(event);
+}
+
+double BaseDateAndTimeInputType::parseToDouble(const String& src, double defaultValue) const
+{
+ DateComponents date;
+ if (!parseToDateComponents(src, &date))
+ return defaultValue;
+ double msec = date.millisecondsSinceEpoch();
+ ASSERT(isfinite(msec));
+ return msec;
+}
+
+bool BaseDateAndTimeInputType::parseToDateComponents(const String& source, DateComponents* out) const
+{
+ if (source.isEmpty())
+ return false;
+ DateComponents ignoredResult;
+ if (!out)
+ out = &ignoredResult;
+ return parseToDateComponentsInternal(source.characters(), source.length(), out);
+}
+
+String BaseDateAndTimeInputType::serialize(double value) const
+{
+ if (!isfinite(value))
+ return String();
+ DateComponents date;
+ if (!setMillisecondToDateComponents(value, &date))
+ return String();
+ double step;
+ if (!element()->getAllowedValueStep(&step))
+ return date.toString();
+ if (!fmod(step, msecPerMinute))
+ return date.toString(DateComponents::None);
+ if (!fmod(step, msecPerSecond))
+ return date.toString(DateComponents::Second);
+ return date.toString(DateComponents::Millisecond);
+}
+
+bool BaseDateAndTimeInputType::hasSpinButton()
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/BaseDateAndTimeInputType.h b/Source/WebCore/html/BaseDateAndTimeInputType.h
new file mode 100644
index 0000000..867115d
--- /dev/null
+++ b/Source/WebCore/html/BaseDateAndTimeInputType.h
@@ -0,0 +1,69 @@
+/*
+ * 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:
+ *
+ * * 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 BaseDateAndTimeInputType_h
+#define BaseDateAndTimeInputType_h
+
+#include "TextFieldInputType.h"
+#include <wtf/unicode/Unicode.h>
+
+namespace WebCore {
+
+// A super class of date, datetime, datetime-local, month, time, and week types.
+class BaseDateAndTimeInputType : public TextFieldInputType {
+protected:
+ BaseDateAndTimeInputType(HTMLInputElement* element) : TextFieldInputType(element) { }
+ virtual double parseToDouble(const String&, double) const;
+ virtual bool parseToDateComponents(const String&, DateComponents*) const;
+
+private:
+ virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const = 0;
+ virtual bool setMillisecondToDateComponents(double, DateComponents*) const = 0;
+ virtual double valueAsDate() const;
+ virtual void setValueAsDate(double, ExceptionCode&) const;
+ virtual double valueAsNumber() const;
+ virtual void setValueAsNumber(double, ExceptionCode&) const;
+ virtual bool typeMismatchFor(const String&) const;
+ virtual bool typeMismatch() const;
+ virtual bool rangeUnderflow(const String&) const;
+ virtual bool rangeOverflow(const String&) const;
+ virtual bool supportsRangeLimitation() const;
+ virtual double defaultValueForStepUp() const;
+ virtual bool stepMismatch(const String&, double) const;
+ virtual double stepBase() const;
+ virtual void handleKeydownEvent(KeyboardEvent*);
+ virtual void handleWheelEvent(WheelEvent*);
+ virtual String serialize(double) const;
+ virtual bool hasSpinButton();
+};
+
+} // namespace WebCore
+
+#endif // BaseDateAndTimeInputType_h
diff --git a/Source/WebCore/html/BaseTextInputType.cpp b/Source/WebCore/html/BaseTextInputType.cpp
new file mode 100644
index 0000000..3e57ace
--- /dev/null
+++ b/Source/WebCore/html/BaseTextInputType.cpp
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * Copyright (C) 2009 Michelangelo De Simone <micdesim@gmail.com>
+ * Copyright (C) 2010 Google 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "BaseTextInputType.h"
+
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "RegularExpression.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+bool BaseTextInputType::isTextType() const
+{
+ return true;
+}
+
+bool BaseTextInputType::patternMismatch(const String& value) const
+{
+ const AtomicString& pattern = element()->fastGetAttribute(patternAttr);
+ // Empty values can't be mismatched
+ if (pattern.isEmpty() || value.isEmpty())
+ return false;
+ int matchLength = 0;
+ int valueLength = value.length();
+ int matchOffset = RegularExpression(pattern, TextCaseSensitive).match(value, 0, &matchLength);
+ return matchOffset || matchLength != valueLength;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/BaseTextInputType.h b/Source/WebCore/html/BaseTextInputType.h
new file mode 100644
index 0000000..874e2a7
--- /dev/null
+++ b/Source/WebCore/html/BaseTextInputType.h
@@ -0,0 +1,51 @@
+/*
+ * 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:
+ *
+ * * 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 BaseTextInputType_h
+#define BaseTextInputType_h
+
+#include "TextFieldInputType.h"
+
+namespace WebCore {
+
+// Base of email, password, search, tel, text, and URL types.
+// They support maxlength, selection functions, and so on.
+class BaseTextInputType : public TextFieldInputType {
+protected:
+ BaseTextInputType(HTMLInputElement* element) : TextFieldInputType(element) { }
+
+private:
+ virtual bool isTextType() const;
+ virtual bool patternMismatch(const String&) const;
+};
+
+} // namespace WebCore
+
+#endif // BaseTextInputType_h
diff --git a/Source/WebCore/html/ButtonInputType.cpp b/Source/WebCore/html/ButtonInputType.cpp
new file mode 100644
index 0000000..3af4720
--- /dev/null
+++ b/Source/WebCore/html/ButtonInputType.cpp
@@ -0,0 +1,58 @@
+/*
+ * 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:
+ *
+ * * 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 "ButtonInputType.h"
+
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<InputType> ButtonInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new ButtonInputType(element));
+}
+
+const AtomicString& ButtonInputType::formControlType() const
+{
+ return InputTypeNames::button();
+}
+
+bool ButtonInputType::supportsValidation() const
+{
+ return false;
+}
+
+bool ButtonInputType::isTextButton() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/ButtonInputType.h b/Source/WebCore/html/ButtonInputType.h
new file mode 100644
index 0000000..f6f87a6
--- /dev/null
+++ b/Source/WebCore/html/ButtonInputType.h
@@ -0,0 +1,51 @@
+/*
+ * 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:
+ *
+ * * 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 ButtonInputType_h
+#define ButtonInputType_h
+
+#include "BaseButtonInputType.h"
+
+namespace WebCore {
+
+class ButtonInputType : public BaseButtonInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ ButtonInputType(HTMLInputElement* element) : BaseButtonInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool supportsValidation() const;
+ virtual bool isTextButton() const;
+};
+
+} // namespace WebCore
+
+#endif // ButtonInputType_h
diff --git a/Source/WebCore/html/CheckboxInputType.cpp b/Source/WebCore/html/CheckboxInputType.cpp
new file mode 100644
index 0000000..39f9c7b
--- /dev/null
+++ b/Source/WebCore/html/CheckboxInputType.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 "CheckboxInputType.h"
+
+#include "HTMLInputElement.h"
+#include "KeyboardEvent.h"
+#include "LocalizedStrings.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<InputType> CheckboxInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new CheckboxInputType(element));
+}
+
+const AtomicString& CheckboxInputType::formControlType() const
+{
+ return InputTypeNames::checkbox();
+}
+
+bool CheckboxInputType::valueMissing(const String&) const
+{
+ return !element()->checked();
+}
+
+String CheckboxInputType::valueMissingText() const
+{
+ return validationMessageValueMissingForCheckboxText();
+}
+
+void CheckboxInputType::handleKeyupEvent(KeyboardEvent* event)
+{
+ const String& key = event->keyIdentifier();
+ if (key != "U+0020")
+ return;
+ dispatchSimulatedClickIfActive(event);
+}
+
+PassOwnPtr<ClickHandlingState> CheckboxInputType::willDispatchClick()
+{
+ // An event handler can use preventDefault or "return false" to reverse the checking we do here.
+ // The ClickHandlingState object contains what we need to undo what we did here in didDispatchClick.
+
+ OwnPtr<ClickHandlingState> state = adoptPtr(new ClickHandlingState);
+
+ state->checked = element()->checked();
+ state->indeterminate = element()->indeterminate();
+
+ if (state->indeterminate)
+ element()->setIndeterminate(false);
+ else
+ element()->setChecked(!state->checked, true);
+
+ return state.release();
+}
+
+void CheckboxInputType::didDispatchClick(Event* event, const ClickHandlingState& state)
+{
+ if (event->defaultPrevented() || event->defaultHandled()) {
+ element()->setIndeterminate(state.indeterminate);
+ element()->setChecked(state.checked);
+ }
+
+ // The work we did in willDispatchClick was default handling.
+ event->setDefaultHandled();
+}
+
+bool CheckboxInputType::isCheckbox() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/CheckboxInputType.h b/Source/WebCore/html/CheckboxInputType.h
new file mode 100644
index 0000000..76725e7
--- /dev/null
+++ b/Source/WebCore/html/CheckboxInputType.h
@@ -0,0 +1,55 @@
+/*
+ * 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:
+ *
+ * * 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 CheckboxInputType_h
+#define CheckboxInputType_h
+
+#include "BaseCheckableInputType.h"
+
+namespace WebCore {
+
+class CheckboxInputType : public BaseCheckableInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ CheckboxInputType(HTMLInputElement* element) : BaseCheckableInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool valueMissing(const String&) const;
+ virtual String valueMissingText() const;
+ virtual void handleKeyupEvent(KeyboardEvent*);
+ virtual PassOwnPtr<ClickHandlingState> willDispatchClick();
+ virtual void didDispatchClick(Event*, const ClickHandlingState&);
+ virtual bool isCheckbox() const;
+};
+
+} // namespace WebCore
+
+#endif // CheckboxInputType_h
diff --git a/Source/WebCore/html/ClassList.cpp b/Source/WebCore/html/ClassList.cpp
new file mode 100644
index 0000000..578601b
--- /dev/null
+++ b/Source/WebCore/html/ClassList.cpp
@@ -0,0 +1,146 @@
+/*
+ * 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. 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 "ClassList.h"
+
+#include "Element.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "SpaceSplitString.h"
+#include <wtf/text/StringBuilder.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+ClassList::ClassList(Element* element)
+ : m_element(element)
+{
+ if (m_element->document()->inQuirksMode())
+ m_classNamesForQuirksMode.set(m_element->fastGetAttribute(classAttr), false);
+}
+
+void ClassList::ref()
+{
+ m_element->ref();
+}
+
+void ClassList::deref()
+{
+ m_element->deref();
+}
+
+unsigned ClassList::length() const
+{
+ return m_element->hasClass() ? classNames().size() : 0;
+}
+
+const AtomicString ClassList::item(unsigned index) const
+{
+ if (index >= length())
+ return AtomicString();
+ return classNames()[index];
+}
+
+bool ClassList::contains(const AtomicString& token, ExceptionCode& ec) const
+{
+ if (!validateToken(token, ec))
+ return false;
+ return containsInternal(token);
+}
+
+bool ClassList::containsInternal(const AtomicString& token) const
+{
+ return m_element->hasClass() && classNames().contains(token);
+}
+
+void ClassList::add(const AtomicString& token, ExceptionCode& ec)
+{
+ if (!validateToken(token, ec))
+ return;
+ addInternal(token);
+}
+
+void ClassList::addInternal(const AtomicString& token)
+{
+ const AtomicString& oldClassName(m_element->fastGetAttribute(classAttr));
+ if (oldClassName.isEmpty())
+ m_element->setAttribute(classAttr, token);
+ else if (!containsInternal(token)) {
+ const AtomicString& newClassName(addToken(oldClassName, token));
+ m_element->setAttribute(classAttr, newClassName);
+ }
+}
+
+void ClassList::remove(const AtomicString& token, ExceptionCode& ec)
+{
+ if (!validateToken(token, ec))
+ return;
+ removeInternal(token);
+}
+
+void ClassList::removeInternal(const AtomicString& token)
+{
+ // Check using contains first since it uses AtomicString comparisons instead
+ // of character by character testing.
+ if (!containsInternal(token))
+ return;
+ const AtomicString& newClassName(removeToken(m_element->fastGetAttribute(classAttr), token));
+ m_element->setAttribute(classAttr, newClassName);
+}
+
+bool ClassList::toggle(const AtomicString& token, ExceptionCode& ec)
+{
+ if (!validateToken(token, ec))
+ return false;
+
+ if (containsInternal(token)) {
+ removeInternal(token);
+ return false;
+ }
+ addInternal(token);
+ return true;
+}
+
+String ClassList::toString() const
+{
+ return m_element->fastGetAttribute(classAttr);
+}
+
+void ClassList::reset(const String& newClassName)
+{
+ if (!m_classNamesForQuirksMode.isNull())
+ m_classNamesForQuirksMode.set(newClassName, false);
+}
+
+const SpaceSplitString& ClassList::classNames() const
+{
+ ASSERT(m_element->hasClass());
+ if (!m_classNamesForQuirksMode.isNull())
+ return m_classNamesForQuirksMode;
+ return m_element->attributeMap()->classNames();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/ClassList.h b/Source/WebCore/html/ClassList.h
new file mode 100644
index 0000000..93aea60
--- /dev/null
+++ b/Source/WebCore/html/ClassList.h
@@ -0,0 +1,74 @@
+/*
+ * 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. 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 ClassList_h
+#define ClassList_h
+
+#include "DOMTokenList.h"
+#include "ExceptionCode.h"
+#include "SpaceSplitString.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class Element;
+
+class ClassList : public DOMTokenList {
+public:
+ static PassOwnPtr<ClassList> create(Element* element)
+ {
+ return adoptPtr(new ClassList(element));
+ }
+
+ virtual void ref();
+ virtual void deref();
+
+ virtual unsigned length() const;
+ virtual const AtomicString item(unsigned index) const;
+ virtual bool contains(const AtomicString&, ExceptionCode&) const;
+ virtual void add(const AtomicString&, ExceptionCode&);
+ virtual void remove(const AtomicString&, ExceptionCode&);
+ virtual bool toggle(const AtomicString&, ExceptionCode&);
+ virtual String toString() const;
+
+ virtual Element* element() { return m_element; }
+
+ void reset(const String&);
+
+private:
+ ClassList(Element*);
+
+ void addInternal(const AtomicString&);
+ bool containsInternal(const AtomicString&) const;
+ void removeInternal(const AtomicString&);
+
+ const SpaceSplitString& classNames() const;
+
+ Element* m_element;
+ SpaceSplitString m_classNamesForQuirksMode;
+};
+
+} // namespace WebCore
+
+#endif // ClassList_h
diff --git a/Source/WebCore/html/CollectionCache.cpp b/Source/WebCore/html/CollectionCache.cpp
new file mode 100644
index 0000000..745cf6e
--- /dev/null
+++ b/Source/WebCore/html/CollectionCache.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "CollectionCache.h"
+
+namespace WebCore {
+
+CollectionCache::CollectionCache()
+ : version(0)
+{
+ reset();
+}
+
+inline void CollectionCache::copyCacheMap(NodeCacheMap& dest, const NodeCacheMap& src)
+{
+ ASSERT(dest.isEmpty());
+ NodeCacheMap::const_iterator end = src.end();
+ for (NodeCacheMap::const_iterator it = src.begin(); it != end; ++it)
+ dest.add(it->first, new Vector<Element*>(*it->second));
+}
+
+CollectionCache::CollectionCache(const CollectionCache& other)
+ : version(other.version)
+ , current(other.current)
+ , position(other.position)
+ , length(other.length)
+ , elementsArrayPosition(other.elementsArrayPosition)
+ , hasLength(other.hasLength)
+ , hasNameCache(other.hasNameCache)
+{
+ copyCacheMap(idCache, other.idCache);
+ copyCacheMap(nameCache, other.nameCache);
+}
+
+void CollectionCache::swap(CollectionCache& other)
+{
+ std::swap(version, other.version);
+ std::swap(current, other.current);
+ std::swap(position, other.position);
+ std::swap(length, other.length);
+ std::swap(elementsArrayPosition, other.elementsArrayPosition);
+
+ idCache.swap(other.idCache);
+ nameCache.swap(other.nameCache);
+
+ std::swap(hasLength, other.hasLength);
+ std::swap(hasNameCache, other.hasNameCache);
+}
+
+CollectionCache::~CollectionCache()
+{
+ deleteAllValues(idCache);
+ deleteAllValues(nameCache);
+}
+
+void CollectionCache::reset()
+{
+ current = 0;
+ position = 0;
+ length = 0;
+ hasLength = false;
+ elementsArrayPosition = 0;
+ deleteAllValues(idCache);
+ idCache.clear();
+ deleteAllValues(nameCache);
+ nameCache.clear();
+ hasNameCache = false;
+}
+
+#if !ASSERT_DISABLED
+void CollectionCache::checkConsistency()
+{
+ idCache.checkConsistency();
+ nameCache.checkConsistency();
+}
+#endif
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/CollectionCache.h b/Source/WebCore/html/CollectionCache.h
new file mode 100644
index 0000000..df1d1fa
--- /dev/null
+++ b/Source/WebCore/html/CollectionCache.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef CollectionCache_h
+#define CollectionCache_h
+
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Element;
+
+struct CollectionCache : FastAllocBase {
+ CollectionCache();
+ CollectionCache(const CollectionCache&);
+ CollectionCache& operator=(const CollectionCache& other)
+ {
+ CollectionCache tmp(other);
+ swap(tmp);
+ return *this;
+ }
+ ~CollectionCache();
+
+ void reset();
+ void swap(CollectionCache&);
+
+ void checkConsistency();
+
+ typedef HashMap<AtomicStringImpl*, Vector<Element*>*> NodeCacheMap;
+
+ unsigned version;
+ Element* current;
+ unsigned position;
+ unsigned length;
+ int elementsArrayPosition;
+ NodeCacheMap idCache;
+ NodeCacheMap nameCache;
+ bool hasLength;
+ bool hasNameCache;
+
+private:
+ static void copyCacheMap(NodeCacheMap&, const NodeCacheMap&);
+};
+
+#if ASSERT_DISABLED
+ inline void CollectionCache::checkConsistency() { }
+#endif
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/CollectionType.h b/Source/WebCore/html/CollectionType.h
new file mode 100644
index 0000000..9d7bb54
--- /dev/null
+++ b/Source/WebCore/html/CollectionType.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef CollectionType_h
+#define CollectionType_h
+
+namespace WebCore {
+
+enum CollectionType {
+ // unnamed collection types cached in the document
+
+ DocImages, // all <img> elements in the document
+ DocApplets, // all <object> and <applet> elements
+ DocEmbeds, // all <embed> elements
+ DocObjects, // all <object> elements
+ DocForms, // all <form> elements
+ DocLinks, // all <a> _and_ <area> elements with a value for href
+ DocAnchors, // all <a> elements with a value for name
+ DocScripts, // all <script> elements
+
+ DocAll, // "all" elements (IE)
+ NodeChildren, // first-level children (IE)
+
+ // named collection types cached in the document
+
+ WindowNamedItems,
+ DocumentNamedItems,
+
+ // types not cached in the document; these are types that can't be used on a document
+
+ TableTBodies, // all <tbody> elements in this table
+ TSectionRows, // all row elements in this table section
+ TRCells, // all cells in this row
+ SelectOptions,
+ DataListOptions,
+ MapAreas,
+
+ OtherCollection
+};
+
+static const CollectionType FirstUnnamedDocumentCachedType = DocImages;
+static const unsigned NumUnnamedDocumentCachedTypes = NodeChildren - DocImages + 1;
+
+static const CollectionType FirstNamedDocumentCachedType = WindowNamedItems;
+static const unsigned NumNamedDocumentCachedTypes = DocumentNamedItems - WindowNamedItems + 1;
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/ColorInputType.cpp b/Source/WebCore/html/ColorInputType.cpp
new file mode 100644
index 0000000..c55eba2
--- /dev/null
+++ b/Source/WebCore/html/ColorInputType.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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:
+ *
+ * * 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 "ColorInputType.h"
+
+#include "Color.h"
+#include "HTMLInputElement.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+static bool isValidColorString(const String& value)
+{
+ if (value.isEmpty())
+ return false;
+ if (value[0] != '#')
+ return false;
+
+ // We don't accept #rgb and #aarrggbb formats.
+ if (value.length() != 7)
+ return false;
+ Color color(value);
+ return color.isValid() && !color.hasAlpha();
+}
+
+PassOwnPtr<InputType> ColorInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new ColorInputType(element));
+}
+
+const AtomicString& ColorInputType::formControlType() const
+{
+ return InputTypeNames::color();
+}
+
+bool ColorInputType::typeMismatchFor(const String& value) const
+{
+ // FIXME: Should not accept an empty value. Remove it when we implement value
+ // sanitization for type=color.
+ if (value.isEmpty())
+ return false;
+ return !isValidColorString(value);
+}
+
+bool ColorInputType::typeMismatch() const
+{
+ // FIXME: Should return false. We don't implement value sanitization for
+ // type=color yet.
+ String value = element()->value();
+ return !value.isEmpty() && !isValidColorString(value);
+}
+
+bool ColorInputType::supportsRequired() const
+{
+ return false;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/ColorInputType.h b/Source/WebCore/html/ColorInputType.h
new file mode 100644
index 0000000..ea3798b
--- /dev/null
+++ b/Source/WebCore/html/ColorInputType.h
@@ -0,0 +1,52 @@
+/*
+ * 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:
+ *
+ * * 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 ColorInputType_h
+#define ColorInputType_h
+
+#include "TextFieldInputType.h"
+
+namespace WebCore {
+
+class ColorInputType : public TextFieldInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ ColorInputType(HTMLInputElement* element) : TextFieldInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool typeMismatchFor(const String&) const;
+ virtual bool typeMismatch() const;
+ virtual bool supportsRequired() const;
+};
+
+} // namespace WebCore
+
+#endif // ButtonInputType_h
diff --git a/Source/WebCore/html/DOMDataGridDataSource.cpp b/Source/WebCore/html/DOMDataGridDataSource.cpp
new file mode 100644
index 0000000..aa44d8c
--- /dev/null
+++ b/Source/WebCore/html/DOMDataGridDataSource.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ * 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(DATAGRID)
+
+#include "DOMDataGridDataSource.h"
+
+namespace WebCore {
+
+DOMDataGridDataSource::DOMDataGridDataSource()
+{
+}
+
+DOMDataGridDataSource::~DOMDataGridDataSource()
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DATAGRID)
diff --git a/Source/WebCore/html/DOMDataGridDataSource.h b/Source/WebCore/html/DOMDataGridDataSource.h
new file mode 100644
index 0000000..2ce2ab8
--- /dev/null
+++ b/Source/WebCore/html/DOMDataGridDataSource.h
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ * 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 DOMDataGridDataSource_h
+#define DOMDataGridDataSource_h
+
+#if ENABLE(DATAGRID)
+
+#include "DataGridDataSource.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class HTMLDataGridElement;
+
+class DOMDataGridDataSource : public DataGridDataSource {
+public:
+ static PassRefPtr<DOMDataGridDataSource> create()
+ {
+ return adoptRef(new DOMDataGridDataSource);
+ }
+
+ virtual ~DOMDataGridDataSource();
+
+ virtual bool isDOMDataGridDataSource() const { return true; }
+
+private:
+ DOMDataGridDataSource();
+};
+
+inline DOMDataGridDataSource* asDOMDataGridDataSource(DataGridDataSource* dataSource)
+{
+ ASSERT(dataSource->isDOMDataGridDataSource());
+ return static_cast<DOMDataGridDataSource*>(dataSource);
+}
+
+inline const DOMDataGridDataSource* asDOMDataGridDataSource(const DataGridDataSource* dataSource)
+{
+ ASSERT(dataSource->isDOMDataGridDataSource());
+ return static_cast<const DOMDataGridDataSource*>(dataSource);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DATAGRID)
+#endif // DOMDataGridDataSource_h
diff --git a/Source/WebCore/html/DOMFormData.cpp b/Source/WebCore/html/DOMFormData.cpp
new file mode 100644
index 0000000..bd20155
--- /dev/null
+++ b/Source/WebCore/html/DOMFormData.cpp
@@ -0,0 +1,72 @@
+/*
+ * 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:
+ *
+ * * 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 "DOMFormData.h"
+
+#include "Blob.h"
+#include "HTMLFormControlElement.h"
+#include "HTMLFormElement.h"
+#include "PlatformString.h"
+#include "TextEncoding.h"
+
+namespace WebCore {
+
+DOMFormData::DOMFormData(const TextEncoding& encoding)
+ : FormDataList(encoding)
+{
+}
+
+DOMFormData::DOMFormData(HTMLFormElement* form)
+ : FormDataList(UTF8Encoding())
+{
+ if (!form)
+ return;
+
+ for (unsigned i = 0; i < form->associatedElements().size(); ++i) {
+ FormAssociatedElement* element = form->associatedElements()[i];
+ if (!toHTMLElement(element)->disabled())
+ element->appendFormData(*this, true);
+ }
+}
+
+void DOMFormData::append(const String& name, const String& value)
+{
+ if (!name.isEmpty())
+ appendData(name, value);
+}
+
+void DOMFormData::append(const String& name, Blob* blob)
+{
+ if (!name.isEmpty())
+ appendBlob(name, blob);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/DOMFormData.h b/Source/WebCore/html/DOMFormData.h
new file mode 100644
index 0000000..967d64d
--- /dev/null
+++ b/Source/WebCore/html/DOMFormData.h
@@ -0,0 +1,60 @@
+/*
+ * 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:
+ *
+ * * 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 DOMFormData_h
+#define DOMFormData_h
+
+#include "FormDataList.h"
+#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class Blob;
+class HTMLFormElement;
+class TextEncoding;
+
+class DOMFormData : public FormDataList, public RefCounted<DOMFormData> {
+public:
+ 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*);
+
+private:
+ explicit DOMFormData(const TextEncoding&);
+ explicit DOMFormData(HTMLFormElement*);
+};
+
+} // namespace WebCore
+
+#endif // DOMFormData_h
diff --git a/Source/WebCore/html/DOMFormData.idl b/Source/WebCore/html/DOMFormData.idl
new file mode 100644
index 0000000..4418428
--- /dev/null
+++ b/Source/WebCore/html/DOMFormData.idl
@@ -0,0 +1,44 @@
+/*
+ * 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:
+ *
+ * * 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.
+ */
+
+module html {
+
+ interface [
+ CanBeConstructed,
+ CustomConstructFunction,
+ V8CustomConstructor,
+ GenerateNativeConverter,
+ GenerateToJS
+ ] DOMFormData {
+ // void append(DOMString name, Blob value);
+ [Custom] void append(in DOMString name, in DOMString value);
+ };
+
+}
diff --git a/Source/WebCore/html/DOMSettableTokenList.cpp b/Source/WebCore/html/DOMSettableTokenList.cpp
new file mode 100644
index 0000000..3a86e9c
--- /dev/null
+++ b/Source/WebCore/html/DOMSettableTokenList.cpp
@@ -0,0 +1,101 @@
+/*
+ * 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. 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 "DOMSettableTokenList.h"
+
+namespace WebCore {
+
+DOMSettableTokenList::DOMSettableTokenList()
+ : m_value()
+ , m_tokens()
+{
+}
+
+DOMSettableTokenList::~DOMSettableTokenList()
+{
+}
+
+const AtomicString DOMSettableTokenList::item(unsigned index) const
+{
+ if (index >= length())
+ return AtomicString();
+ return m_tokens[index];
+}
+
+bool DOMSettableTokenList::contains(const AtomicString& token, ExceptionCode& ec) const
+{
+ if (!validateToken(token, ec))
+ return false;
+ return m_tokens.contains(token);
+}
+
+void DOMSettableTokenList::add(const AtomicString& token, ExceptionCode& ec)
+{
+ if (!validateToken(token, ec) || m_tokens.contains(token))
+ return;
+ addInternal(token);
+}
+
+void DOMSettableTokenList::addInternal(const AtomicString& token)
+{
+ m_value = addToken(m_value, token);
+ if (m_tokens.isNull())
+ m_tokens.set(token, false);
+ else
+ m_tokens.add(token);
+}
+
+void DOMSettableTokenList::remove(const AtomicString& token, ExceptionCode& ec)
+{
+ if (!validateToken(token, ec) || !m_tokens.contains(token))
+ return;
+ removeInternal(token);
+}
+
+void DOMSettableTokenList::removeInternal(const AtomicString& token)
+{
+ m_value = removeToken(m_value, token);
+ m_tokens.remove(token);
+}
+
+bool DOMSettableTokenList::toggle(const AtomicString& token, ExceptionCode& ec)
+{
+ if (!validateToken(token, ec))
+ return false;
+ if (m_tokens.contains(token)) {
+ removeInternal(token);
+ return false;
+ }
+ addInternal(token);
+ return true;
+}
+
+void DOMSettableTokenList::setValue(const String& value)
+{
+ m_value = value;
+ m_tokens.set(value, false);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/DOMSettableTokenList.h b/Source/WebCore/html/DOMSettableTokenList.h
new file mode 100644
index 0000000..2b711b4
--- /dev/null
+++ b/Source/WebCore/html/DOMSettableTokenList.h
@@ -0,0 +1,71 @@
+/*
+ * 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. 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 DOMSettableTokenList_h
+#define DOMSettableTokenList_h
+
+#include "DOMTokenList.h"
+#include "ExceptionCode.h"
+#include "SpaceSplitString.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+class DOMSettableTokenList : public DOMTokenList, public RefCounted<DOMSettableTokenList> {
+public:
+ static PassRefPtr<DOMSettableTokenList> create()
+ {
+ return adoptRef(new DOMSettableTokenList());
+ }
+ virtual ~DOMSettableTokenList();
+
+ virtual void ref() { RefCounted<DOMSettableTokenList>::ref(); }
+ virtual void deref() { RefCounted<DOMSettableTokenList>::deref(); }
+
+ virtual unsigned length() const { return m_tokens.size(); }
+ virtual const AtomicString item(unsigned index) const;
+ virtual bool contains(const AtomicString&, ExceptionCode&) const;
+ virtual void add(const AtomicString&, ExceptionCode&);
+ virtual void remove(const AtomicString&, ExceptionCode&);
+ virtual bool toggle(const AtomicString&, ExceptionCode&);
+ virtual String toString() const { return value(); }
+
+ String value() const { return m_value; }
+ void setValue(const String&);
+
+private:
+ DOMSettableTokenList();
+
+ void removeInternal(const AtomicString&);
+ void addInternal(const AtomicString&);
+
+ String m_value;
+ SpaceSplitString m_tokens;
+};
+
+} // namespace WebCore
+
+#endif // DOMSettableTokenList_h
diff --git a/Source/WebCore/html/DOMSettableTokenList.idl b/Source/WebCore/html/DOMSettableTokenList.idl
new file mode 100644
index 0000000..6260623
--- /dev/null
+++ b/Source/WebCore/html/DOMSettableTokenList.idl
@@ -0,0 +1,35 @@
+/*
+ * 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. 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.
+ */
+
+module core {
+
+ interface [
+ GenerateConstructor,
+ HasIndexGetter,
+ GenerateToJS
+ ] DOMSettableTokenList : DOMTokenList {
+ attribute DOMString value;
+ };
+
+}
diff --git a/Source/WebCore/html/DOMTokenList.cpp b/Source/WebCore/html/DOMTokenList.cpp
new file mode 100644
index 0000000..3c91f20
--- /dev/null
+++ b/Source/WebCore/html/DOMTokenList.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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. 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 "DOMTokenList.h"
+
+#include "HTMLParserIdioms.h"
+#include <wtf/text/StringBuilder.h>
+
+namespace WebCore {
+
+bool DOMTokenList::validateToken(const AtomicString& token, ExceptionCode& ec)
+{
+ if (token.isEmpty()) {
+ ec = SYNTAX_ERR;
+ return false;
+ }
+
+ unsigned length = token.length();
+ for (unsigned i = 0; i < length; ++i) {
+ if (isHTMLSpace(token[i])) {
+ ec = INVALID_CHARACTER_ERR;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+String DOMTokenList::addToken(const AtomicString& input, const AtomicString& token)
+{
+ if (input.isEmpty())
+ return token;
+
+ StringBuilder builder;
+ builder.append(input);
+ if (input[input.length()-1] != ' ')
+ builder.append(' ');
+ builder.append(token);
+ return builder.toString();
+}
+
+String DOMTokenList::removeToken(const AtomicString& input, const AtomicString& token)
+{
+ // Algorithm defined at http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#remove-a-token-from-a-string
+
+ unsigned inputLength = input.length();
+ Vector<UChar> output; // 3
+ output.reserveCapacity(inputLength);
+ unsigned position = 0; // 4
+
+ // Step 5
+ while (position < inputLength) {
+ if (isHTMLSpace(input[position])) { // 6
+ output.append(input[position++]); // 6.1, 6.2
+ continue; // 6.3
+ }
+
+ // Step 7
+ Vector<UChar> s;
+ while (position < inputLength && isNotHTMLSpace(input[position]))
+ s.append(input[position++]);
+
+ // Step 8
+ if (s == token) {
+ // Step 8.1
+ while (position < inputLength && isHTMLSpace(input[position]))
+ ++position;
+
+ // Step 8.2
+ size_t j = output.size();
+ while (j > 0 && isHTMLSpace(output[j - 1]))
+ --j;
+ output.resize(j);
+
+ // Step 8.3
+ if (position < inputLength && !output.isEmpty())
+ output.append(' ');
+ } else
+ output.append(s); // Step 9
+ }
+
+ output.shrinkToFit();
+ return String::adopt(output);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/DOMTokenList.h b/Source/WebCore/html/DOMTokenList.h
new file mode 100644
index 0000000..5df2ede
--- /dev/null
+++ b/Source/WebCore/html/DOMTokenList.h
@@ -0,0 +1,62 @@
+/*
+ * 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. 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 DOMTokenList_h
+#define DOMTokenList_h
+
+#include "ExceptionCode.h"
+#include <wtf/text/AtomicString.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Element;
+
+class DOMTokenList : public Noncopyable {
+public:
+ virtual ~DOMTokenList() {};
+
+ virtual void ref() = 0;
+ virtual void deref() = 0;
+
+ virtual unsigned length() const = 0;
+ virtual const AtomicString item(unsigned index) const = 0;
+ virtual bool contains(const AtomicString&, ExceptionCode&) const = 0;
+ virtual void add(const AtomicString&, ExceptionCode&) = 0;
+ virtual void remove(const AtomicString&, ExceptionCode&) = 0;
+ virtual bool toggle(const AtomicString&, ExceptionCode&) = 0;
+ virtual String toString() const = 0;
+
+ virtual Element* element() { return 0; }
+
+protected:
+ static bool validateToken(const AtomicString&, ExceptionCode&);
+ static String addToken(const AtomicString&, const AtomicString&);
+ static String removeToken(const AtomicString&, const AtomicString&);
+};
+
+} // namespace WebCore
+
+#endif // DOMTokenList_h
diff --git a/Source/WebCore/html/DOMTokenList.idl b/Source/WebCore/html/DOMTokenList.idl
new file mode 100644
index 0000000..a46900e
--- /dev/null
+++ b/Source/WebCore/html/DOMTokenList.idl
@@ -0,0 +1,43 @@
+/*
+ * 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. 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.
+ */
+
+module core {
+
+ interface [
+ GenerateConstructor,
+ HasIndexGetter
+ ] DOMTokenList {
+ readonly attribute unsigned long length;
+ [ConvertNullStringTo=Null] DOMString item(in unsigned long index);
+ boolean contains(in DOMString token) raises(DOMException);
+ void add(in DOMString token) raises(DOMException);
+ void remove(in DOMString token) raises(DOMException);
+ boolean toggle(in DOMString token) raises(DOMException);
+
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ [DontEnum] DOMString toString();
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/DataGridColumn.cpp b/Source/WebCore/html/DataGridColumn.cpp
new file mode 100644
index 0000000..7810c86
--- /dev/null
+++ b/Source/WebCore/html/DataGridColumn.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ * 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 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(DATAGRID)
+
+#include "DataGridColumn.h"
+
+#include "DataGridColumnList.h"
+
+namespace WebCore {
+
+void DataGridColumn::setPrimary(bool primary)
+{
+ if (m_primary != primary) {
+ m_primary = primary;
+ if (m_columns)
+ m_columns->primaryColumnChanged(this);
+ }
+}
+
+void DataGridColumn::columnChanged()
+{
+ if (m_columns)
+ m_columns->setDataGridNeedsLayout();
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/DataGridColumn.h b/Source/WebCore/html/DataGridColumn.h
new file mode 100644
index 0000000..555389c
--- /dev/null
+++ b/Source/WebCore/html/DataGridColumn.h
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ * 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 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 DataGridColumn_h
+#define DataGridColumn_h
+
+#if ENABLE(DATAGRID)
+
+#include "RenderStyle.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+class DataGridColumnList;
+
+class DataGridColumn : public RefCounted<DataGridColumn> {
+public:
+ static PassRefPtr<DataGridColumn> create(const String& columnID, const String& label, const String& type, bool primary, unsigned short sortable)
+ {
+ return adoptRef(new DataGridColumn(columnID, label, type, primary, sortable));
+ }
+
+ const AtomicString& id() const { return m_id; }
+ void setId(const AtomicString& id) { m_id = id; columnChanged(); }
+
+ const AtomicString& label() const { return m_label; }
+ void setLabel(const AtomicString& label) { m_label = label; columnChanged(); }
+
+ const AtomicString& type() const { return m_type; }
+ void setType(const AtomicString& type) { m_type = type; columnChanged(); }
+
+ unsigned short sortable() const { return m_sortable; }
+ void setSortable(unsigned short sortable) { m_sortable = sortable; columnChanged(); }
+
+ unsigned short sortDirection() const { return m_sortDirection; }
+ void setSortDirection(unsigned short sortDirection) { m_sortDirection = sortDirection; columnChanged(); }
+
+ bool primary() const { return m_primary; }
+ void setPrimary(bool);
+
+ void setColumnList(DataGridColumnList* list)
+ {
+ m_columns = list;
+ m_columnStyle = 0;
+ m_headerStyle = 0;
+ m_rect = IntRect();
+ }
+
+ RenderStyle* columnStyle() const { return m_columnStyle.get(); }
+ void setColumnStyle(PassRefPtr<RenderStyle> style) { m_columnStyle = style; }
+
+ RenderStyle* headerStyle() const { return m_headerStyle.get(); }
+ void setHeaderStyle(PassRefPtr<RenderStyle> style) { m_headerStyle = style; }
+
+ const IntRect& rect() const { return m_rect; }
+ void setRect(const IntRect& rect) { m_rect = rect; }
+
+private:
+ DataGridColumn(const String& columnID, const String& label, const String& type, bool primary, unsigned short sortable)
+ : m_columns(0)
+ , m_id(columnID)
+ , m_label(label)
+ , m_type(type)
+ , m_primary(primary)
+ , m_sortable(sortable)
+ , m_sortDirection(0)
+ {
+ }
+
+ void columnChanged();
+
+ DataGridColumnList* m_columns; // Not refcounted. The columns list will null out our reference when it goes away.
+
+ AtomicString m_id;
+ AtomicString m_label;
+ AtomicString m_type;
+
+ bool m_primary;
+
+ unsigned short m_sortable;
+ unsigned short m_sortDirection;
+
+ RefPtr<RenderStyle> m_columnStyle; // The style used to render the column background behind the row cells.
+ RefPtr<RenderStyle> m_headerStyle; // The style used to render the column header above the row cells.
+
+ IntRect m_rect;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // DataGridColumn_h
diff --git a/Source/WebCore/html/DataGridColumn.idl b/Source/WebCore/html/DataGridColumn.idl
new file mode 100644
index 0000000..9214800
--- /dev/null
+++ b/Source/WebCore/html/DataGridColumn.idl
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ * 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 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.
+ */
+
+module html {
+
+ interface [
+ Conditional=DATAGRID
+ ] DataGridColumn {
+ attribute DOMString id; // The identifier for the column.
+ attribute DOMString label; // The text to display in the column.
+ attribute DOMString type; // The type of data displayed in this column.
+
+ const unsigned short NEVER_SORTED = 0;
+ const unsigned short ALWAYS_SORTED = 1;
+ const unsigned short SOMETIMES_SORTED = 2;
+ attribute unsigned short sortable; // Whether or not the column can be sorted.
+
+ const unsigned short NATURAL_SORT = 0;
+ const unsigned short SORT_ASCENDING = 1;
+ const unsigned short SORC_DESCENDING = 2;
+ attribute unsigned short sortDirection; // The sort direction for the column. Valid values are ascending, descending and natural (no sort applied).
+
+ attribute boolean primary; // Whether or not this is the primary column of the tree (this will be where the disclosure triangle and connecting tree lines will display)
+ };
+
+}
diff --git a/Source/WebCore/html/DataGridColumnList.cpp b/Source/WebCore/html/DataGridColumnList.cpp
new file mode 100644
index 0000000..15590b2
--- /dev/null
+++ b/Source/WebCore/html/DataGridColumnList.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ * 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 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(DATAGRID)
+
+#include "DataGridColumnList.h"
+#include "HTMLDataGridElement.h"
+#include "PlatformString.h"
+#include "RenderObject.h"
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+DataGridColumnList::DataGridColumnList(HTMLDataGridElement* dataGrid)
+ : m_dataGrid(dataGrid)
+{
+}
+
+DataGridColumnList::~DataGridColumnList()
+{
+ clear();
+}
+
+DataGridColumn* DataGridColumnList::itemWithName(const AtomicString& name) const
+{
+ unsigned length = m_columns.size();
+ for (unsigned i = 0; i < length; ++i) {
+ if (m_columns[i]->id() == name)
+ return m_columns[i].get();
+ }
+ return 0;
+}
+
+void DataGridColumnList::setDataGridNeedsLayout()
+{
+ // Mark the datagrid as needing layout.
+ if (dataGrid() && dataGrid()->renderer())
+ dataGrid()->renderer()->setNeedsLayout(true);
+}
+
+DataGridColumn* DataGridColumnList::add(const String& id, const String& label, const String& type, bool primary, unsigned short sortable)
+{
+ return add(DataGridColumn::create(id, label, type, primary, sortable).get());
+}
+
+DataGridColumn* DataGridColumnList::add(DataGridColumn* column)
+{
+ if (column->primary())
+ m_primaryColumn = column;
+ m_columns.append(column);
+ column->setColumnList(this);
+ setDataGridNeedsLayout();
+ return column;
+}
+
+void DataGridColumnList::remove(DataGridColumn* col)
+{
+ size_t index = m_columns.find(col);
+ if (index == notFound)
+ return;
+ m_columns.remove(index);
+ if (col == m_primaryColumn)
+ m_primaryColumn = 0;
+ if (col == m_sortColumn)
+ m_sortColumn = 0;
+ col->setColumnList(0);
+ setDataGridNeedsLayout();
+}
+
+void DataGridColumnList::move(DataGridColumn* col, unsigned long index)
+{
+ size_t colIndex = m_columns.find(col);
+ if (colIndex == notFound)
+ return;
+ m_columns.insert(index, col);
+ setDataGridNeedsLayout();
+}
+
+void DataGridColumnList::clear()
+{
+ unsigned length = m_columns.size();
+ for (unsigned i = 0; i < length; ++i)
+ m_columns[i]->setColumnList(0);
+ m_columns.clear();
+ m_primaryColumn = 0;
+ m_sortColumn = 0;
+ setDataGridNeedsLayout();
+}
+
+void DataGridColumnList::primaryColumnChanged(DataGridColumn* col)
+{
+ if (col->primary())
+ m_primaryColumn = col;
+ else if (m_primaryColumn = col)
+ m_primaryColumn = 0;
+
+ setDataGridNeedsLayout();
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/DataGridColumnList.h b/Source/WebCore/html/DataGridColumnList.h
new file mode 100644
index 0000000..8a7ec75
--- /dev/null
+++ b/Source/WebCore/html/DataGridColumnList.h
@@ -0,0 +1,63 @@
+#ifndef DataGridColumnList_h
+#define DataGridColumnList_h
+
+#if ENABLE(DATAGRID)
+
+#include "DataGridColumn.h"
+
+#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class HTMLDataGridElement;
+
+class DataGridColumnList : public RefCounted<DataGridColumnList> {
+ friend class DataGridColumn;
+public:
+ static PassRefPtr<DataGridColumnList> create(HTMLDataGridElement* grid)
+ {
+ return adoptRef(new DataGridColumnList(grid));
+ }
+
+ ~DataGridColumnList();
+
+ unsigned length() const { return m_columns.size(); }
+
+ DataGridColumn* item(unsigned index) const { return m_columns[index].get(); }
+ DataGridColumn* itemWithName(const AtomicString&) const;
+
+ DataGridColumn* primaryColumn() const { return m_primaryColumn.get(); }
+
+ DataGridColumn* sortColumn() const { return m_sortColumn.get(); }
+
+ DataGridColumn* add(const String& id, const String& label, const String& type, bool primary, unsigned short sortable);
+ DataGridColumn* add(DataGridColumn*);
+ void remove(DataGridColumn*);
+ void move(DataGridColumn*, unsigned long index);
+ void clear();
+
+ HTMLDataGridElement* dataGrid() const { return m_dataGrid; }
+ void clearDataGrid() { m_dataGrid = 0; }
+
+ void setDataGridNeedsLayout();
+
+private:
+ DataGridColumnList(HTMLDataGridElement*);
+
+ void primaryColumnChanged(DataGridColumn*);
+
+ HTMLDataGridElement* m_dataGrid; // Weak reference. Will be nulled out when our tree goes away.
+
+ Vector<RefPtr<DataGridColumn> > m_columns;
+ RefPtr<DataGridColumn> m_primaryColumn;
+ RefPtr<DataGridColumn> m_sortColumn;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // DataGridColumnList_h
diff --git a/Source/WebCore/html/DataGridColumnList.idl b/Source/WebCore/html/DataGridColumnList.idl
new file mode 100644
index 0000000..9a8ea5c
--- /dev/null
+++ b/Source/WebCore/html/DataGridColumnList.idl
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ * 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 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.
+ */
+
+module html {
+
+ interface [
+ HasIndexGetter,
+ HasNameGetter,
+ Conditional=DATAGRID
+ ] DataGridColumnList {
+ DataGridColumn item(in [IsIndex] unsigned long index);
+ readonly attribute unsigned long length;
+
+ readonly attribute DataGridColumn sortColumn;
+ readonly attribute DataGridColumn primaryColumn;
+
+ DataGridColumn add(in DOMString id, in DOMString label, in DOMString type, in boolean primary, in unsigned short sortable);
+ void remove(in DataGridColumn column);
+ void move(in DataGridColumn column, in unsigned long index);
+ void clear();
+ };
+
+}
diff --git a/Source/WebCore/html/DataGridDataSource.h b/Source/WebCore/html/DataGridDataSource.h
new file mode 100644
index 0000000..2ab1f5b
--- /dev/null
+++ b/Source/WebCore/html/DataGridDataSource.h
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ * 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 DataGridDataSource_h
+#define DataGridDataSource_h
+
+#if ENABLE(DATAGRID)
+
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class HTMLDataGridElement;
+
+class DataGridDataSource : public RefCounted<DataGridDataSource> {
+public:
+ virtual ~DataGridDataSource() { }
+
+ virtual bool isDOMDataGridDataSource() const { return false; }
+ virtual bool isJSDataGridDataSource() const { return false; }
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // DataGridDataSource_h
diff --git a/Source/WebCore/html/DateComponents.cpp b/Source/WebCore/html/DateComponents.cpp
new file mode 100644
index 0000000..8dced1d
--- /dev/null
+++ b/Source/WebCore/html/DateComponents.cpp
@@ -0,0 +1,728 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "DateComponents.h"
+
+#include "PlatformString.h"
+#include <limits.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/DateMath.h>
+#include <wtf/MathExtras.h>
+
+using namespace std;
+
+namespace WebCore {
+
+// HTML5 uses ISO-8601 format with year >= 1. Gregorian calendar started in
+// 1582. However, we need to support 0001-01-01 in Gregorian calendar rule.
+static const int minimumYear = 1;
+// Date in ECMAScript can't represent dates later than 275760-09-13T00:00Z.
+// So, we have the same upper limit in HTML5 dates.
+static const int maximumYear = 275760;
+static const int maximumMonthInMaximumYear = 8; // This is September, since months are 0 based.
+static const int maximumDayInMaximumMonth = 13;
+static const int maximumWeekInMaximumYear = 37; // The week of 275760-09-13
+
+static const int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+static bool isLeapYear(int year)
+{
+ if (year % 4)
+ return false;
+ if (!(year % 400))
+ return true;
+ if (!(year % 100))
+ return false;
+ return true;
+}
+
+// 'month' is 0-based.
+static int maxDayOfMonth(int year, int month)
+{
+ if (month != 1) // February?
+ return daysInMonth[month];
+ return isLeapYear(year) ? 29 : 28;
+}
+
+// 'month' is 0-based.
+static int dayOfWeek(int year, int month, int day)
+{
+ int shiftedMonth = month + 2;
+ // 2:January, 3:Feburuary, 4:March, ...
+
+ // Zeller's congruence
+ if (shiftedMonth <= 3) {
+ shiftedMonth += 12;
+ year--;
+ }
+ // 4:March, ..., 14:January, 15:February
+
+ int highYear = year / 100;
+ int lowYear = year % 100;
+ // We add 6 to make the result Sunday-origin.
+ int result = (day + 13 * shiftedMonth / 5 + lowYear + lowYear / 4 + highYear / 4 + 5 * highYear + 6) % 7;
+ return result;
+}
+
+int DateComponents::maxWeekNumberInYear() const
+{
+ int day = dayOfWeek(m_year, 0, 1); // January 1.
+ return day == Thursday || (day == Wednesday && isLeapYear(m_year)) ? 53 : 52;
+}
+
+static unsigned countDigits(const UChar* src, unsigned length, unsigned start)
+{
+ unsigned index = start;
+ for (; index < length; ++index) {
+ if (!isASCIIDigit(src[index]))
+ break;
+ }
+ return index - start;
+}
+
+// Very strict integer parser. Do not allow leading or trailing whitespace unlike charactersToIntStrict().
+static bool toInt(const UChar* src, unsigned length, unsigned parseStart, unsigned parseLength, int& out)
+{
+ if (parseStart + parseLength > length || parseLength <= 0)
+ return false;
+ int value = 0;
+ const UChar* current = src + parseStart;
+ const UChar* end = current + parseLength;
+
+ // We don't need to handle negative numbers for ISO 8601.
+ for (; current < end; ++current) {
+ if (!isASCIIDigit(*current))
+ return false;
+ int digit = *current - '0';
+ if (value > (INT_MAX - digit) / 10) // Check for overflow.
+ return false;
+ value = value * 10 + digit;
+ }
+ out = value;
+ return true;
+}
+
+bool DateComponents::parseYear(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ unsigned digitsLength = countDigits(src, length, start);
+ // Needs at least 4 digits according to the standard.
+ if (digitsLength < 4)
+ return false;
+ int year;
+ if (!toInt(src, length, start, digitsLength, year))
+ return false;
+ if (year < minimumYear || year > maximumYear)
+ return false;
+ m_year = year;
+ end = start + digitsLength;
+ return true;
+}
+
+static bool withinHTMLDateLimits(int year, int month)
+{
+ if (year < minimumYear)
+ return false;
+ if (year < maximumYear)
+ return true;
+ return month <= maximumMonthInMaximumYear;
+}
+
+static bool withinHTMLDateLimits(int year, int month, int monthDay)
+{
+ if (year < minimumYear)
+ return false;
+ if (year < maximumYear)
+ return true;
+ if (month < maximumMonthInMaximumYear)
+ return true;
+ return monthDay <= maximumDayInMaximumMonth;
+}
+
+static bool withinHTMLDateLimits(int year, int month, int monthDay, int hour, int minute, int second, int millisecond)
+{
+ if (year < minimumYear)
+ return false;
+ if (year < maximumYear)
+ return true;
+ if (month < maximumMonthInMaximumYear)
+ return true;
+ if (monthDay < maximumDayInMaximumMonth)
+ return true;
+ if (monthDay > maximumDayInMaximumMonth)
+ return false;
+ // (year, month, monthDay) = (maximumYear, maximumMonthInMaximumYear, maximumDayInMaximumMonth)
+ return !hour && !minute && !second && !millisecond;
+}
+
+bool DateComponents::addDay(int dayDiff)
+{
+ ASSERT(m_monthDay);
+
+ int day = m_monthDay + dayDiff;
+ if (day > maxDayOfMonth(m_year, m_month)) {
+ day = m_monthDay;
+ int year = m_year;
+ int month = m_month;
+ int maxDay = maxDayOfMonth(year, month);
+ for (; dayDiff > 0; --dayDiff) {
+ ++day;
+ if (day > maxDay) {
+ day = 1;
+ ++month;
+ if (month >= 12) { // month is 0-origin.
+ month = 0;
+ ++year;
+ }
+ maxDay = maxDayOfMonth(year, month);
+ }
+ }
+ if (!withinHTMLDateLimits(year, month, day))
+ return false;
+ m_year = year;
+ m_month = month;
+ } else if (day < 1) {
+ int month = m_month;
+ int year = m_year;
+ day = m_monthDay;
+ for (; dayDiff < 0; ++dayDiff) {
+ --day;
+ if (day < 1) {
+ --month;
+ if (month < 0) {
+ month = 11;
+ --year;
+ }
+ day = maxDayOfMonth(year, month);
+ }
+ }
+ if (!withinHTMLDateLimits(year, month, day))
+ return false;
+ m_year = year;
+ m_month = month;
+ } else {
+ if (!withinHTMLDateLimits(m_year, m_month, day))
+ return false;
+ }
+ m_monthDay = day;
+ return true;
+}
+
+bool DateComponents::addMinute(int minute)
+{
+ // This function is used to adjust timezone offset. So m_year, m_month,
+ // m_monthDay have values between the lower and higher limits.
+ ASSERT(withinHTMLDateLimits(m_year, m_month, m_monthDay));
+
+ int carry;
+ // minute can be negative or greater than 59.
+ minute += m_minute;
+ if (minute > 59) {
+ carry = minute / 60;
+ minute = minute % 60;
+ } else if (m_minute < 0) {
+ carry = (59 - m_minute) / 60;
+ minute += carry * 60;
+ carry = -carry;
+ ASSERT(minute >= 0 && minute <= 59);
+ } else {
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, minute, m_second, m_millisecond))
+ return false;
+ m_minute = minute;
+ return true;
+ }
+
+ int hour = m_hour + carry;
+ if (hour > 23) {
+ carry = hour / 24;
+ hour = hour % 24;
+ } else if (hour < 0) {
+ carry = (23 - hour) / 24;
+ hour += carry * 24;
+ carry = -carry;
+ ASSERT(hour >= 0 && hour <= 23);
+ } else {
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, hour, minute, m_second, m_millisecond))
+ return false;
+ m_minute = minute;
+ m_hour = hour;
+ return true;
+ }
+ if (!addDay(carry))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, hour, minute, m_second, m_millisecond))
+ return false;
+ m_minute = minute;
+ m_hour = hour;
+ return true;
+}
+
+// Parses a timezone part, and adjust year, month, monthDay, hour, minute, second, millisecond.
+bool DateComponents::parseTimeZone(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ if (start >= length)
+ return false;
+ unsigned index = start;
+ if (src[index] == 'Z') {
+ end = index + 1;
+ return true;
+ }
+
+ bool minus;
+ if (src[index] == '+')
+ minus = false;
+ else if (src[index] == '-')
+ minus = true;
+ else
+ return false;
+ ++index;
+
+ int hour;
+ int minute;
+ if (!toInt(src, length, index, 2, hour) || hour < 0 || hour > 23)
+ return false;
+ index += 2;
+
+ if (index >= length || src[index] != ':')
+ return false;
+ ++index;
+
+ if (!toInt(src, length, index, 2, minute) || minute < 0 || minute > 59)
+ return false;
+ index += 2;
+
+ if (minus) {
+ hour = -hour;
+ minute = -minute;
+ }
+
+ // Subtract the timezone offset.
+ if (!addMinute(-(hour * 60 + minute)))
+ return false;
+ end = index;
+ return true;
+}
+
+bool DateComponents::parseMonth(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ ASSERT(src);
+ unsigned index;
+ if (!parseYear(src, length, start, index))
+ return false;
+ if (index >= length || src[index] != '-')
+ return false;
+ ++index;
+
+ int month;
+ if (!toInt(src, length, index, 2, month) || month < 1 || month > 12)
+ return false;
+ --month;
+ if (!withinHTMLDateLimits(m_year, month))
+ return false;
+ m_month = month;
+ end = index + 2;
+ m_type = Month;
+ return true;
+}
+
+bool DateComponents::parseDate(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ ASSERT(src);
+ unsigned index;
+ if (!parseMonth(src, length, start, index))
+ return false;
+ // '-' and 2-digits are needed.
+ if (index + 2 >= length)
+ return false;
+ if (src[index] != '-')
+ return false;
+ ++index;
+
+ int day;
+ if (!toInt(src, length, index, 2, day) || day < 1 || day > maxDayOfMonth(m_year, m_month))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month, day))
+ return false;
+ m_monthDay = day;
+ end = index + 2;
+ m_type = Date;
+ return true;
+}
+
+bool DateComponents::parseWeek(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ ASSERT(src);
+ unsigned index;
+ if (!parseYear(src, length, start, index))
+ return false;
+
+ // 4 characters ('-' 'W' digit digit) are needed.
+ if (index + 3 >= length)
+ return false;
+ if (src[index] != '-')
+ return false;
+ ++index;
+ if (src[index] != 'W')
+ return false;
+ ++index;
+
+ int week;
+ if (!toInt(src, length, index, 2, week) || week < 1 || week > maxWeekNumberInYear())
+ return false;
+ if (m_year == maximumYear && week > maximumWeekInMaximumYear)
+ return false;
+ m_week = week;
+ end = index + 2;
+ m_type = Week;
+ return true;
+}
+
+bool DateComponents::parseTime(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ ASSERT(src);
+ int hour;
+ if (!toInt(src, length, start, 2, hour) || hour < 0 || hour > 23)
+ return false;
+ unsigned index = start + 2;
+ if (index >= length)
+ return false;
+ if (src[index] != ':')
+ return false;
+ ++index;
+
+ int minute;
+ if (!toInt(src, length, index, 2, minute) || minute < 0 || minute > 59)
+ return false;
+ index += 2;
+
+ int second = 0;
+ int millisecond = 0;
+ // Optional second part.
+ // Do not return with false because the part is optional.
+ if (index + 2 < length && src[index] == ':') {
+ if (toInt(src, length, index + 1, 2, second) && second >= 0 && second <= 59) {
+ index += 3;
+
+ // Optional fractional second part.
+ if (index < length && src[index] == '.') {
+ unsigned digitsLength = countDigits(src, length, index + 1);
+ if (digitsLength > 0) {
+ ++index;
+ bool ok;
+ if (digitsLength == 1) {
+ ok = toInt(src, length, index, 1, millisecond);
+ millisecond *= 100;
+ } else if (digitsLength == 2) {
+ ok = toInt(src, length, index, 2, millisecond);
+ millisecond *= 10;
+ } else // digitsLength >= 3
+ ok = toInt(src, length, index, 3, millisecond);
+ ASSERT(ok);
+ index += digitsLength;
+ }
+ }
+ }
+ }
+ m_hour = hour;
+ m_minute = minute;
+ m_second = second;
+ m_millisecond = millisecond;
+ end = index;
+ m_type = Time;
+ return true;
+}
+
+bool DateComponents::parseDateTimeLocal(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ ASSERT(src);
+ unsigned index;
+ if (!parseDate(src, length, start, index))
+ return false;
+ if (index >= length)
+ return false;
+ if (src[index] != 'T')
+ return false;
+ ++index;
+ if (!parseTime(src, length, index, end))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond))
+ return false;
+ m_type = DateTimeLocal;
+ return true;
+}
+
+bool DateComponents::parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ ASSERT(src);
+ unsigned index;
+ if (!parseDate(src, length, start, index))
+ return false;
+ if (index >= length)
+ return false;
+ if (src[index] != 'T')
+ return false;
+ ++index;
+ if (!parseTime(src, length, index, index))
+ return false;
+ if (!parseTimeZone(src, length, index, end))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond))
+ return false;
+ m_type = DateTime;
+ return true;
+}
+
+static inline double positiveFmod(double value, double divider)
+{
+ double remainder = fmod(value, divider);
+ return remainder < 0 ? remainder + divider : remainder;
+}
+
+void DateComponents::setMillisecondsSinceMidnightInternal(double msInDay)
+{
+ ASSERT(msInDay >= 0 && msInDay < msPerDay);
+ m_millisecond = static_cast<int>(fmod(msInDay, msPerSecond));
+ double value = floor(msInDay / msPerSecond);
+ m_second = static_cast<int>(fmod(value, secondsPerMinute));
+ value = floor(value / secondsPerMinute);
+ m_minute = static_cast<int>(fmod(value, minutesPerHour));
+ m_hour = static_cast<int>(value / minutesPerHour);
+}
+
+bool DateComponents::setMillisecondsSinceEpochForDateInternal(double ms)
+{
+ m_year = msToYear(ms);
+ int yearDay = dayInYear(ms, m_year);
+ m_month = monthFromDayInYear(yearDay, isLeapYear(m_year));
+ m_monthDay = dayInMonthFromDayInYear(yearDay, isLeapYear(m_year));
+ return true;
+}
+
+bool DateComponents::setMillisecondsSinceEpochForDate(double ms)
+{
+ m_type = Invalid;
+ if (!isfinite(ms))
+ return false;
+ if (!setMillisecondsSinceEpochForDateInternal(round(ms)))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay))
+ return false;
+ m_type = Date;
+ return true;
+}
+
+bool DateComponents::setMillisecondsSinceEpochForDateTime(double ms)
+{
+ m_type = Invalid;
+ if (!isfinite(ms))
+ return false;
+ ms = round(ms);
+ setMillisecondsSinceMidnightInternal(positiveFmod(ms, msPerDay));
+ if (!setMillisecondsSinceEpochForDateInternal(ms))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond))
+ return false;
+ m_type = DateTime;
+ return true;
+}
+
+bool DateComponents::setMillisecondsSinceEpochForDateTimeLocal(double ms)
+{
+ // Internal representation of DateTimeLocal is the same as DateTime except m_type.
+ if (!setMillisecondsSinceEpochForDateTime(ms))
+ return false;
+ m_type = DateTimeLocal;
+ return true;
+}
+
+bool DateComponents::setMillisecondsSinceEpochForMonth(double ms)
+{
+ m_type = Invalid;
+ if (!isfinite(ms))
+ return false;
+ if (!setMillisecondsSinceEpochForDateInternal(round(ms)))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month))
+ return false;
+ m_type = Month;
+ return true;
+}
+
+bool DateComponents::setMillisecondsSinceMidnight(double ms)
+{
+ m_type = Invalid;
+ if (!isfinite(ms))
+ return false;
+ setMillisecondsSinceMidnightInternal(positiveFmod(round(ms), msPerDay));
+ m_type = Time;
+ return true;
+}
+
+bool DateComponents::setMonthsSinceEpoch(double months)
+{
+ if (!isfinite(months))
+ return false;
+ months = round(months);
+ double doubleMonth = positiveFmod(months, 12);
+ double doubleYear = 1970 + (months - doubleMonth) / 12;
+ if (doubleYear < minimumYear || maximumYear < doubleYear)
+ return false;
+ int year = static_cast<int>(doubleYear);
+ int month = static_cast<int>(doubleMonth);
+ if (!withinHTMLDateLimits(year, month))
+ return false;
+ m_year = year;
+ m_month = month;
+ m_type = Month;
+ return true;
+}
+
+// Offset from January 1st to Monday of the ISO 8601's first week.
+// ex. If January 1st is Friday, such Monday is 3 days later. Returns 3.
+static int offsetTo1stWeekStart(int year)
+{
+ int offsetTo1stWeekStart = 1 - dayOfWeek(year, 0, 1);
+ if (offsetTo1stWeekStart <= -4)
+ offsetTo1stWeekStart += 7;
+ return offsetTo1stWeekStart;
+}
+
+bool DateComponents::setMillisecondsSinceEpochForWeek(double ms)
+{
+ m_type = Invalid;
+ if (!isfinite(ms))
+ return false;
+ ms = round(ms);
+
+ m_year = msToYear(ms);
+ if (m_year < minimumYear || m_year > maximumYear)
+ return false;
+
+ int yearDay = dayInYear(ms, m_year);
+ int offset = offsetTo1stWeekStart(m_year);
+ if (yearDay < offset) {
+ // The day belongs to the last week of the previous year.
+ m_year--;
+ if (m_year <= minimumYear)
+ return false;
+ m_week = maxWeekNumberInYear();
+ } else {
+ m_week = ((yearDay - offset) / 7) + 1;
+ if (m_week > maxWeekNumberInYear()) {
+ m_year++;
+ m_week = 1;
+ }
+ if (m_year > maximumYear || (m_year == maximumYear && m_week > maximumWeekInMaximumYear))
+ return false;
+ }
+ m_type = Week;
+ return true;
+}
+
+double DateComponents::millisecondsSinceEpochForTime() const
+{
+ ASSERT(m_type == Time || m_type == DateTime || m_type == DateTimeLocal);
+ return ((m_hour * minutesPerHour + m_minute) * secondsPerMinute + m_second) * msPerSecond + m_millisecond;
+}
+
+double DateComponents::millisecondsSinceEpoch() const
+{
+ switch (m_type) {
+ case Date:
+ return dateToDaysFrom1970(m_year, m_month, m_monthDay) * msPerDay;
+ case DateTime:
+ case DateTimeLocal:
+ return dateToDaysFrom1970(m_year, m_month, m_monthDay) * msPerDay + millisecondsSinceEpochForTime();
+ case Month:
+ return dateToDaysFrom1970(m_year, m_month, 1) * msPerDay;
+ case Time:
+ return millisecondsSinceEpochForTime();
+ case Week:
+ return (dateToDaysFrom1970(m_year, 0, 1) + offsetTo1stWeekStart(m_year) + (m_week - 1) * 7) * msPerDay;
+ case Invalid:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return invalidMilliseconds();
+}
+
+double DateComponents::monthsSinceEpoch() const
+{
+ ASSERT(m_type == Month);
+ return (m_year - 1970) * 12 + m_month;
+}
+
+String DateComponents::toStringForTime(SecondFormat format) const
+{
+ ASSERT(m_type == DateTime || m_type == DateTimeLocal || m_type == Time);
+ SecondFormat effectiveFormat = format;
+ if (m_millisecond)
+ effectiveFormat = Millisecond;
+ else if (format == None && m_second)
+ effectiveFormat = Second;
+
+ switch (effectiveFormat) {
+ default:
+ ASSERT_NOT_REACHED();
+ // Fallback to None.
+ case None:
+ return String::format("%02d:%02d", m_hour, m_minute);
+ case Second:
+ return String::format("%02d:%02d:%02d", m_hour, m_minute, m_second);
+ case Millisecond:
+ return String::format("%02d:%02d:%02d.%03d", m_hour, m_minute, m_second, m_millisecond);
+ }
+}
+
+String DateComponents::toString(SecondFormat format) const
+{
+ switch (m_type) {
+ case Date:
+ return String::format("%04d-%02d-%02d", m_year, m_month + 1, m_monthDay);
+ case DateTime:
+ return String::format("%04d-%02d-%02dT", m_year, m_month + 1, m_monthDay)
+ + toStringForTime(format) + String("Z");
+ case DateTimeLocal:
+ return String::format("%04d-%02d-%02dT", m_year, m_month + 1, m_monthDay)
+ + toStringForTime(format);
+ case Month:
+ return String::format("%04d-%02d", m_year, m_month + 1);
+ case Time:
+ return toStringForTime(format);
+ case Week:
+ return String::format("%04d-W%02d", m_year, m_week);
+ case Invalid:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return String("(Invalid DateComponents)");
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/DateComponents.h b/Source/WebCore/html/DateComponents.h
new file mode 100644
index 0000000..9bce0c3
--- /dev/null
+++ b/Source/WebCore/html/DateComponents.h
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+#ifndef DateComponents_h
+#define DateComponents_h
+
+#include <limits>
+#include <wtf/Forward.h>
+#include <wtf/unicode/Unicode.h>
+
+namespace WebCore {
+
+// A DateComponents instance represents one of the following date and time combinations:
+// * Month type: year-month
+// * Date type: year-month-day
+// * Week type: year-week
+// * Time type: hour-minute-second-millisecond
+// * DateTime or DateTimeLocal type: year-month-day hour-minute-second-millisecond
+class DateComponents {
+public:
+ DateComponents()
+ : m_millisecond(0)
+ , m_second(0)
+ , m_minute(0)
+ , m_hour(0)
+ , m_monthDay(0)
+ , m_month(0)
+ , m_year(0)
+ , m_week(0)
+ , m_type(Invalid)
+ {
+ }
+
+ int millisecond() const { return m_millisecond; }
+ int second() const { return m_second; }
+ int minute() const { return m_minute; }
+ int hour() const { return m_hour; }
+ int monthDay() const { return m_monthDay; }
+ int month() const { return m_month; }
+ int fullYear() const { return m_year; }
+ int week() const { return m_week; }
+
+ enum SecondFormat {
+ None, // Suppress the second part and the millisecond part if they are 0.
+ Second, // Always show the second part, and suppress the millisecond part if it is 0.
+ Millisecond // Always show the second part and the millisecond part.
+ };
+
+ // Returns an ISO 8601 representation for this instance.
+ // The format argument is valid for DateTime, DateTimeLocal, and Time types.
+ String toString(SecondFormat format = None) const;
+
+ // parse*() and setMillisecondsSince*() functions are initializers for an
+ // DateComponents instance. If these functions return false, the instance
+ // might be invalid.
+
+ // The following six functions parse the input 'src' whose length is
+ // 'length', and updates some fields of this instance. The parsing starts at
+ // src[start] and examines characters before src[length].
+ // 'src' must be non-null. The 'src' string doesn't need to be
+ // null-terminated.
+ // The functions return true if the parsing succeeds, and set 'end' to the
+ // next index after the last consumed. Extra leading characters cause parse
+ // failures, and the trailing extra characters don't cause parse failures.
+
+ // Sets year and month.
+ bool parseMonth(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ // Sets year, month and monthDay.
+ bool parseDate(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ // Sets year and week.
+ bool parseWeek(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ // Sets hour, minute, second and millisecond.
+ bool parseTime(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ // Sets year, month, monthDay, hour, minute, second and millisecond.
+ bool parseDateTimeLocal(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ // Sets year, month, monthDay, hour, minute, second and millisecond, and adjusts timezone.
+ bool parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end);
+
+ // The following setMillisecondsSinceEpochFor*() functions take
+ // the number of milliseconds since 1970-01-01 00:00:00.000 UTC as
+ // the argument, and update all fields for the corresponding
+ // DateComponents type. The functions return true if it succeeds, and
+ // false if they fail.
+
+ // For Date type. Updates m_year, m_month and m_monthDay.
+ bool setMillisecondsSinceEpochForDate(double ms);
+ // For DateTime type. Updates m_year, m_month, m_monthDay, m_hour, m_minute, m_second and m_millisecond.
+ bool setMillisecondsSinceEpochForDateTime(double ms);
+ // For DateTimeLocal type. Updates m_year, m_month, m_monthDay, m_hour, m_minute, m_second and m_millisecond.
+ bool setMillisecondsSinceEpochForDateTimeLocal(double ms);
+ // For Month type. Updates m_year and m_month.
+ bool setMillisecondsSinceEpochForMonth(double ms);
+ // For Week type. Updates m_year and m_week.
+ bool setMillisecondsSinceEpochForWeek(double ms);
+
+ // For Time type. Updates m_hour, m_minute, m_second and m_millisecond.
+ bool setMillisecondsSinceMidnight(double ms);
+
+ // Another initializer for Month type. Updates m_year and m_month.
+ bool setMonthsSinceEpoch(double months);
+
+ // Returns the number of milliseconds from 1970-01-01 00:00:00 UTC.
+ // For a DateComponents initialized with parseDateTimeLocal(),
+ // millisecondsSinceEpoch() returns a value for UTC timezone.
+ double millisecondsSinceEpoch() const;
+ // Returns the number of months from 1970-01.
+ // Do not call this for types other than Month.
+ double monthsSinceEpoch() const;
+ static inline double invalidMilliseconds() { return std::numeric_limits<double>::quiet_NaN(); }
+
+ // Minimum and maxmimum limits for setMillisecondsSince*(),
+ // setMonthsSinceEpoch(), millisecondsSinceEpoch(), and monthsSinceEpoch().
+ static inline double minimumDate() { return -62135596800000.0; } // 0001-01-01T00:00Z
+ static inline double minimumDateTime() { return -62135596800000.0; } // ditto.
+ static inline double minimumMonth() { return (1 - 1970) * 12.0 + 1 - 1; } // 0001-01
+ static inline double minimumTime() { return 0; } // 00:00:00.000
+ static inline double minimumWeek() { return -62135596800000.0; } // 0001-01-01, the first Monday of 0001.
+ static inline double maximumDate() { return 8640000000000000.0; } // 275760-09-13T00:00Z
+ static inline double maximumDateTime() { return 8640000000000000.0; } // ditto.
+ static inline double maximumMonth() { return (275760 - 1970) * 12.0 + 9 - 1; } // 275760-09
+ static inline double maximumTime() { return 86399999; } // 23:59:59.999
+ static inline double maximumWeek() { return 8639999568000000.0; } // 275760-09-08, the Monday of the week including 275760-09-13.
+
+private:
+ // Returns the maximum week number in this DateComponents's year.
+ // The result is either of 52 and 53.
+ int maxWeekNumberInYear() const;
+ bool parseYear(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ bool addDay(int);
+ bool addMinute(int);
+ bool parseTimeZone(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ // Helper for millisecondsSinceEpoch().
+ double millisecondsSinceEpochForTime() const;
+ // Helpers for setMillisecondsSinceEpochFor*().
+ bool setMillisecondsSinceEpochForDateInternal(double ms);
+ void setMillisecondsSinceMidnightInternal(double ms);
+ // Helper for toString().
+ String toStringForTime(SecondFormat) const;
+
+ // m_weekDay values
+ enum {
+ Sunday = 0,
+ Monday,
+ Tuesday,
+ Wednesday,
+ Thursday,
+ Friday,
+ Saturday,
+ };
+
+ int m_millisecond; // 0 - 999
+ int m_second;
+ int m_minute;
+ int m_hour;
+ int m_monthDay; // 1 - 31
+ int m_month; // 0:January - 11:December
+ int m_year; // 1582 -
+ int m_week; // 1 - 53
+
+ enum Type {
+ Invalid,
+ Date,
+ DateTime,
+ DateTimeLocal,
+ Month,
+ Time,
+ Week,
+ };
+ Type m_type;
+};
+
+
+} // namespace WebCore
+
+#endif // DateComponents_h
diff --git a/Source/WebCore/html/DateInputType.cpp b/Source/WebCore/html/DateInputType.cpp
new file mode 100644
index 0000000..3409d3b
--- /dev/null
+++ b/Source/WebCore/html/DateInputType.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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:
+ *
+ * * 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 "DateInputType.h"
+
+#include "DateComponents.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static const double dateDefaultStep = 1.0;
+static const double dateStepScaleFactor = 86400000.0;
+
+PassOwnPtr<InputType> DateInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new DateInputType(element));
+}
+
+const AtomicString& DateInputType::formControlType() const
+{
+ return InputTypeNames::date();
+}
+
+double DateInputType::minimum() const
+{
+ return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumDate());
+}
+
+double DateInputType::maximum() const
+{
+ return parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumDate());
+}
+
+double DateInputType::defaultStep() const
+{
+ return dateDefaultStep;
+}
+
+double DateInputType::stepScaleFactor() const
+{
+ return dateStepScaleFactor;
+}
+
+bool DateInputType::parsedStepValueShouldBeInteger() const
+{
+ return true;
+}
+
+bool DateInputType::parseToDateComponentsInternal(const UChar* characters, unsigned length, DateComponents* out) const
+{
+ ASSERT(out);
+ unsigned end;
+ return out->parseDate(characters, length, 0, end) && end == length;
+}
+
+bool DateInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+{
+ ASSERT(date);
+ return date->setMillisecondsSinceEpochForDate(value);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/DateInputType.h b/Source/WebCore/html/DateInputType.h
new file mode 100644
index 0000000..965d9ea
--- /dev/null
+++ b/Source/WebCore/html/DateInputType.h
@@ -0,0 +1,56 @@
+/*
+ * 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:
+ *
+ * * 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 DateInputType_h
+#define DateInputType_h
+
+#include "BaseDateAndTimeInputType.h"
+
+namespace WebCore {
+
+class DateInputType : public BaseDateAndTimeInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ DateInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual double minimum() const;
+ virtual double maximum() const;
+ virtual double defaultStep() const;
+ virtual double stepScaleFactor() const;
+ virtual bool parsedStepValueShouldBeInteger() const;
+ virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const;
+ virtual bool setMillisecondToDateComponents(double, DateComponents*) const;
+};
+
+} // namespace WebCore
+
+#endif // DateInputType_h
diff --git a/Source/WebCore/html/DateTimeInputType.cpp b/Source/WebCore/html/DateTimeInputType.cpp
new file mode 100644
index 0000000..2acb997
--- /dev/null
+++ b/Source/WebCore/html/DateTimeInputType.cpp
@@ -0,0 +1,100 @@
+/*
+ * 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:
+ *
+ * * 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 "DateTimeInputType.h"
+
+#include "DateComponents.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static const double dateTimeDefaultStep = 60.0;
+static const double dateTimeStepScaleFactor = 1000.0;
+
+PassOwnPtr<InputType> DateTimeInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new DateTimeInputType(element));
+}
+
+const AtomicString& DateTimeInputType::formControlType() const
+{
+ return InputTypeNames::datetime();
+}
+
+double DateTimeInputType::defaultValueForStepUp() const
+{
+ return currentTimeMS();
+}
+
+double DateTimeInputType::minimum() const
+{
+ return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumDateTime());
+}
+
+double DateTimeInputType::maximum() const
+{
+ return parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumDateTime());
+}
+
+double DateTimeInputType::defaultStep() const
+{
+ return dateTimeDefaultStep;
+}
+
+double DateTimeInputType::stepScaleFactor() const
+{
+ return dateTimeStepScaleFactor;
+}
+
+bool DateTimeInputType::scaledStepValueShouldBeInteger() const
+{
+ return true;
+}
+
+bool DateTimeInputType::parseToDateComponentsInternal(const UChar* characters, unsigned length, DateComponents* out) const
+{
+ ASSERT(out);
+ unsigned end;
+ return out->parseDateTime(characters, length, 0, end) && end == length;
+}
+
+bool DateTimeInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+{
+ ASSERT(date);
+ return date->setMillisecondsSinceEpochForDateTime(value);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/DateTimeInputType.h b/Source/WebCore/html/DateTimeInputType.h
new file mode 100644
index 0000000..1b9e06c
--- /dev/null
+++ b/Source/WebCore/html/DateTimeInputType.h
@@ -0,0 +1,57 @@
+/*
+ * 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:
+ *
+ * * 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 DateTimeInputType_h
+#define DateTimeInputType_h
+
+#include "BaseDateAndTimeInputType.h"
+
+namespace WebCore {
+
+class DateTimeInputType : public BaseDateAndTimeInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ DateTimeInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual double defaultValueForStepUp() const;
+ virtual double minimum() const;
+ virtual double maximum() const;
+ virtual double defaultStep() const;
+ virtual double stepScaleFactor() const;
+ virtual bool scaledStepValueShouldBeInteger() const;
+ virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const;
+ virtual bool setMillisecondToDateComponents(double, DateComponents*) const;
+};
+
+} // namespace WebCore
+
+#endif // DateTimeInputType_h
diff --git a/Source/WebCore/html/DateTimeLocalInputType.cpp b/Source/WebCore/html/DateTimeLocalInputType.cpp
new file mode 100644
index 0000000..361fad7
--- /dev/null
+++ b/Source/WebCore/html/DateTimeLocalInputType.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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:
+ *
+ * * 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 "DateTimeLocalInputType.h"
+
+#include "DateComponents.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static const double dateTimeLocalDefaultStep = 60.0;
+static const double dateTimeLocalStepScaleFactor = 1000.0;
+
+PassOwnPtr<InputType> DateTimeLocalInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new DateTimeLocalInputType(element));
+}
+
+const AtomicString& DateTimeLocalInputType::formControlType() const
+{
+ return InputTypeNames::datetimelocal();
+}
+
+double DateTimeLocalInputType::valueAsDate() const
+{
+ // valueAsDate doesn't work for the datetime-local type according to the standard.
+ return DateComponents::invalidMilliseconds();
+}
+
+void DateTimeLocalInputType::setValueAsDate(double value, ExceptionCode& ec) const
+{
+ // valueAsDate doesn't work for the datetime-local type according to the standard.
+ InputType::setValueAsDate(value, ec);
+}
+
+double DateTimeLocalInputType::minimum() const
+{
+ return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumDateTime());
+}
+
+double DateTimeLocalInputType::maximum() const
+{
+ return parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumDateTime());
+}
+
+double DateTimeLocalInputType::defaultStep() const
+{
+ return dateTimeLocalDefaultStep;
+}
+
+double DateTimeLocalInputType::stepScaleFactor() const
+{
+ return dateTimeLocalStepScaleFactor;
+}
+
+bool DateTimeLocalInputType::scaledStepValueShouldBeInteger() const
+{
+ return true;
+}
+
+bool DateTimeLocalInputType::parseToDateComponentsInternal(const UChar* characters, unsigned length, DateComponents* out) const
+{
+ ASSERT(out);
+ unsigned end;
+ return out->parseDateTimeLocal(characters, length, 0, end) && end == length;
+}
+
+bool DateTimeLocalInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+{
+ ASSERT(date);
+ return date->setMillisecondsSinceEpochForDateTimeLocal(value);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/DateTimeLocalInputType.h b/Source/WebCore/html/DateTimeLocalInputType.h
new file mode 100644
index 0000000..ae118af
--- /dev/null
+++ b/Source/WebCore/html/DateTimeLocalInputType.h
@@ -0,0 +1,58 @@
+/*
+ * 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:
+ *
+ * * 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 DateTimeLocalInputType_h
+#define DateTimeLocalInputType_h
+
+#include "BaseDateAndTimeInputType.h"
+
+namespace WebCore {
+
+class DateTimeLocalInputType : public BaseDateAndTimeInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ DateTimeLocalInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual double valueAsDate() const;
+ virtual void setValueAsDate(double, ExceptionCode&) const;
+ virtual double minimum() const;
+ virtual double maximum() const;
+ virtual double defaultStep() const;
+ virtual double stepScaleFactor() const;
+ virtual bool scaledStepValueShouldBeInteger() const;
+ virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const;
+ virtual bool setMillisecondToDateComponents(double, DateComponents*) const;
+};
+
+} // namespace WebCore
+
+#endif // DateTimeLocalInputType_h
diff --git a/Source/WebCore/html/DocTypeStrings.gperf b/Source/WebCore/html/DocTypeStrings.gperf
new file mode 100644
index 0000000..2e2a7e8
--- /dev/null
+++ b/Source/WebCore/html/DocTypeStrings.gperf
@@ -0,0 +1,103 @@
+%{
+#include "HashTools.h"
+#include <string.h>
+
+namespace WebCore {
+%}
+%struct-type
+struct PubIDInfo;
+%omit-struct-type
+%language=C++
+%readonly-tables
+%global-table
+%compare-strncmp
+%define class-name DocTypeStringsHash
+%define initializer-suffix ,PubIDInfo::eAlmostStandards,PubIDInfo::eAlmostStandards
+%define lookup-function-name findDoctypeEntryImpl
+%define hash-function-name doctype_hash_function
+%enum
+%%
+"+//silmaril//dtd html pro v0r11 19970101//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//advasoft ltd//dtd html 3.0 aswedit + extensions//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//as//dtd html 3.0 aswedit + extensions//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html 2.0 level 1//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html 2.0 level 2//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html 2.0 strict level 1//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html 2.0 strict level 2//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html 2.0 strict//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html 2.0//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html 2.1e//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html 3.0//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html 3.0//en//", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html 3.2 final//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html 3.2//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html 3//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html level 0//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html level 0//en//2.0", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html level 1//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html level 1//en//2.0", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html level 2//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html level 2//en//2.0", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html level 3//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html level 3//en//3.0", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html strict level 0//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html strict level 0//en//2.0", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html strict level 1//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html strict level 1//en//2.0", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html strict level 2//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html strict level 2//en//2.0", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html strict level 3//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html strict level 3//en//3.0", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html strict//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html strict//en//2.0", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html strict//en//3.0", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html//en//2.0", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//ietf//dtd html//en//3.0", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//metrius//dtd metrius presentational//en", PubIDInfo::eQuirks, PubIDInfo::eQuirks
+"-//microsoft//dtd internet explorer 2.0 html strict//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//microsoft//dtd internet explorer 2.0 html//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//microsoft//dtd internet explorer 2.0 tables//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//microsoft//dtd internet explorer 3.0 html strict//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//microsoft//dtd internet explorer 3.0 html//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//microsoft//dtd internet explorer 3.0 tables//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//netscape comm. corp.//dtd html//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//netscape comm. corp.//dtd strict html//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//o'reilly and associates//dtd html 2.0//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//o'reilly and associates//dtd html extended 1.0//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//o'reilly and associates//dtd html extended relaxed 1.0//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//en", PubIDInfo::eQuirks, PubIDInfo::eQuirks
+"-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//en", PubIDInfo::eQuirks, PubIDInfo::eQuirks
+"-//spyglass//dtd html 2.0 extended//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//sq//dtd html 2.0 hotmetal + extensions//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//sun microsystems corp.//dtd hotjava html//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//sun microsystems corp.//dtd hotjava strict html//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//w30//dtd w3 html 2.0//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//w3c//dtd html 3 1995-03-24//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//w3c//dtd html 3.2 draft//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//w3c//dtd html 3.2 final//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//w3c//dtd html 3.2//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//w3c//dtd html 3.2s draft//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//w3c//dtd html 4.0 frameset//en", PubIDInfo::eQuirks, PubIDInfo::eQuirks
+"-//w3c//dtd html 4.0 transitional//en", PubIDInfo::eQuirks, PubIDInfo::eQuirks
+"-//w3c//dtd html 4.01 frameset//en", PubIDInfo::eQuirks, PubIDInfo::eAlmostStandards
+"-//w3c//dtd html 4.01 transitional//en", PubIDInfo::eQuirks, PubIDInfo::eAlmostStandards
+"-//w3c//dtd html experimental 19960712//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//w3c//dtd html experimental 970421//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//w3c//dtd w3 html//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//w3c//dtd xhtml 1.0 frameset//en", PubIDInfo::eAlmostStandards, PubIDInfo::eAlmostStandards
+"-//w3c//dtd xhtml 1.0 transitional//en", PubIDInfo::eAlmostStandards, PubIDInfo::eAlmostStandards
+"-//w3o//dtd w3 html 3.0//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//w3o//dtd w3 html 3.0//en//", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//w3o//dtd w3 html strict 3.0//en//", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//webtechs//dtd mozilla html 2.0//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-//webtechs//dtd mozilla html//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+"-/w3c/dtd html 4.0 transitional/en", PubIDInfo::eQuirks, PubIDInfo::eQuirks
+"html", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+%%
+const PubIDInfo* findDoctypeEntry(register const char* str, register unsigned int len)
+{
+ return DocTypeStringsHash::findDoctypeEntryImpl(str, len);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/EmailInputType.cpp b/Source/WebCore/html/EmailInputType.cpp
new file mode 100644
index 0000000..5d153a1
--- /dev/null
+++ b/Source/WebCore/html/EmailInputType.cpp
@@ -0,0 +1,93 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * Copyright (C) 2009 Michelangelo De Simone <micdesim@gmail.com>
+ * Copyright (C) 2010 Google 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "EmailInputType.h"
+
+#include "HTMLInputElement.h"
+#include "LocalizedStrings.h"
+#include "RegularExpression.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+static const char emailPattern[] =
+ "[a-z0-9!#$%&'*+/=?^_`{|}~.-]+" // local part
+ "@"
+ "[a-z0-9-]+(\\.[a-z0-9-]+)+"; // domain part
+
+static bool isValidEmailAddress(const String& address)
+{
+ int addressLength = address.length();
+ if (!addressLength)
+ return false;
+
+ DEFINE_STATIC_LOCAL(const RegularExpression, regExp, (emailPattern, TextCaseInsensitive));
+
+ int matchLength;
+ int matchOffset = regExp.match(address, 0, &matchLength);
+
+ return !matchOffset && matchLength == addressLength;
+}
+
+PassOwnPtr<InputType> EmailInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new EmailInputType(element));
+}
+
+const AtomicString& EmailInputType::formControlType() const
+{
+ return InputTypeNames::email();
+}
+
+bool EmailInputType::typeMismatchFor(const String& value) const
+{
+ if (value.isEmpty())
+ return false;
+ if (!element()->multiple())
+ return !isValidEmailAddress(value);
+ Vector<String> addresses;
+ value.split(',', addresses);
+ for (unsigned i = 0; i < addresses.size(); ++i) {
+ if (!isValidEmailAddress(addresses[i]))
+ return true;
+ }
+ return false;
+}
+
+bool EmailInputType::typeMismatch() const
+{
+ return typeMismatchFor(element()->value());
+}
+
+String EmailInputType::typeMismatchText() const
+{
+ return element()->multiple() ? validationMessageTypeMismatchForMultipleEmailText() : validationMessageTypeMismatchForEmailText();
+}
+
+bool EmailInputType::isEmailField() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/EmailInputType.h b/Source/WebCore/html/EmailInputType.h
new file mode 100644
index 0000000..b94ae9c
--- /dev/null
+++ b/Source/WebCore/html/EmailInputType.h
@@ -0,0 +1,53 @@
+/*
+ * 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:
+ *
+ * * 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 EmailInputType_h
+#define EmailInputType_h
+
+#include "BaseTextInputType.h"
+
+namespace WebCore {
+
+class EmailInputType : public BaseTextInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ EmailInputType(HTMLInputElement* element) : BaseTextInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool typeMismatchFor(const String&) const;
+ virtual bool typeMismatch() const;
+ virtual String typeMismatchText() const;
+ virtual bool isEmailField() const;
+};
+
+} // namespace WebCore
+
+#endif // ButtonInputType_h
diff --git a/Source/WebCore/html/FTPDirectoryDocument.cpp b/Source/WebCore/html/FTPDirectoryDocument.cpp
new file mode 100644
index 0000000..2a08696
--- /dev/null
+++ b/Source/WebCore/html/FTPDirectoryDocument.cpp
@@ -0,0 +1,452 @@
+/*
+ * 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
+ * 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"
+#if ENABLE(FTPDIR)
+#include "FTPDirectoryDocument.h"
+
+#include "CharacterNames.h"
+#include "HTMLDocumentParser.h"
+#include "HTMLNames.h"
+#include "HTMLTableElement.h"
+#include "LocalizedStrings.h"
+#include "Logging.h"
+#include "FTPDirectoryParser.h"
+#include "SegmentedString.h"
+#include "Settings.h"
+#include "SharedBuffer.h"
+#include "Text.h"
+
+#include <wtf/text/CString.h>
+#include <wtf/text/StringConcatenate.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/StdLibExtras.h>
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+class FTPDirectoryDocumentParser : public HTMLDocumentParser {
+public:
+ static PassRefPtr<FTPDirectoryDocumentParser> create(HTMLDocument* document)
+ {
+ return adoptRef(new FTPDirectoryDocumentParser(document));
+ }
+
+ virtual void append(const SegmentedString&);
+ virtual void finish();
+
+ virtual bool isWaitingForScripts() const { return false; }
+
+ inline void checkBuffer(int len = 10)
+ {
+ if ((m_dest - m_buffer) > m_size - len) {
+ // Enlarge buffer
+ int newSize = max(m_size * 2, m_size + len);
+ int oldOffset = m_dest - m_buffer;
+ m_buffer = static_cast<UChar*>(fastRealloc(m_buffer, newSize * sizeof(UChar)));
+ m_dest = m_buffer + oldOffset;
+ m_size = newSize;
+ }
+ }
+
+private:
+ FTPDirectoryDocumentParser(HTMLDocument*);
+
+ // The parser will attempt to load the document template specified via the preference
+ // Failing that, it will fall back and create the basic document which will have a minimal
+ // table for presenting the FTP directory in a useful manner
+ bool loadDocumentTemplate();
+ void createBasicDocument();
+
+ void parseAndAppendOneLine(const String&);
+ void appendEntry(const String& name, const String& size, const String& date, bool isDirectory);
+ PassRefPtr<Element> createTDForFilename(const String&);
+
+ RefPtr<HTMLTableElement> m_tableElement;
+
+ bool m_skipLF;
+ bool m_parsedTemplate;
+
+ int m_size;
+ UChar* m_buffer;
+ UChar* m_dest;
+ String m_carryOver;
+
+ ListState m_listState;
+};
+
+FTPDirectoryDocumentParser::FTPDirectoryDocumentParser(HTMLDocument* document)
+ : HTMLDocumentParser(document, false)
+ , m_skipLF(false)
+ , m_parsedTemplate(false)
+ , m_size(254)
+ , m_buffer(static_cast<UChar*>(fastMalloc(sizeof(UChar) * m_size)))
+ , m_dest(m_buffer)
+{
+}
+
+void FTPDirectoryDocumentParser::appendEntry(const String& filename, const String& size, const String& date, bool isDirectory)
+{
+ ExceptionCode ec;
+
+ RefPtr<Element> rowElement = m_tableElement->insertRow(-1, ec);
+ rowElement->setAttribute("class", "ftpDirectoryEntryRow", ec);
+
+ RefPtr<Element> element = document()->createElement(tdTag, false);
+ element->appendChild(Text::create(document(), String(&noBreakSpace, 1)), ec);
+ if (isDirectory)
+ element->setAttribute("class", "ftpDirectoryIcon ftpDirectoryTypeDirectory", ec);
+ else
+ element->setAttribute("class", "ftpDirectoryIcon ftpDirectoryTypeFile", ec);
+ rowElement->appendChild(element, ec);
+
+ element = createTDForFilename(filename);
+ element->setAttribute("class", "ftpDirectoryFileName", ec);
+ rowElement->appendChild(element, ec);
+
+ element = document()->createElement(tdTag, false);
+ element->appendChild(Text::create(document(), date), ec);
+ element->setAttribute("class", "ftpDirectoryFileDate", ec);
+ rowElement->appendChild(element, ec);
+
+ element = document()->createElement(tdTag, false);
+ element->appendChild(Text::create(document(), size), ec);
+ element->setAttribute("class", "ftpDirectoryFileSize", ec);
+ rowElement->appendChild(element, ec);
+}
+
+PassRefPtr<Element> FTPDirectoryDocumentParser::createTDForFilename(const String& filename)
+{
+ ExceptionCode ec;
+
+ String fullURL = document()->baseURL().string();
+ if (fullURL[fullURL.length() - 1] == '/')
+ fullURL.append(filename);
+ else
+ fullURL.append("/" + filename);
+
+ RefPtr<Element> anchorElement = document()->createElement(aTag, false);
+ anchorElement->setAttribute("href", fullURL, ec);
+ anchorElement->appendChild(Text::create(document(), filename), ec);
+
+ RefPtr<Element> tdElement = document()->createElement(tdTag, false);
+ tdElement->appendChild(anchorElement, ec);
+
+ return tdElement.release();
+}
+
+static String processFilesizeString(const String& size, bool isDirectory)
+{
+ if (isDirectory)
+ return "--";
+
+ bool valid;
+ int64_t bytes = size.toUInt64(&valid);
+ if (!valid)
+ return unknownFileSizeText();
+
+ if (bytes < 1000000)
+ return String::format("%.2f KB", static_cast<float>(bytes)/1000);
+
+ if (bytes < 1000000000)
+ return String::format("%.2f MB", static_cast<float>(bytes)/1000000);
+
+ return String::format("%.2f GB", static_cast<float>(bytes)/1000000000);
+}
+
+static bool wasLastDayOfMonth(int year, int month, int day)
+{
+ static int lastDays[] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ if (month < 0 || month > 11)
+ return false;
+
+ if (month == 2) {
+ if (year % 4 == 0 && (year % 100 || year % 400 == 0)) {
+ if (day == 29)
+ return true;
+ return false;
+ }
+
+ if (day == 28)
+ return true;
+ return false;
+ }
+
+ return lastDays[month] == day;
+}
+
+static String processFileDateString(const FTPTime& fileTime)
+{
+ // FIXME: Need to localize this string?
+
+ String timeOfDay;
+
+ if (!(fileTime.tm_hour == 0 && fileTime.tm_min == 0 && fileTime.tm_sec == 0)) {
+ int hour = fileTime.tm_hour;
+ ASSERT(hour >= 0 && hour < 24);
+
+ if (hour < 12) {
+ if (hour == 0)
+ hour = 12;
+ timeOfDay = String::format(", %i:%02i AM", hour, fileTime.tm_min);
+ } else {
+ hour = hour - 12;
+ if (hour == 0)
+ hour = 12;
+ timeOfDay = String::format(", %i:%02i PM", hour, fileTime.tm_min);
+ }
+ }
+
+ // If it was today or yesterday, lets just do that - but we have to compare to the current time
+ struct tm now;
+ time_t now_t = time(NULL);
+ getLocalTime(&now_t, &now);
+
+ // localtime does "year = current year - 1900", compensate for that for readability and comparison purposes
+ now.tm_year += 1900;
+
+ if (fileTime.tm_year == now.tm_year) {
+ if (fileTime.tm_mon == now.tm_mon) {
+ if (fileTime.tm_mday == now.tm_mday)
+ return "Today" + timeOfDay;
+ if (fileTime.tm_mday == now.tm_mday - 1)
+ return "Yesterday" + timeOfDay;
+ }
+
+ if (now.tm_mday == 1 && (now.tm_mon == fileTime.tm_mon + 1 || (now.tm_mon == 0 && fileTime.tm_mon == 11)) &&
+ wasLastDayOfMonth(fileTime.tm_year, fileTime.tm_mon, fileTime.tm_mday))
+ return "Yesterday" + timeOfDay;
+ }
+
+ if (fileTime.tm_year == now.tm_year - 1 && fileTime.tm_mon == 12 && fileTime.tm_mday == 31 && now.tm_mon == 1 && now.tm_mday == 1)
+ return "Yesterday" + timeOfDay;
+
+ static const char* months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" };
+
+ int month = fileTime.tm_mon;
+ if (month < 0 || month > 11)
+ month = 12;
+
+ String dateString;
+
+ if (fileTime.tm_year > -1)
+ dateString = makeString(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.tm_year));
+
+ return dateString + timeOfDay;
+}
+
+void FTPDirectoryDocumentParser::parseAndAppendOneLine(const String& inputLine)
+{
+ ListResult result;
+ CString latin1Input = inputLine.latin1();
+
+ FTPEntryType typeResult = parseOneFTPLine(latin1Input.data(), m_listState, result);
+
+ // FTPMiscEntry is a comment or usage statistic which we don't care about, and junk is invalid data - bail in these 2 cases
+ if (typeResult == FTPMiscEntry || typeResult == FTPJunkEntry)
+ return;
+
+ String filename(result.filename, result.filenameLength);
+ if (result.type == FTPDirectoryEntry) {
+ filename.append("/");
+
+ // We have no interest in linking to "current directory"
+ if (filename == "./")
+ return;
+ }
+
+ LOG(FTP, "Appending entry - %s, %s", filename.ascii().data(), result.fileSize.ascii().data());
+
+ appendEntry(filename, processFilesizeString(result.fileSize, result.type == FTPDirectoryEntry), processFileDateString(result.modifiedTime), result.type == FTPDirectoryEntry);
+}
+
+static inline PassRefPtr<SharedBuffer> createTemplateDocumentData(Settings* settings)
+{
+ 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.release();
+}
+
+bool FTPDirectoryDocumentParser::loadDocumentTemplate()
+{
+ DEFINE_STATIC_LOCAL(RefPtr<SharedBuffer>, templateDocumentData, (createTemplateDocumentData(document()->settings())));
+ // 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");
+ return false;
+ }
+
+ HTMLDocumentParser::insert(String(templateDocumentData->data(), templateDocumentData->size()));
+
+ RefPtr<Element> tableElement = document()->getElementById("ftpDirectoryTable");
+ if (!tableElement)
+ LOG_ERROR("Unable to find element by id \"ftpDirectoryTable\" in the template document.");
+ else if (!tableElement->hasTagName(tableTag))
+ LOG_ERROR("Element of id \"ftpDirectoryTable\" is not a table element");
+ else
+ m_tableElement = static_cast<HTMLTableElement*>(tableElement.get());
+
+ // Bail if we found the table element
+ if (m_tableElement)
+ return true;
+
+ // Otherwise create one manually
+ tableElement = document()->createElement(tableTag, false);
+ m_tableElement = static_cast<HTMLTableElement*>(tableElement.get());
+ ExceptionCode ec;
+ m_tableElement->setAttribute("id", "ftpDirectoryTable", ec);
+
+ // 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 (Element* body = document()->body())
+ body->appendChild(m_tableElement, ec);
+ else
+ document()->appendChild(m_tableElement, ec);
+
+ return true;
+}
+
+void FTPDirectoryDocumentParser::createBasicDocument()
+{
+ LOG(FTP, "Creating a basic FTP document structure as no template was loaded");
+
+ // FIXME: Make this "basic document" more acceptable
+
+ RefPtr<Element> bodyElement = document()->createElement(bodyTag, false);
+
+ ExceptionCode ec;
+ document()->appendChild(bodyElement, ec);
+
+ RefPtr<Element> tableElement = document()->createElement(tableTag, false);
+ m_tableElement = static_cast<HTMLTableElement*>(tableElement.get());
+ m_tableElement->setAttribute("id", "ftpDirectoryTable", ec);
+
+ bodyElement->appendChild(m_tableElement, ec);
+}
+
+void FTPDirectoryDocumentParser::append(const SegmentedString& source)
+{
+ // Make sure we have the table element to append to by loading the template set in the pref, or
+ // creating a very basic document with the appropriate table
+ if (!m_tableElement) {
+ if (!loadDocumentTemplate())
+ createBasicDocument();
+ ASSERT(m_tableElement);
+ }
+
+ bool foundNewLine = false;
+
+ m_dest = m_buffer;
+ SegmentedString str = source;
+ while (!str.isEmpty()) {
+ UChar c = *str;
+
+ if (c == '\r') {
+ *m_dest++ = '\n';
+ foundNewLine = true;
+ // possibly skip an LF in the case of an CRLF sequence
+ m_skipLF = true;
+ } else if (c == '\n') {
+ if (!m_skipLF)
+ *m_dest++ = c;
+ else
+ m_skipLF = false;
+ } else {
+ *m_dest++ = c;
+ m_skipLF = false;
+ }
+
+ str.advance();
+
+ // Maybe enlarge the buffer
+ checkBuffer();
+ }
+
+ if (!foundNewLine) {
+ m_dest = m_buffer;
+ return;
+ }
+
+ UChar* start = m_buffer;
+ UChar* cursor = start;
+
+ while (cursor < m_dest) {
+ if (*cursor == '\n') {
+ m_carryOver.append(String(start, cursor - start));
+ LOG(FTP, "%s", m_carryOver.ascii().data());
+ parseAndAppendOneLine(m_carryOver);
+ m_carryOver = String();
+
+ start = ++cursor;
+ } else
+ cursor++;
+ }
+
+ // Copy the partial line we have left to the carryover buffer
+ if (cursor - start > 1)
+ m_carryOver.append(String(start, cursor - start - 1));
+}
+
+void FTPDirectoryDocumentParser::finish()
+{
+ // Possible the last line in the listing had no newline, so try to parse it now
+ if (!m_carryOver.isEmpty()) {
+ parseAndAppendOneLine(m_carryOver);
+ m_carryOver = String();
+ }
+
+ m_tableElement = 0;
+ fastFree(m_buffer);
+
+ HTMLDocumentParser::finish();
+}
+
+FTPDirectoryDocument::FTPDirectoryDocument(Frame* frame, const KURL& url)
+ : HTMLDocument(frame, url)
+{
+#ifndef NDEBUG
+ LogFTP.state = WTFLogChannelOn;
+#endif
+}
+
+PassRefPtr<DocumentParser> FTPDirectoryDocument::createParser()
+{
+ return FTPDirectoryDocumentParser::create(this);
+}
+
+}
+
+#endif // ENABLE(FTPDIR)
diff --git a/Source/WebCore/html/FTPDirectoryDocument.h b/Source/WebCore/html/FTPDirectoryDocument.h
new file mode 100644
index 0000000..e7e52f7
--- /dev/null
+++ b/Source/WebCore/html/FTPDirectoryDocument.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 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
+ * 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 FTPDirectoryDocument_h
+#define FTPDirectoryDocument_h
+
+#include "HTMLDocument.h"
+
+namespace WebCore {
+
+class DOMImplementation;
+
+class FTPDirectoryDocument : public HTMLDocument {
+public:
+ static PassRefPtr<FTPDirectoryDocument> create(Frame* frame, const KURL& url)
+ {
+ return adoptRef(new FTPDirectoryDocument(frame, url));
+ }
+
+private:
+ FTPDirectoryDocument(Frame*, const KURL&);
+ virtual PassRefPtr<DocumentParser> createParser();
+};
+
+} // namespace WebCore
+
+#endif // FTPDirectoryDocument_h
diff --git a/Source/WebCore/html/FileInputType.cpp b/Source/WebCore/html/FileInputType.cpp
new file mode 100644
index 0000000..a4d1dd3
--- /dev/null
+++ b/Source/WebCore/html/FileInputType.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "FileInputType.h"
+
+#include "Event.h"
+#include "File.h"
+#include "FileList.h"
+#include "FileSystem.h"
+#include "FormDataList.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "LocalizedStrings.h"
+#include "RenderFileUploadControl.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline FileInputType::FileInputType(HTMLInputElement* element)
+ : BaseButtonInputType(element)
+ , m_fileList(FileList::create())
+{
+}
+
+PassOwnPtr<InputType> FileInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new FileInputType(element));
+}
+
+const AtomicString& FileInputType::formControlType() const
+{
+ return InputTypeNames::file();
+}
+
+bool FileInputType::appendFormData(FormDataList& encoding, bool multipart) const
+{
+ FileList* fileList = element()->files();
+ unsigned numFiles = fileList->length();
+ if (!multipart) {
+ // Send only the basenames.
+ // 4.10.16.4 and 4.10.16.6 sections in HTML5.
+
+ // Unlike the multipart case, we have no special handling for the empty
+ // fileList because Netscape doesn't support for non-multipart
+ // submission of file inputs, and Firefox doesn't add "name=" query
+ // parameter.
+ for (unsigned i = 0; i < numFiles; ++i)
+ encoding.appendData(element()->name(), fileList->item(i)->fileName());
+ return true;
+ }
+
+ // If no filename at all is entered, return successful but empty.
+ // Null would be more logical, but Netscape posts an empty file. Argh.
+ if (!numFiles) {
+ encoding.appendBlob(element()->name(), File::create(""));
+ return true;
+ }
+
+ for (unsigned i = 0; i < numFiles; ++i)
+ encoding.appendBlob(element()->name(), fileList->item(i));
+ return true;
+}
+
+bool FileInputType::valueMissing(const String& value) const
+{
+ return value.isEmpty();
+}
+
+String FileInputType::valueMissingText() const
+{
+ return element()->multiple() ? validationMessageValueMissingForMultipleFileText() : validationMessageValueMissingForFileText();
+}
+
+void FileInputType::handleDOMActivateEvent(Event* event)
+{
+ if (element()->disabled() || !element()->renderer())
+ return;
+ toRenderFileUploadControl(element()->renderer())->click();
+ event->setDefaultHandled();
+}
+
+RenderObject* FileInputType::createRenderer(RenderArena* arena, RenderStyle*) const
+{
+ return new (arena) RenderFileUploadControl(element());
+}
+
+bool FileInputType::canSetStringValue() const
+{
+ return false;
+}
+
+bool FileInputType::canChangeFromAnotherType() const
+{
+ // Don't allow the type to be changed to file after the first type change.
+ // In other engines this might mean a JavaScript programmer could set a text
+ // field's value to something like /etc/passwd and then change it to a file input.
+ // I don't think this would actually occur in WebKit, but this rule still may be
+ // important for compatibility.
+ return false;
+}
+
+FileList* FileInputType::files()
+{
+ return m_fileList.get();
+}
+
+bool FileInputType::canSetValue(const String& value)
+{
+ // For security reasons, we don't allow setting the filename, but we do allow clearing it.
+ // The HTML5 spec (as of the 10/24/08 working draft) says that the value attribute isn't
+ // applicable to the file upload control at all, but for now we are keeping this behavior
+ // to avoid breaking existing websites that may be relying on this.
+ return value.isEmpty();
+}
+
+bool FileInputType::getTypeSpecificValue(String& value)
+{
+ if (m_fileList->isEmpty()) {
+ value = String();
+ return true;
+ }
+
+ // HTML5 tells us that we're supposed to use this goofy value for
+ // file input controls. Historically, browsers revealed the real
+ // file path, but that's a privacy problem. Code on the web
+ // decided to try to parse the value by looking for backslashes
+ // (because that's what Windows file paths use). To be compatible
+ // with that code, we make up a fake path for the file.
+ value = "C:\\fakepath\\" + m_fileList->item(0)->fileName();
+ return true;
+}
+
+bool FileInputType::storesValueSeparateFromAttribute()
+{
+ return true;
+}
+
+void FileInputType::setFileList(const Vector<String>& paths)
+{
+ m_fileList->clear();
+ size_t size = paths.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(paths[0]);
+ for (size_t i = 1; i < size; i++) {
+ while (!paths[i].startsWith(rootPath))
+ rootPath = directoryName(rootPath);
+ }
+ rootPath = directoryName(rootPath);
+ ASSERT(rootPath.length());
+ for (size_t i = 0; i < size; i++) {
+ // Normalize backslashes to slashes before exposing the relative path to script.
+ String relativePath = paths[i].substring(1 + rootPath.length()).replace('\\', '/');
+ m_fileList->append(File::create(relativePath, paths[i]));
+ }
+ return;
+ }
+#endif
+
+ for (size_t i = 0; i < size; i++)
+ m_fileList->append(File::create(paths[i]));
+}
+
+bool FileInputType::isFileUpload() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/FileInputType.h b/Source/WebCore/html/FileInputType.h
new file mode 100644
index 0000000..6d79ecd
--- /dev/null
+++ b/Source/WebCore/html/FileInputType.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 FileInputType_h
+#define FileInputType_h
+
+#include "BaseButtonInputType.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class FileList;
+
+class FileInputType : public BaseButtonInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ FileInputType(HTMLInputElement*);
+ virtual const AtomicString& formControlType() const;
+ virtual bool appendFormData(FormDataList&, bool) const;
+ virtual bool valueMissing(const String&) const;
+ virtual String valueMissingText() const;
+ virtual void handleDOMActivateEvent(Event*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
+ virtual bool canSetStringValue() const;
+ virtual bool canChangeFromAnotherType() const;
+ virtual FileList* files();
+ virtual bool canSetValue(const String&);
+ virtual bool getTypeSpecificValue(String&); // Checked first, before internal storage or the value attribute.
+ virtual bool storesValueSeparateFromAttribute();
+ virtual void setFileList(const Vector<String>& paths);
+ virtual bool isFileUpload() const;
+
+ RefPtr<FileList> m_fileList;
+};
+
+} // namespace WebCore
+
+#endif // FileInputType_h
diff --git a/Source/WebCore/html/FormAssociatedElement.cpp b/Source/WebCore/html/FormAssociatedElement.cpp
new file mode 100644
index 0000000..a97c0e2
--- /dev/null
+++ b/Source/WebCore/html/FormAssociatedElement.cpp
@@ -0,0 +1,162 @@
+/*
+ * 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 Apple Inc. All rights reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "FormAssociatedElement.h"
+
+#include "HTMLFormControlElement.h"
+#include "HTMLFormElement.h"
+#include "HTMLNames.h"
+#include "HTMLObjectElement.h"
+#include "ValidityState.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+FormAssociatedElement::FormAssociatedElement(HTMLFormElement* form)
+ : m_form(form)
+{
+}
+
+FormAssociatedElement::~FormAssociatedElement()
+{
+}
+
+ValidityState* FormAssociatedElement::validity()
+{
+ if (!m_validityState)
+ m_validityState = ValidityState::create(this);
+
+ return m_validityState.get();
+}
+
+void FormAssociatedElement::insertedIntoTree()
+{
+ HTMLElement* element = toHTMLElement(this);
+ if (element->fastHasAttribute(formAttr)) {
+ element->document()->registerFormElementWithFormAttribute(this);
+ Element* formElement = element->document()->getElementById(element->fastGetAttribute(formAttr));
+ if (formElement && formElement->hasTagName(formTag)) {
+ if (m_form)
+ m_form->removeFormElement(this);
+ m_form = static_cast<HTMLFormElement*>(formElement);
+ m_form->registerFormElement(this);
+ }
+ }
+ if (!m_form) {
+ // This handles the case of a new form element being created by
+ // JavaScript and inserted inside a form. In the case of the parser
+ // setting a form, we will already have a non-null value for m_form,
+ // and so we don't need to do anything.
+ m_form = element->findFormAncestor();
+ if (m_form)
+ m_form->registerFormElement(this);
+ }
+}
+
+static inline Node* findRoot(Node* n)
+{
+ Node* root = n;
+ for (; n; n = n->parentNode())
+ root = n;
+ return root;
+}
+
+void FormAssociatedElement::removedFromTree()
+{
+ HTMLElement* element = toHTMLElement(this);
+ if (element->fastHasAttribute(formAttr))
+ element->document()->unregisterFormElementWithFormAttribute(this);
+
+ // If the form and element are both in the same tree, preserve the connection to the form.
+ // Otherwise, null out our form and remove ourselves from the form's list of elements.
+ if (m_form && findRoot(element) != findRoot(m_form))
+ removeFromForm();
+}
+
+void FormAssociatedElement::removeFromForm()
+{
+ if (!m_form)
+ return;
+ m_form->removeFormElement(this);
+ m_form = 0;
+}
+
+void FormAssociatedElement::resetFormOwner(HTMLFormElement* form)
+{
+ HTMLElement* element = toHTMLElement(this);
+ const AtomicString& formId(element->fastGetAttribute(formAttr));
+ if (m_form) {
+ if (formId.isNull())
+ return;
+ m_form->removeFormElement(this);
+ }
+ m_form = 0;
+ if (!formId.isNull()) {
+ // The HTML5 spec says that the element should be associated with
+ // the first element in the document to have an ID that equal to
+ // the value of form attribute, so we put the result of
+ // document()->getElementById() over the given element.
+ Element* firstElement = element->document()->getElementById(formId);
+ if (firstElement && firstElement->hasTagName(formTag))
+ m_form = static_cast<HTMLFormElement*>(firstElement);
+ else
+ m_form = form;
+ } else
+ m_form = element->findFormAncestor();
+ if (m_form)
+ m_form->registerFormElement(this);
+}
+
+void FormAssociatedElement::formAttributeChanged()
+{
+ HTMLElement* element = toHTMLElement(this);
+ if (!element->fastHasAttribute(formAttr)) {
+ // The form attribute removed. We need to reset form owner here.
+ if (m_form)
+ m_form->removeFormElement(this);
+ m_form = element->findFormAncestor();
+ if (m_form)
+ form()->registerFormElement(this);
+ } else
+ resetFormOwner(0);
+}
+
+const HTMLElement* toHTMLElement(const FormAssociatedElement* associatedElement)
+{
+ if (associatedElement->isFormControlElement())
+ return static_cast<const HTMLFormControlElement*>(associatedElement);
+ // Assumes the element is an HTMLObjectElement
+ const HTMLElement* element = static_cast<const HTMLObjectElement*>(associatedElement);
+ ASSERT(element->hasTagName(objectTag));
+ return element;
+}
+
+HTMLElement* toHTMLElement(FormAssociatedElement* associatedElement)
+{
+ return const_cast<HTMLElement*>(toHTMLElement(static_cast<const FormAssociatedElement*>(associatedElement)));
+}
+
+} // namespace Webcore
diff --git a/Source/WebCore/html/FormAssociatedElement.h b/Source/WebCore/html/FormAssociatedElement.h
new file mode 100644
index 0000000..3c8c6e1
--- /dev/null
+++ b/Source/WebCore/html/FormAssociatedElement.h
@@ -0,0 +1,85 @@
+/*
+ * 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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef FormAssociatedElement_h
+#define FormAssociatedElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class FormDataList;
+class HTMLFormElement;
+class ValidationMessage;
+class ValidityState;
+class VisibleSelection;
+
+class FormAssociatedElement {
+public:
+ virtual ~FormAssociatedElement();
+
+ void ref() { refFormAssociatedElement(); }
+ void deref() { derefFormAssociatedElement(); }
+
+ HTMLFormElement* form() const { return m_form; }
+ ValidityState* validity();
+
+ virtual bool isFormControlElement() const = 0;
+ virtual bool isEnumeratable() const = 0;
+
+ const AtomicString& name() const { return formControlName(); }
+
+ // Override in derived classes to get the encoded name=value pair for submitting.
+ // Return true for a successful control (see HTML4-17.13.2).
+ virtual bool appendFormData(FormDataList&, bool) { return false; }
+
+ virtual void formDestroyed() { m_form = 0; }
+
+ void resetFormOwner(HTMLFormElement*);
+
+protected:
+ FormAssociatedElement(HTMLFormElement*);
+
+ void insertedIntoTree();
+ void removedFromTree();
+
+ void setForm(HTMLFormElement* form) { m_form = form; }
+ void removeFromForm();
+ void formAttributeChanged();
+
+private:
+ virtual const AtomicString& formControlName() const = 0;
+
+ virtual void refFormAssociatedElement() = 0;
+ virtual void derefFormAssociatedElement() = 0;
+
+ HTMLFormElement* m_form;
+ OwnPtr<ValidityState> m_validityState;
+};
+
+HTMLElement* toHTMLElement(FormAssociatedElement*);
+const HTMLElement* toHTMLElement(const FormAssociatedElement*);
+
+} // namespace
+
+#endif // FormAssociatedElement_h
diff --git a/Source/WebCore/html/FormDataList.cpp b/Source/WebCore/html/FormDataList.cpp
new file mode 100644
index 0000000..4503fd2
--- /dev/null
+++ b/Source/WebCore/html/FormDataList.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2005, 2006, 2008 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "FormDataList.h"
+
+#include "LineEnding.h"
+
+namespace WebCore {
+
+FormDataList::FormDataList(const TextEncoding& c)
+ : m_encoding(c)
+{
+}
+
+void FormDataList::appendString(const String& s)
+{
+ CString cstr = m_encoding.encode(s.characters(), s.length(), EntitiesForUnencodables);
+ m_items.append(normalizeLineEndingsToCRLF(cstr));
+}
+
+void FormDataList::appendString(const CString& s)
+{
+ m_items.append(s);
+}
+
+void FormDataList::appendBlob(PassRefPtr<Blob> blob)
+{
+ m_items.append(blob);
+}
+
+} // namespace
diff --git a/Source/WebCore/html/FormDataList.h b/Source/WebCore/html/FormDataList.h
new file mode 100644
index 0000000..8e1a937
--- /dev/null
+++ b/Source/WebCore/html/FormDataList.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2005, 2006, 2008 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef FormDataList_h
+#define FormDataList_h
+
+#include "Blob.h"
+#include "TextEncoding.h"
+#include <wtf/Forward.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+class FormDataList {
+public:
+ class Item {
+ public:
+ Item() { }
+ Item(const WTF::CString& data) : m_data(data) { }
+ Item(PassRefPtr<Blob> blob) : m_blob(blob) { }
+
+ const WTF::CString& data() const { return m_data; }
+ Blob* blob() const { return m_blob.get(); }
+
+ private:
+ WTF::CString m_data;
+ RefPtr<Blob> m_blob;
+ };
+
+ FormDataList(const TextEncoding&);
+
+ void appendData(const String& key, const String& value)
+ {
+ appendString(key);
+ appendString(value);
+ }
+ void appendData(const String& key, const CString& value)
+ {
+ appendString(key);
+ appendString(value);
+ }
+ void appendData(const String& key, int value)
+ {
+ appendString(key);
+ appendString(String::number(value));
+ }
+ void appendBlob(const String& key, PassRefPtr<Blob> blob)
+ {
+ appendString(key);
+ appendBlob(blob);
+ }
+
+ const Vector<Item>& items() const { return m_items; }
+ const TextEncoding& encoding() const { return m_encoding; }
+
+private:
+ void appendString(const CString&);
+ void appendString(const String&);
+ void appendBlob(PassRefPtr<Blob>);
+
+ TextEncoding m_encoding;
+ Vector<Item> m_items;
+};
+
+} // namespace WebCore
+
+#endif // FormDataList_h
diff --git a/Source/WebCore/html/HTMLAllCollection.cpp b/Source/WebCore/html/HTMLAllCollection.cpp
new file mode 100644
index 0000000..dbfed28
--- /dev/null
+++ b/Source/WebCore/html/HTMLAllCollection.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ * 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 "HTMLAllCollection.h"
+
+#include "Node.h"
+
+namespace WebCore {
+
+PassRefPtr<HTMLAllCollection> HTMLAllCollection::create(PassRefPtr<Node> base)
+{
+ return adoptRef(new HTMLAllCollection(base));
+}
+
+HTMLAllCollection::HTMLAllCollection(PassRefPtr<Node> base)
+ : HTMLCollection(base, DocAll)
+{
+}
+
+HTMLAllCollection::~HTMLAllCollection()
+{
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLAllCollection.h b/Source/WebCore/html/HTMLAllCollection.h
new file mode 100644
index 0000000..1dd3ede
--- /dev/null
+++ b/Source/WebCore/html/HTMLAllCollection.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ * 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 HTMLAllCollection_h
+#define HTMLAllCollection_h
+
+#include "HTMLCollection.h"
+
+namespace WebCore {
+
+class HTMLAllCollection : public HTMLCollection {
+public:
+ static PassRefPtr<HTMLAllCollection> create(PassRefPtr<Node>);
+ virtual ~HTMLAllCollection();
+
+private:
+ HTMLAllCollection(PassRefPtr<Node>);
+};
+
+} // namespace WebCore
+
+#endif // HTMLAllCollection_h
diff --git a/Source/WebCore/html/HTMLAllCollection.idl b/Source/WebCore/html/HTMLAllCollection.idl
new file mode 100644
index 0000000..3b65a0a
--- /dev/null
+++ b/Source/WebCore/html/HTMLAllCollection.idl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ * 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.
+ */
+
+module html {
+
+ interface [
+ HasIndexGetter,
+ HasNameGetter,
+ CustomCall,
+ MasqueradesAsUndefined
+ ] HTMLAllCollection {
+ readonly attribute unsigned long length;
+ [Custom] Node item(in unsigned long index);
+ [Custom] Node namedItem(in DOMString name);
+
+ // FIXME: This should return an HTMLAllCollection.
+ NodeList tags(in DOMString name);
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLAnchorElement.cpp b/Source/WebCore/html/HTMLAnchorElement.cpp
new file mode 100644
index 0000000..dcdde28
--- /dev/null
+++ b/Source/WebCore/html/HTMLAnchorElement.cpp
@@ -0,0 +1,559 @@
+/*
+ * 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 Apple Inc. All rights reserved.
+ * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLAnchorElement.h"
+
+#include "Attribute.h"
+#include "EventNames.h"
+#include "Frame.h"
+#include "FrameLoaderTypes.h"
+#include "HTMLImageElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "KeyboardEvent.h"
+#include "MouseEvent.h"
+#include "Page.h"
+#include "PingLoader.h"
+#include "RenderImage.h"
+#include "ResourceHandle.h"
+#include "Settings.h"
+#include "UserGestureIndicator.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , m_wasShiftKeyDownOnMouseDown(false)
+ , m_linkRelations(0)
+{
+}
+
+PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(Document* document)
+{
+ return adoptRef(new HTMLAnchorElement(aTag, document));
+}
+
+PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLAnchorElement(tagName, document));
+}
+
+// This function does not allow leading spaces before the port number.
+static unsigned parsePortFromStringPosition(const String& value, unsigned portStart, unsigned& portEnd)
+{
+ portEnd = portStart;
+ while (isASCIIDigit(value[portEnd]))
+ ++portEnd;
+ return value.substring(portStart, portEnd - portStart).toUInt();
+}
+
+bool HTMLAnchorElement::supportsFocus() const
+{
+ if (isContentEditable())
+ return HTMLElement::supportsFocus();
+ // If not a link we should still be able to focus the element if it has tabIndex.
+ return isLink() || HTMLElement::supportsFocus();
+}
+
+bool HTMLAnchorElement::isMouseFocusable() const
+{
+ // Anchor elements should be mouse focusable, https://bugs.webkit.org/show_bug.cgi?id=26856
+#if !PLATFORM(GTK) && !PLATFORM(QT) && !PLATFORM(EFL)
+ if (isLink())
+ // Only allow links with tabIndex or contentEditable to be mouse focusable.
+ return HTMLElement::supportsFocus();
+#endif
+
+ // Allow tab index etc to control focus.
+ return HTMLElement::isMouseFocusable();
+}
+
+bool HTMLAnchorElement::isKeyboardFocusable(KeyboardEvent* event) const
+{
+ if (!isLink())
+ return HTMLElement::isKeyboardFocusable(event);
+
+ if (!isFocusable())
+ return false;
+
+ if (!document()->frame())
+ return false;
+
+ if (!document()->frame()->eventHandler()->tabsToLinks(event))
+ return false;
+
+ return hasNonEmptyBoundingBox();
+}
+
+static void appendServerMapMousePosition(String& url, Event* event)
+{
+ if (!event->isMouseEvent())
+ return;
+
+ ASSERT(event->target());
+ Node* target = event->target()->toNode();
+ ASSERT(target);
+ if (!target->hasTagName(imgTag))
+ return;
+
+ HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(event->target()->toNode());
+ if (!imageElement || !imageElement->isServerMap())
+ return;
+
+ RenderImage* renderer = toRenderImage(imageElement->renderer());
+ if (!renderer)
+ return;
+
+ // FIXME: This should probably pass true for useTransforms.
+ FloatPoint absolutePosition = renderer->absoluteToLocal(FloatPoint(static_cast<MouseEvent*>(event)->pageX(), static_cast<MouseEvent*>(event)->pageY()));
+ int x = absolutePosition.x();
+ int y = absolutePosition.y();
+ url += "?";
+ url += String::number(x);
+ url += ",";
+ url += String::number(y);
+}
+
+void HTMLAnchorElement::defaultEventHandler(Event* event)
+{
+ if (isLink()) {
+ if (focused() && isEnterKeyKeydownEvent(event) && treatLinkAsLiveForEventType(NonMouseEvent)) {
+ event->setDefaultHandled();
+ dispatchSimulatedClick(event);
+ return;
+ }
+
+ if (isLinkClick(event) && treatLinkAsLiveForEventType(eventType(event))) {
+ String url = stripLeadingAndTrailingHTMLSpaces(getAttribute(hrefAttr));
+ appendServerMapMousePosition(url, event);
+ handleLinkClick(event, document(), url, getAttribute(targetAttr), hasRel(RelationNoReferrer));
+ sendPings(document()->completeURL(url));
+ return;
+ }
+
+ if (isContentEditable()) {
+ // 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 && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() != RightButton && document()->frame() && document()->frame()->selection()) {
+ m_rootEditableElementForSelectionOnMouseDown = 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.
+ m_rootEditableElementForSelectionOnMouseDown = 0;
+ m_wasShiftKeyDownOnMouseDown = false;
+ }
+ }
+ }
+
+ HTMLElement::defaultEventHandler(event);
+}
+
+void HTMLAnchorElement::setActive(bool down, bool pause)
+{
+ if (isContentEditable()) {
+ EditableLinkBehavior editableLinkBehavior = EditableLinkDefaultBehavior;
+ if (Settings* settings = document()->settings())
+ editableLinkBehavior = settings->editableLinkBehavior();
+
+ switch (editableLinkBehavior) {
+ default:
+ case EditableLinkDefaultBehavior:
+ case EditableLinkAlwaysLive:
+ break;
+
+ case EditableLinkNeverLive:
+ return;
+
+ // 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()->rootEditableElement() == rootEditableElement())
+ return;
+ break;
+
+ case EditableLinkOnlyLiveWithShiftKey:
+ return;
+ }
+
+ }
+
+ ContainerNode::setActive(down, pause);
+}
+
+void HTMLAnchorElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == hrefAttr) {
+ bool wasLink = isLink();
+ setIsLink(!attr->isNull());
+ if (wasLink != isLink())
+ setNeedsStyleRecalc();
+ if (isLink()) {
+ String parsedURL = stripLeadingAndTrailingHTMLSpaces(attr->value());
+ if (document()->isDNSPrefetchEnabled()) {
+ if (protocolIs(parsedURL, "http") || protocolIs(parsedURL, "https") || parsedURL.startsWith("//"))
+ ResourceHandle::prepareForURL(document()->completeURL(parsedURL));
+ }
+ if (document()->page() && !document()->page()->javaScriptURLsAreAllowed() && protocolIsJavaScript(parsedURL)) {
+ clearIsLink();
+ attr->setValue(nullAtom);
+ }
+ }
+ } else if (attr->name() == nameAttr ||
+ attr->name() == titleAttr) {
+ // Do nothing.
+ } else if (attr->name() == relAttr)
+ setRel(attr->value());
+ else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+void HTMLAnchorElement::accessKeyAction(bool sendToAnyElement)
+{
+ // send the mouse button events if the caller specified sendToAnyElement
+ dispatchSimulatedClick(0, sendToAnyElement);
+}
+
+bool HTMLAnchorElement::isURLAttribute(Attribute *attr) const
+{
+ return attr->name() == hrefAttr;
+}
+
+bool HTMLAnchorElement::canStartSelection() const
+{
+ // FIXME: We probably want this same behavior in SVGAElement too
+ if (!isLink())
+ return HTMLElement::canStartSelection();
+ return isContentEditable();
+}
+
+bool HTMLAnchorElement::draggable() const
+{
+ // Should be draggable if we have an href attribute.
+ const AtomicString& value = getAttribute(draggableAttr);
+ if (equalIgnoringCase(value, "true"))
+ return true;
+ if (equalIgnoringCase(value, "false"))
+ return false;
+ return hasAttribute(hrefAttr);
+}
+
+KURL HTMLAnchorElement::href() const
+{
+ return document()->completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(hrefAttr)));
+}
+
+void HTMLAnchorElement::setHref(const AtomicString& value)
+{
+ setAttribute(hrefAttr, value);
+}
+
+bool HTMLAnchorElement::hasRel(uint32_t relation) const
+{
+ return m_linkRelations & relation;
+}
+
+void HTMLAnchorElement::setRel(const String& value)
+{
+ m_linkRelations = 0;
+ SpaceSplitString newLinkRelations(value, true);
+ // FIXME: Add link relations as they are implemented
+ if (newLinkRelations.contains("noreferrer"))
+ m_linkRelations |= RelationNoReferrer;
+}
+
+const AtomicString& HTMLAnchorElement::name() const
+{
+ return getAttribute(nameAttr);
+}
+
+short HTMLAnchorElement::tabIndex() const
+{
+ // Skip the supportsFocus check in HTMLElement.
+ return Element::tabIndex();
+}
+
+String HTMLAnchorElement::target() const
+{
+ return getAttribute(targetAttr);
+}
+
+String HTMLAnchorElement::hash() const
+{
+ String fragmentIdentifier = href().fragmentIdentifier();
+ return fragmentIdentifier.isEmpty() ? "" : "#" + fragmentIdentifier;
+}
+
+void HTMLAnchorElement::setHash(const String& value)
+{
+ KURL url = href();
+ if (value[0] == '#')
+ url.setFragmentIdentifier(value.substring(1));
+ else
+ url.setFragmentIdentifier(value);
+ setHref(url.string());
+}
+
+String HTMLAnchorElement::host() const
+{
+ const KURL& 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());
+}
+
+void HTMLAnchorElement::setHost(const String& value)
+{
+ if (value.isEmpty())
+ return;
+ KURL 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());
+}
+
+String HTMLAnchorElement::hostname() const
+{
+ return href().host();
+}
+
+void HTMLAnchorElement::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;
+
+ KURL url = href();
+ if (!url.canSetHostOrPort())
+ return;
+
+ url.setHost(value.substring(i));
+ setHref(url.string());
+}
+
+String HTMLAnchorElement::pathname() const
+{
+ return href().path();
+}
+
+void HTMLAnchorElement::setPathname(const String& value)
+{
+ KURL url = href();
+ if (!url.canSetPathname())
+ return;
+
+ if (value[0] == '/')
+ url.setPath(value);
+ else
+ url.setPath("/" + value);
+
+ setHref(url.string());
+}
+
+String HTMLAnchorElement::port() const
+{
+ return String::number(href().port());
+}
+
+void HTMLAnchorElement::setPort(const String& value)
+{
+ KURL 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.
+ unsigned port = value.toUInt();
+ if (isDefaultPortForProtocol(port, url.protocol()))
+ url.removePort();
+ else
+ url.setPort(port);
+
+ setHref(url.string());
+}
+
+String HTMLAnchorElement::protocol() const
+{
+ return href().protocol() + ":";
+}
+
+void HTMLAnchorElement::setProtocol(const String& value)
+{
+ KURL url = href();
+ url.setProtocol(value);
+ setHref(url.string());
+}
+
+String HTMLAnchorElement::search() const
+{
+ String query = href().query();
+ return query.isEmpty() ? "" : "?" + query;
+}
+
+String HTMLAnchorElement::origin() const
+{
+ RefPtr<SecurityOrigin> origin = SecurityOrigin::create(href());
+ return origin->toString();
+}
+
+String HTMLAnchorElement::getParameter(const String& name) const
+{
+ ParsedURLParameters parameters;
+ href().copyParsedQueryTo(parameters);
+ return parameters.get(name);
+}
+
+void HTMLAnchorElement::setSearch(const String& value)
+{
+ KURL 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.replace('#', "%23"));
+
+ setHref(url.string());
+}
+
+String HTMLAnchorElement::text() const
+{
+ return innerText();
+}
+
+String HTMLAnchorElement::toString() const
+{
+ return href().string();
+}
+
+bool HTMLAnchorElement::isLiveLink() const
+{
+ return isLink() && treatLinkAsLiveForEventType(m_wasShiftKeyDownOnMouseDown ? MouseEventWithShiftKey : MouseEventWithoutShiftKey);
+}
+
+void HTMLAnchorElement::sendPings(const KURL& destinationURL)
+{
+ if (!hasAttribute(pingAttr) || !document()->settings()->hyperlinkAuditingEnabled())
+ return;
+
+ SpaceSplitString pingURLs(getAttribute(pingAttr), true);
+ for (unsigned i = 0; i < pingURLs.size(); i++)
+ PingLoader::sendPing(document()->frame(), document()->completeURL(pingURLs[i]), destinationURL);
+}
+
+HTMLAnchorElement::EventType HTMLAnchorElement::eventType(Event* event)
+{
+ if (!event->isMouseEvent())
+ return NonMouseEvent;
+ return static_cast<MouseEvent*>(event)->shiftKey() ? MouseEventWithShiftKey : MouseEventWithoutShiftKey;
+}
+
+bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const
+{
+ if (!isContentEditable())
+ return true;
+
+ Settings* settings = document()->settings();
+ if (!settings)
+ return true;
+
+ switch (settings->editableLinkBehavior()) {
+ case EditableLinkDefaultBehavior:
+ case EditableLinkAlwaysLive:
+ return true;
+
+ case EditableLinkNeverLive:
+ return false;
+
+ // If the selection prior to clicking on this link resided in the same editable block as this link,
+ // and the shift key isn't pressed, we don't want to follow the link.
+ case EditableLinkLiveWhenNotFocused:
+ return eventType == MouseEventWithShiftKey || (eventType == MouseEventWithoutShiftKey && m_rootEditableElementForSelectionOnMouseDown != rootEditableElement());
+
+ case EditableLinkOnlyLiveWithShiftKey:
+ return eventType == MouseEventWithShiftKey;
+ }
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+bool isEnterKeyKeydownEvent(Event* event)
+{
+ return event->type() == eventNames().keydownEvent && event->isKeyboardEvent() && static_cast<KeyboardEvent*>(event)->keyIdentifier() == "Enter";
+}
+
+bool isMiddleMouseButtonEvent(Event* event)
+{
+ return event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == MiddleButton;
+}
+
+bool isLinkClick(Event* event)
+{
+ return event->type() == eventNames().clickEvent || (event->type() == eventNames().mouseupEvent && isMiddleMouseButtonEvent(event));
+}
+
+void handleLinkClick(Event* event, Document* document, const String& url, const String& target, bool hideReferrer)
+{
+ event->setDefaultHandled();
+
+ Frame* frame = document->frame();
+ if (!frame)
+ return;
+ // FIXME: This seems wrong. Why are we manufactuing a user gesture?
+ UserGestureIndicator indicator(DefinitelyProcessingUserGesture);
+ frame->loader()->urlSelected(document->completeURL(url), target, event, false, false, hideReferrer ? NoReferrer : SendReferrer);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLAnchorElement.h b/Source/WebCore/html/HTMLAnchorElement.h
new file mode 100644
index 0000000..71837ca
--- /dev/null
+++ b/Source/WebCore/html/HTMLAnchorElement.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2000 Simon Hausmann <hausmann@kde.org>
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLAnchorElement_h
+#define HTMLAnchorElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+// Link relation bitmask values.
+// FIXME: Uncomment as the various link relations are implemented.
+enum {
+// RelationAlternate = 0x00000001,
+// RelationArchives = 0x00000002,
+// RelationAuthor = 0x00000004,
+// RelationBoomark = 0x00000008,
+// RelationExternal = 0x00000010,
+// RelationFirst = 0x00000020,
+// RelationHelp = 0x00000040,
+// RelationIndex = 0x00000080,
+// RelationLast = 0x00000100,
+// RelationLicense = 0x00000200,
+// RelationNext = 0x00000400,
+// RelationNoFolow = 0x00000800,
+ RelationNoReferrer = 0x00001000,
+// RelationPrev = 0x00002000,
+// RelationSearch = 0x00004000,
+// RelationSidebar = 0x00008000,
+// RelationTag = 0x00010000,
+// RelationUp = 0x00020000,
+};
+
+class HTMLAnchorElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLAnchorElement> create(Document*);
+ static PassRefPtr<HTMLAnchorElement> create(const QualifiedName&, Document*);
+
+ KURL href() const;
+ void setHref(const AtomicString&);
+
+ const AtomicString& name() const;
+
+ String hash() const;
+ void setHash(const String&);
+
+ String host() const;
+ void setHost(const String&);
+
+ String hostname() const;
+ void setHostname(const String&);
+
+ String pathname() const;
+ void setPathname(const String&);
+
+ String port() const;
+ void setPort(const String&);
+
+ String protocol() const;
+ void setProtocol(const String&);
+
+ String search() const;
+ void setSearch(const String&);
+
+ String origin() const;
+
+ String getParameter(const String&) const;
+
+ String text() const;
+
+ String toString() const;
+
+ bool isLiveLink() const;
+
+ bool hasRel(uint32_t relation) const;
+ void setRel(const String&);
+
+protected:
+ HTMLAnchorElement(const QualifiedName&, Document*);
+
+ virtual void parseMappedAttribute(Attribute*);
+
+private:
+ virtual bool supportsFocus() const;
+ virtual bool isMouseFocusable() const;
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const;
+ virtual void defaultEventHandler(Event*);
+ virtual void setActive(bool active = true, bool pause = false);
+ virtual void accessKeyAction(bool fullAction);
+ virtual bool isURLAttribute(Attribute*) const;
+ virtual bool canStartSelection() const;
+ virtual String target() const;
+ virtual short tabIndex() const;
+ virtual bool draggable() const;
+
+ void sendPings(const KURL& destinationURL);
+
+ enum EventType {
+ MouseEventWithoutShiftKey,
+ MouseEventWithShiftKey,
+ NonMouseEvent,
+ };
+ static EventType eventType(Event*);
+ bool treatLinkAsLiveForEventType(EventType) const;
+
+ RefPtr<Element> m_rootEditableElementForSelectionOnMouseDown;
+ bool m_wasShiftKeyDownOnMouseDown;
+ uint32_t m_linkRelations;
+};
+
+// Functions shared with the other anchor elements (SVG and WML).
+
+bool isEnterKeyKeydownEvent(Event*);
+bool isMiddleMouseButtonEvent(Event*);
+bool isLinkClick(Event*);
+void handleLinkClick(Event*, Document*, const String& url, const String& target, bool hideReferrer = false);
+
+} // namespace WebCore
+
+#endif // HTMLAnchorElement_h
diff --git a/Source/WebCore/html/HTMLAnchorElement.idl b/Source/WebCore/html/HTMLAnchorElement.idl
new file mode 100644
index 0000000..432df69
--- /dev/null
+++ b/Source/WebCore/html/HTMLAnchorElement.idl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLAnchorElement : HTMLElement {
+ attribute [Reflect] DOMString accessKey;
+ attribute [Reflect] DOMString charset;
+ attribute [Reflect] DOMString coords;
+ attribute [Reflect, URL] DOMString href;
+ attribute [Reflect] DOMString hreflang;
+ attribute [Reflect] DOMString name;
+ attribute [Reflect] DOMString rel;
+ attribute [Reflect] DOMString rev;
+ attribute [Reflect] DOMString shape;
+ attribute [Reflect] DOMString target;
+ attribute [Reflect] DOMString type;
+
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+ readonly attribute DOMString hash;
+ readonly attribute DOMString host;
+ readonly attribute DOMString hostname;
+ readonly attribute DOMString pathname;
+ readonly attribute DOMString port;
+ readonly attribute DOMString protocol;
+ readonly attribute DOMString search;
+#else
+ attribute [ConvertNullToNullString] DOMString hash;
+ attribute [ConvertNullToNullString] DOMString host;
+ attribute [ConvertNullToNullString] DOMString hostname;
+ attribute [ConvertNullToNullString] DOMString pathname;
+ attribute [ConvertNullToNullString] DOMString port;
+ attribute [ConvertNullToNullString] DOMString protocol;
+ attribute [ConvertNullToNullString] DOMString search;
+
+ readonly attribute [ConvertNullToNullString] DOMString origin;
+#endif
+
+ DOMString getParameter(in DOMString name);
+
+ readonly attribute DOMString text;
+
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ [DontEnum] DOMString toString();
+#endif
+
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+ // Objective-C extension:
+ readonly attribute URL absoluteLinkURL;
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLAppletElement.cpp b/Source/WebCore/html/HTMLAppletElement.cpp
new file mode 100644
index 0000000..c7995b5
--- /dev/null
+++ b/Source/WebCore/html/HTMLAppletElement.cpp
@@ -0,0 +1,183 @@
+/*
+ * 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, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLAppletElement.h"
+
+#include "Attribute.h"
+#include "HTMLDocument.h"
+#include "HTMLNames.h"
+#include "RenderApplet.h"
+#include "SecurityOrigin.h"
+#include "Settings.h"
+#include "Widget.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLAppletElement::HTMLAppletElement(const QualifiedName& tagName, Document* document)
+ : HTMLPlugInElement(tagName, document)
+{
+ ASSERT(hasTagName(appletTag));
+}
+
+PassRefPtr<HTMLAppletElement> HTMLAppletElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLAppletElement(tagName, document));
+}
+
+void HTMLAppletElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == altAttr ||
+ attr->name() == archiveAttr ||
+ attr->name() == codeAttr ||
+ attr->name() == codebaseAttr ||
+ attr->name() == mayscriptAttr ||
+ attr->name() == objectAttr) {
+ // Do nothing.
+ } else if (attr->name() == nameAttr) {
+ const AtomicString& newName = attr->value();
+ if (inDocument() && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->addNamedItem(newName);
+ }
+ m_name = newName;
+ } else if (isIdAttributeName(attr->name())) {
+ const AtomicString& newId = attr->value();
+ if (inDocument() && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeExtraNamedItem(m_id);
+ document->addExtraNamedItem(newId);
+ }
+ m_id = newId;
+ // also call superclass
+ HTMLPlugInElement::parseMappedAttribute(attr);
+ } else
+ HTMLPlugInElement::parseMappedAttribute(attr);
+}
+
+void HTMLAppletElement::insertedIntoDocument()
+{
+ if (document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->addNamedItem(m_name);
+ document->addExtraNamedItem(m_id);
+ }
+
+ HTMLPlugInElement::insertedIntoDocument();
+}
+
+void HTMLAppletElement::removedFromDocument()
+{
+ if (document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->removeExtraNamedItem(m_id);
+ }
+
+ HTMLPlugInElement::removedFromDocument();
+}
+
+bool HTMLAppletElement::rendererIsNeeded(RenderStyle* style)
+{
+ if (!fastHasAttribute(codeAttr))
+ return false;
+
+ return HTMLPlugInElement::rendererIsNeeded(style);
+}
+
+RenderObject* HTMLAppletElement::createRenderer(RenderArena*, RenderStyle* style)
+{
+ if (canEmbedJava()) {
+ HashMap<String, String> args;
+
+ args.set("code", getAttribute(codeAttr));
+
+ const AtomicString& codeBase = getAttribute(codebaseAttr);
+ if (!codeBase.isNull())
+ args.set("codeBase", codeBase);
+
+ const AtomicString& name = document()->isHTMLDocument() ? getAttribute(nameAttr) : getIdAttribute();
+ if (!name.isNull())
+ args.set("name", name);
+ const AtomicString& archive = getAttribute(archiveAttr);
+ if (!archive.isNull())
+ args.set("archive", archive);
+
+ args.set("baseURL", document()->baseURL().string());
+
+ const AtomicString& mayScript = getAttribute(mayscriptAttr);
+ if (!mayScript.isNull())
+ args.set("mayScript", mayScript);
+
+ // Other arguments (from <PARAM> tags) are added later.
+
+ return new (document()->renderArena()) RenderApplet(this, args);
+ }
+
+ return RenderObject::createObject(this, style);
+}
+
+void HTMLAppletElement::defaultEventHandler(Event* event)
+{
+ RenderObject* r = renderer();
+ if (!r || !r->isWidget())
+ return;
+ Widget* widget = toRenderWidget(r)->widget();
+ if (!widget)
+ return;
+ widget->handleEvent(event);
+}
+
+RenderWidget* HTMLAppletElement::renderWidgetForJSBindings() const
+{
+ if (!canEmbedJava())
+ return 0;
+
+ RenderApplet* applet = toRenderApplet(renderer());
+ if (applet)
+ applet->createWidgetIfNecessary();
+
+ return applet;
+}
+
+bool HTMLAppletElement::canEmbedJava() const
+{
+ if (document()->securityOrigin()->isSandboxed(SandboxPlugins))
+ return false;
+
+ Settings* settings = document()->settings();
+ return settings && settings->isJavaEnabled();
+}
+
+void HTMLAppletElement::finishParsingChildren()
+{
+ // The parser just reached </applet>, so all the params are available now.
+ HTMLPlugInElement::finishParsingChildren();
+ if (renderer())
+ renderer()->setNeedsLayout(true); // This will cause it to create its widget & the Java applet
+}
+
+}
diff --git a/Source/WebCore/html/HTMLAppletElement.h b/Source/WebCore/html/HTMLAppletElement.h
new file mode 100644
index 0000000..0f3aad8
--- /dev/null
+++ b/Source/WebCore/html/HTMLAppletElement.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2004, 2006, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLAppletElement_h
+#define HTMLAppletElement_h
+
+#include "HTMLPlugInElement.h"
+
+namespace WebCore {
+
+class HTMLAppletElement : public HTMLPlugInElement {
+public:
+ static PassRefPtr<HTMLAppletElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLAppletElement(const QualifiedName&, Document*);
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+ virtual void finishParsingChildren();
+
+ virtual void defaultEventHandler(Event*);
+
+ virtual RenderWidget* renderWidgetForJSBindings() const;
+
+ void setupApplet() const;
+ bool canEmbedJava() const;
+
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
+ AtomicString m_id;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/HTMLAppletElement.idl b/Source/WebCore/html/HTMLAppletElement.idl
new file mode 100644
index 0000000..388b5cb
--- /dev/null
+++ b/Source/WebCore/html/HTMLAppletElement.idl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ DelegatingPutFunction,
+ DelegatingGetOwnPropertySlot,
+ CustomCall
+ ] HTMLAppletElement : HTMLElement {
+ attribute [Reflect] DOMString align;
+ attribute [Reflect] DOMString alt;
+ attribute [Reflect] DOMString archive;
+ attribute [Reflect] DOMString code;
+ attribute [Reflect] DOMString codeBase;
+ attribute [Reflect] DOMString height;
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ attribute [Reflect] DOMString hspace;
+#else
+ attribute [Reflect] long hspace;
+#endif
+ attribute [Reflect] DOMString name;
+ attribute [Reflect] DOMString object;
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ attribute [Reflect] DOMString vspace;
+#else
+ attribute [Reflect] long vspace;
+#endif
+ attribute [Reflect] DOMString width;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLAreaElement.cpp b/Source/WebCore/html/HTMLAreaElement.cpp
new file mode 100644
index 0000000..dc87ef6
--- /dev/null
+++ b/Source/WebCore/html/HTMLAreaElement.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLAreaElement.h"
+
+#include "Attribute.h"
+#include "Frame.h"
+#include "HTMLImageElement.h"
+#include "HTMLMapElement.h"
+#include "HTMLNames.h"
+#include "HitTestResult.h"
+#include "Path.h"
+#include "RenderObject.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLAreaElement::HTMLAreaElement(const QualifiedName& tagName, Document* document)
+ : HTMLAnchorElement(tagName, document)
+ , m_coordsLen(0)
+ , m_lastSize(-1, -1)
+ , m_shape(Unknown)
+{
+ ASSERT(hasTagName(areaTag));
+}
+
+PassRefPtr<HTMLAreaElement> HTMLAreaElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLAreaElement(tagName, document));
+}
+
+void HTMLAreaElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == shapeAttr) {
+ if (equalIgnoringCase(attr->value(), "default"))
+ m_shape = Default;
+ else if (equalIgnoringCase(attr->value(), "circle"))
+ m_shape = Circle;
+ else if (equalIgnoringCase(attr->value(), "poly"))
+ m_shape = Poly;
+ else if (equalIgnoringCase(attr->value(), "rect"))
+ m_shape = Rect;
+ } else if (attr->name() == coordsAttr) {
+ m_coords.set(newCoordsArray(attr->value().string(), m_coordsLen));
+ } else if (attr->name() == altAttr || attr->name() == accesskeyAttr) {
+ // Do nothing.
+ } else
+ HTMLAnchorElement::parseMappedAttribute(attr);
+}
+
+bool HTMLAreaElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestResult& result)
+{
+ if (m_lastSize != size) {
+ m_region = adoptPtr(new Path(getRegion(size)));
+ m_lastSize = size;
+ }
+
+ if (!m_region->contains(IntPoint(x, y)))
+ return false;
+
+ result.setInnerNode(this);
+ result.setURLElement(this);
+ return true;
+}
+
+Path HTMLAreaElement::getPath(RenderObject* obj) const
+{
+ if (!obj)
+ return Path();
+
+ // FIXME: This doesn't work correctly with transforms.
+ FloatPoint absPos = obj->localToAbsolute();
+
+ // Default should default to the size of the containing object.
+ IntSize size = m_lastSize;
+ if (m_shape == Default)
+ size = obj->absoluteOutlineBounds().size();
+
+ Path p = getRegion(size);
+ float zoomFactor = document()->frame()->pageZoomFactor();
+ if (zoomFactor != 1.0f) {
+ AffineTransform zoomTransform;
+ zoomTransform.scale(zoomFactor);
+ p.transform(zoomTransform);
+ }
+
+ p.translate(absPos - FloatPoint());
+ return p;
+}
+
+IntRect HTMLAreaElement::getRect(RenderObject* obj) const
+{
+ return enclosingIntRect(getPath(obj).boundingRect());
+}
+
+Path HTMLAreaElement::getRegion(const IntSize& size) const
+{
+ if (!m_coords && m_shape != Default)
+ return Path();
+
+ int width = size.width();
+ int height = size.height();
+
+ // If element omits the shape attribute, select shape based on number of coordinates.
+ Shape shape = m_shape;
+ if (shape == Unknown) {
+ if (m_coordsLen == 3)
+ shape = Circle;
+ else if (m_coordsLen == 4)
+ shape = Rect;
+ else if (m_coordsLen >= 6)
+ shape = Poly;
+ }
+
+ Path path;
+ switch (shape) {
+ case Poly:
+ if (m_coordsLen >= 6) {
+ int numPoints = m_coordsLen / 2;
+ path.moveTo(FloatPoint(m_coords[0].calcMinValue(width), m_coords[1].calcMinValue(height)));
+ for (int i = 1; i < numPoints; ++i)
+ path.addLineTo(FloatPoint(m_coords[i * 2].calcMinValue(width), m_coords[i * 2 + 1].calcMinValue(height)));
+ path.closeSubpath();
+ }
+ break;
+ case Circle:
+ if (m_coordsLen >= 3) {
+ Length radius = m_coords[2];
+ int r = min(radius.calcMinValue(width), radius.calcMinValue(height));
+ path.addEllipse(FloatRect(m_coords[0].calcMinValue(width) - r, m_coords[1].calcMinValue(height) - r, 2 * r, 2 * r));
+ }
+ break;
+ case Rect:
+ if (m_coordsLen >= 4) {
+ int x0 = m_coords[0].calcMinValue(width);
+ int y0 = m_coords[1].calcMinValue(height);
+ int x1 = m_coords[2].calcMinValue(width);
+ int y1 = m_coords[3].calcMinValue(height);
+ path.addRect(FloatRect(x0, y0, x1 - x0, y1 - y0));
+ }
+ break;
+ case Default:
+ path.addRect(FloatRect(0, 0, width, height));
+ break;
+ case Unknown:
+ break;
+ }
+
+ return path;
+}
+
+HTMLImageElement* HTMLAreaElement::imageElement() const
+{
+ Node* mapElement = parentNode();
+ if (!mapElement->hasTagName(mapTag))
+ return 0;
+
+ return static_cast<HTMLMapElement*>(mapElement)->imageElement();
+}
+
+bool HTMLAreaElement::isKeyboardFocusable(KeyboardEvent*) const
+{
+ return isFocusable();
+}
+
+bool HTMLAreaElement::isMouseFocusable() const
+{
+ return isFocusable();
+}
+
+bool HTMLAreaElement::isFocusable() const
+{
+ return supportsFocus() && Element::tabIndex() >= 0;
+}
+
+void HTMLAreaElement::dispatchBlurEvent()
+{
+ HTMLAnchorElement::dispatchBlurEvent();
+
+ // On a blur, we might need to remove our focus rings by repainting.
+ updateFocusAppearance(false);
+}
+
+void HTMLAreaElement::updateFocusAppearance(bool restorePreviousSelection)
+{
+ if (!isFocusable())
+ return;
+
+ ContainerNode* parent = parentNode();
+ if (!parent || !parent->hasTagName(mapTag))
+ return;
+
+ HTMLImageElement* imageElement = static_cast<HTMLMapElement*>(parent)->imageElement();
+ if (!imageElement)
+ return;
+
+ // This will handle scrolling to the image if necessary.
+ imageElement->updateFocusAppearance(restorePreviousSelection);
+
+ RenderObject* imageRenderer = imageElement->renderer();
+ if (imageRenderer)
+ imageRenderer->setNeedsLayout(true);
+}
+
+bool HTMLAreaElement::supportsFocus() const
+{
+ // If the AREA element was a link, it should support focus.
+ // The inherited method is not used because it assumes that a render object must exist
+ // for the element to support focus. AREA elements do not have render objects.
+ return isLink();
+}
+
+String HTMLAreaElement::target() const
+{
+ return getAttribute(targetAttr);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLAreaElement.h b/Source/WebCore/html/HTMLAreaElement.h
new file mode 100644
index 0000000..42d4198
--- /dev/null
+++ b/Source/WebCore/html/HTMLAreaElement.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2004, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLAreaElement_h
+#define HTMLAreaElement_h
+
+#include "HTMLAnchorElement.h"
+#include "IntSize.h"
+#include <wtf/OwnArrayPtr.h>
+
+namespace WebCore {
+
+class HitTestResult;
+class HTMLImageElement;
+class Path;
+
+class HTMLAreaElement : public HTMLAnchorElement {
+public:
+ static PassRefPtr<HTMLAreaElement> create(const QualifiedName&, Document*);
+
+ bool isDefault() const { return m_shape == Default; }
+
+ bool mapMouseEvent(int x, int y, const IntSize&, HitTestResult&);
+
+ IntRect getRect(RenderObject*) const;
+ Path getPath(RenderObject*) const;
+
+ // The parent map's image.
+ HTMLImageElement* imageElement() const;
+
+private:
+ HTMLAreaElement(const QualifiedName&, Document*);
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual bool supportsFocus() const;
+ virtual String target() const;
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const;
+ virtual bool isMouseFocusable() const;
+ virtual bool isFocusable() const;
+ virtual void updateFocusAppearance(bool /*restorePreviousSelection*/);
+ virtual void dispatchBlurEvent();
+
+ enum Shape { Default, Poly, Rect, Circle, Unknown };
+ Path getRegion(const IntSize&) const;
+
+ OwnPtr<Path> m_region;
+ OwnArrayPtr<Length> m_coords;
+ int m_coordsLen;
+ IntSize m_lastSize;
+ Shape m_shape;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLAreaElement.idl b/Source/WebCore/html/HTMLAreaElement.idl
new file mode 100644
index 0000000..a77e615
--- /dev/null
+++ b/Source/WebCore/html/HTMLAreaElement.idl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLAreaElement : HTMLElement {
+ attribute [Reflect] DOMString accessKey;
+ attribute [Reflect] DOMString alt;
+ attribute [Reflect] DOMString coords;
+ attribute [Reflect, URL] DOMString href;
+ attribute [Reflect] boolean noHref;
+ attribute [Reflect] DOMString shape;
+ attribute [Reflect] DOMString target;
+
+ // IE Extensions
+ readonly attribute DOMString hash;
+ readonly attribute DOMString host;
+ readonly attribute DOMString hostname;
+ readonly attribute DOMString pathname;
+ readonly attribute DOMString port;
+ readonly attribute DOMString protocol;
+ readonly attribute DOMString search;
+
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+ // Objective-C extension:
+ readonly attribute URL absoluteLinkURL;
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in
new file mode 100644
index 0000000..513e44f
--- /dev/null
+++ b/Source/WebCore/html/HTMLAttributeNames.in
@@ -0,0 +1,298 @@
+namespace="HTML"
+namespacePrefix="xhtml"
+namespaceURI="http://www.w3.org/1999/xhtml"
+attrsNullNamespace
+
+abbr
+accept_charset
+accept
+accesskey
+action
+align
+alink
+alt
+archive
+aria-activedescendant
+aria-atomic
+aria-busy
+aria-checked
+aria-controls
+aria-describedby
+aria-disabled
+aria-dropeffect
+aria-expanded
+aria-flowto
+aria-grabbed
+aria-haspopup
+aria-help
+aria-hidden
+aria-invalid
+aria-label
+aria-labeledby
+aria-labelledby
+aria-level
+aria-live
+aria-multiline
+aria-multiselectable
+aria-orientation
+aria-owns
+aria-pressed
+aria-readonly
+aria-relevant
+aria-required
+aria-selected
+aria-valuemax
+aria-valuemin
+aria-valuenow
+aria-valuetext
+async
+autocomplete
+autofocus
+autoplay
+autosave
+axis
+background
+behavior
+bgcolor
+bgproperties
+border
+bordercolor
+cellpadding
+cellspacing
+char
+challenge
+charoff
+charset
+checked
+cellborder
+cite
+class
+classid
+clear
+code
+codebase
+codetype
+color
+cols
+colspan
+compact
+composite
+content
+contenteditable
+controls
+coords
+data
+datetime
+declare
+defer
+dir
+direction
+disabled
+draggable
+enctype
+end
+event
+expanded
+face
+focused
+for
+form
+formaction
+formenctype
+formmethod
+formnovalidate
+formtarget
+frame
+frameborder
+headers
+height
+hidden
+high
+href
+hreflang
+hspace
+http_equiv
+id
+incremental
+indeterminate
+ismap
+keytype
+label
+lang
+language
+leftmargin
+link
+list
+longdesc
+loop
+low
+playcount
+loopend
+loopstart
+lowsrc
+manifest
+marginheight
+marginwidth
+max
+maxlength
+mayscript
+media
+method
+min
+multiple
+name
+nohref
+noresize
+noshade
+novalidate
+nowrap
+object
+onabort
+onbeforecopy
+onbeforecut
+onbeforeload
+onbeforepaste
+onbeforeprocess
+onbeforeunload
+onblur
+oncanplay
+oncanplaythrough
+onchange
+onclick
+oncontextmenu
+oncopy
+oncut
+ondblclick
+ondrag
+ondragend
+ondragenter
+ondragleave
+ondragover
+ondragstart
+ondrop
+ondurationchange
+onemptied
+onended
+onerror
+onfocus
+onfocusin
+onfocusout
+onhashchange
+oninput
+oninvalid
+onkeydown
+onkeypress
+onkeyup
+onload
+onloadeddata
+onloadedmetadata
+onloadstart
+onmousedown
+onmousemove
+onmouseout
+onmouseover
+onmouseup
+onmousewheel
+ononline
+onoffline
+onorientationchange
+onpagehide
+onpageshow
+onpaste
+onpause
+onplay
+onplaying
+onpopstate
+onprogress
+onratechange
+onreset
+onresize
+onscroll
+onsearch
+onseeked
+onseeking
+onselect
+onselectstart
+onwebkitspeechchange
+onstalled
+onstorage
+onsuspend
+onsubmit
+ontimeupdate
+ontouchstart
+ontouchmove
+ontouchend
+ontouchcancel
+onunload
+onvolumechange
+onwaiting
+onwebkitanimationstart
+onwebkitanimationiteration
+onwebkitanimationend
+onwebkitbeginfullscreen
+onwebkitendfullscreen
+onwebkitfullscreenchange
+onwebkittransitionend
+open
+optimum
+pattern
+placeholder
+pluginurl
+ping
+poster
+precision
+preload
+primary
+profile
+progress
+prompt
+readonly
+rel
+required
+results
+rev
+role
+rows
+rowspan
+rules
+sandbox
+scheme
+scope
+scrollamount
+scrolldelay
+scrolling
+selected
+shape
+size
+sortable
+sortdirection
+span
+x-webkit-speech
+x-webkit-grammar
+spellcheck
+src
+standby
+start
+step
+style
+summary
+tabindex
+tableborder
+target
+text
+title
+top
+topmargin
+truespeed
+type
+usemap
+valign
+value
+valuetype
+version
+viewsource
+vlink
+vspace
+webkitdirectory
+width
+wrap
diff --git a/Source/WebCore/html/HTMLAudioElement.cpp b/Source/WebCore/html/HTMLAudioElement.cpp
new file mode 100644
index 0000000..d94e146
--- /dev/null
+++ b/Source/WebCore/html/HTMLAudioElement.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 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,
+ * 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 "HTMLAudioElement.h"
+
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLAudioElement::HTMLAudioElement(const QualifiedName& tagName, Document* document)
+ : HTMLMediaElement(tagName, document)
+{
+ ASSERT(hasTagName(audioTag));
+}
+
+PassRefPtr<HTMLAudioElement> HTMLAudioElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLAudioElement(tagName, document));
+}
+
+PassRefPtr<HTMLAudioElement> HTMLAudioElement::createForJSConstructor(Document* document, const String& src)
+{
+ RefPtr<HTMLAudioElement> audio = adoptRef(new HTMLAudioElement(audioTag, document));
+ audio->setPreload("auto");
+ if (!src.isNull()) {
+ audio->setSrc(src);
+ audio->scheduleLoad();
+ }
+ return audio.release();
+}
+
+}
+#endif
diff --git a/Source/WebCore/html/HTMLAudioElement.h b/Source/WebCore/html/HTMLAudioElement.h
new file mode 100644
index 0000000..54d952c
--- /dev/null
+++ b/Source/WebCore/html/HTMLAudioElement.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007, 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
+ * 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 HTMLAudioElement_h
+#define HTMLAudioElement_h
+
+#if ENABLE(VIDEO)
+
+#include "HTMLMediaElement.h"
+
+namespace WebCore {
+
+class Document;
+
+class HTMLAudioElement : public HTMLMediaElement {
+public:
+ static PassRefPtr<HTMLAudioElement> create(const QualifiedName&, Document*);
+ static PassRefPtr<HTMLAudioElement> createForJSConstructor(Document*, const String& src);
+
+private:
+ HTMLAudioElement(const QualifiedName&, Document*);
+
+ virtual bool isVideo() const { return false; }
+};
+
+} //namespace
+
+#endif
+#endif
diff --git a/Source/WebCore/html/HTMLAudioElement.idl b/Source/WebCore/html/HTMLAudioElement.idl
new file mode 100644
index 0000000..107b8b1
--- /dev/null
+++ b/Source/WebCore/html/HTMLAudioElement.idl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+module html {
+ interface [Conditional=VIDEO] HTMLAudioElement : HTMLMediaElement {
+
+ };
+}
diff --git a/Source/WebCore/html/HTMLBRElement.cpp b/Source/WebCore/html/HTMLBRElement.cpp
new file mode 100644
index 0000000..e8f4520
--- /dev/null
+++ b/Source/WebCore/html/HTMLBRElement.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLBRElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "HTMLNames.h"
+#include "RenderBR.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLBRElement::HTMLBRElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(brTag));
+}
+
+PassRefPtr<HTMLBRElement> HTMLBRElement::create(Document* document)
+{
+ return adoptRef(new HTMLBRElement(brTag, document));
+}
+
+PassRefPtr<HTMLBRElement> HTMLBRElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLBRElement(tagName, document));
+}
+
+bool HTMLBRElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == clearAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLBRElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == clearAttr) {
+ // If the string is empty, then don't add the clear property.
+ // <br clear> and <br clear=""> are just treated like <br> by Gecko, Mac IE, etc. -dwh
+ const AtomicString& str = attr->value();
+ if (!str.isEmpty()) {
+ if (equalIgnoringCase(str, "all"))
+ addCSSProperty(attr, CSSPropertyClear, "both");
+ else
+ addCSSProperty(attr, CSSPropertyClear, str);
+ }
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+RenderObject* HTMLBRElement::createRenderer(RenderArena* arena, RenderStyle* style)
+{
+ if (style->contentData())
+ return RenderObject::createObject(this, style);
+
+ return new (arena) RenderBR(this);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLBRElement.h b/Source/WebCore/html/HTMLBRElement.h
new file mode 100644
index 0000000..05df8f6
--- /dev/null
+++ b/Source/WebCore/html/HTMLBRElement.h
@@ -0,0 +1,47 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLBRElement_h
+#define HTMLBRElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLBRElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLBRElement> create(Document*);
+ static PassRefPtr<HTMLBRElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLBRElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLBRElement.idl b/Source/WebCore/html/HTMLBRElement.idl
new file mode 100644
index 0000000..a6d215d
--- /dev/null
+++ b/Source/WebCore/html/HTMLBRElement.idl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2006, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLBRElement : HTMLElement {
+ attribute [Reflect] DOMString clear;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLBaseElement.cpp b/Source/WebCore/html/HTMLBaseElement.cpp
new file mode 100644
index 0000000..0dd16fa
--- /dev/null
+++ b/Source/WebCore/html/HTMLBaseElement.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLBaseElement.h"
+
+#include "Attribute.h"
+#include "Document.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLBaseElement::HTMLBaseElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(baseTag));
+}
+
+PassRefPtr<HTMLBaseElement> HTMLBaseElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLBaseElement(tagName, document));
+}
+
+void HTMLBaseElement::parseMappedAttribute(Attribute* attribute)
+{
+ if (attribute->name() == hrefAttr || attribute->name() == targetAttr)
+ document()->processBaseElement();
+ else
+ HTMLElement::parseMappedAttribute(attribute);
+}
+
+void HTMLBaseElement::insertedIntoDocument()
+{
+ HTMLElement::insertedIntoDocument();
+ document()->processBaseElement();
+}
+
+void HTMLBaseElement::removedFromDocument()
+{
+ HTMLElement::removedFromDocument();
+ document()->processBaseElement();
+}
+
+bool HTMLBaseElement::isURLAttribute(Attribute* attribute) const
+{
+ return attribute->name() == hrefAttr;
+}
+
+String HTMLBaseElement::target() const
+{
+ return fastGetAttribute(targetAttr);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLBaseElement.h b/Source/WebCore/html/HTMLBaseElement.h
new file mode 100644
index 0000000..fd3cef6
--- /dev/null
+++ b/Source/WebCore/html/HTMLBaseElement.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLBaseElement_h
+#define HTMLBaseElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLBaseElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLBaseElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLBaseElement(const QualifiedName&, Document*);
+
+ virtual String target() const;
+ virtual bool isURLAttribute(Attribute*) const;
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLBaseElement.idl b/Source/WebCore/html/HTMLBaseElement.idl
new file mode 100644
index 0000000..2750c9e
--- /dev/null
+++ b/Source/WebCore/html/HTMLBaseElement.idl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLBaseElement : HTMLElement {
+ attribute [Reflect, URL] DOMString href;
+ attribute [Reflect] DOMString target;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLBaseFontElement.cpp b/Source/WebCore/html/HTMLBaseFontElement.cpp
new file mode 100644
index 0000000..2ab681e
--- /dev/null
+++ b/Source/WebCore/html/HTMLBaseFontElement.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLBaseFontElement.h"
+
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLBaseFontElement::HTMLBaseFontElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(basefontTag));
+}
+
+PassRefPtr<HTMLBaseFontElement> HTMLBaseFontElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLBaseFontElement(tagName, document));
+}
+
+}
diff --git a/Source/WebCore/html/HTMLBaseFontElement.h b/Source/WebCore/html/HTMLBaseFontElement.h
new file mode 100644
index 0000000..7573045
--- /dev/null
+++ b/Source/WebCore/html/HTMLBaseFontElement.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLBaseFontElement_h
+#define HTMLBaseFontElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLBaseFontElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLBaseFontElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLBaseFontElement(const QualifiedName&, Document*);
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLBaseFontElement.idl b/Source/WebCore/html/HTMLBaseFontElement.idl
new file mode 100644
index 0000000..95bc92c
--- /dev/null
+++ b/Source/WebCore/html/HTMLBaseFontElement.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLBaseFontElement : HTMLElement {
+ attribute [Reflect] DOMString color;
+ attribute [Reflect] DOMString face;
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+ attribute [Reflect] DOMString size; // this changed to a long, but our existing API is a string
+#else
+ attribute [Reflect] long size;
+#endif
+ };
+}
diff --git a/Source/WebCore/html/HTMLBlockquoteElement.cpp b/Source/WebCore/html/HTMLBlockquoteElement.cpp
new file mode 100644
index 0000000..726bc0f
--- /dev/null
+++ b/Source/WebCore/html/HTMLBlockquoteElement.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLBlockquoteElement.h"
+
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLBlockquoteElement::HTMLBlockquoteElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(blockquoteTag));
+}
+
+PassRefPtr<HTMLBlockquoteElement> HTMLBlockquoteElement::create(Document* document)
+{
+ return adoptRef(new HTMLBlockquoteElement(blockquoteTag, document));
+}
+
+PassRefPtr<HTMLBlockquoteElement> HTMLBlockquoteElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLBlockquoteElement(tagName, document));
+}
+
+bool HTMLBlockquoteElement::isURLAttribute(Attribute* attribute) const
+{
+ return attribute->name() == citeAttr;
+}
+
+}
diff --git a/Source/WebCore/html/HTMLBlockquoteElement.h b/Source/WebCore/html/HTMLBlockquoteElement.h
new file mode 100644
index 0000000..6566117
--- /dev/null
+++ b/Source/WebCore/html/HTMLBlockquoteElement.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLBlockquoteElement_h
+#define HTMLBlockquoteElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLBlockquoteElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLBlockquoteElement> create(Document*);
+ static PassRefPtr<HTMLBlockquoteElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLBlockquoteElement(const QualifiedName&, Document*);
+
+ virtual bool isURLAttribute(Attribute*) const;
+};
+
+} // namespace WebCore
+
+#endif // HTMLBlockquoteElement_h
diff --git a/Source/WebCore/html/HTMLBlockquoteElement.idl b/Source/WebCore/html/HTMLBlockquoteElement.idl
new file mode 100644
index 0000000..5a319a3
--- /dev/null
+++ b/Source/WebCore/html/HTMLBlockquoteElement.idl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLBlockquoteElement : HTMLElement {
+ attribute [Reflect, URL] DOMString cite;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLBodyElement.cpp b/Source/WebCore/html/HTMLBodyElement.cpp
new file mode 100644
index 0000000..84f81c3
--- /dev/null
+++ b/Source/WebCore/html/HTMLBodyElement.cpp
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLBodyElement.h"
+
+#include "Attribute.h"
+#include "CSSStyleSelector.h"
+#include "CSSStyleSheet.h"
+#include "CSSValueKeywords.h"
+#include "EventNames.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "HTMLFrameElementBase.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "ScriptEventListener.h"
+
+#ifdef ANDROID_META_SUPPORT
+#include "PlatformBridge.h"
+#include "Settings.h"
+#endif
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLBodyElement::HTMLBodyElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(bodyTag));
+}
+
+PassRefPtr<HTMLBodyElement> HTMLBodyElement::create(Document* document)
+{
+ return adoptRef(new HTMLBodyElement(bodyTag, document));
+}
+
+PassRefPtr<HTMLBodyElement> HTMLBodyElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLBodyElement(tagName, document));
+}
+
+HTMLBodyElement::~HTMLBodyElement()
+{
+ if (m_linkDecl) {
+ m_linkDecl->setNode(0);
+ m_linkDecl->setParent(0);
+ }
+}
+
+void HTMLBodyElement::createLinkDecl()
+{
+ m_linkDecl = CSSMutableStyleDeclaration::create();
+ m_linkDecl->setParent(document()->elementSheet());
+ m_linkDecl->setNode(this);
+ m_linkDecl->setStrictParsing(!document()->inQuirksMode());
+}
+
+bool HTMLBodyElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == backgroundAttr) {
+ result = (MappedAttributeEntry)(eLastEntry + document()->docID());
+ return false;
+ }
+
+ if (attrName == bgcolorAttr ||
+ attrName == textAttr ||
+ attrName == marginwidthAttr ||
+ attrName == leftmarginAttr ||
+ attrName == marginheightAttr ||
+ attrName == topmarginAttr ||
+ attrName == bgpropertiesAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLBodyElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == backgroundAttr) {
+ String url = stripLeadingAndTrailingHTMLSpaces(attr->value());
+ if (!url.isEmpty())
+ addCSSImageProperty(attr, CSSPropertyBackgroundImage, document()->completeURL(url).string());
+ } else if (attr->name() == marginwidthAttr || attr->name() == leftmarginAttr) {
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
+ } else if (attr->name() == marginheightAttr || attr->name() == topmarginAttr) {
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
+ } else if (attr->name() == bgcolorAttr) {
+ addCSSColor(attr, CSSPropertyBackgroundColor, attr->value());
+ } else if (attr->name() == textAttr) {
+ addCSSColor(attr, CSSPropertyColor, attr->value());
+ } else if (attr->name() == bgpropertiesAttr) {
+ if (equalIgnoringCase(attr->value(), "fixed"))
+ addCSSProperty(attr, CSSPropertyBackgroundAttachment, CSSValueFixed);
+ } else if (attr->name() == vlinkAttr ||
+ attr->name() == alinkAttr ||
+ attr->name() == linkAttr) {
+ if (attr->isNull()) {
+ if (attr->name() == linkAttr)
+ document()->resetLinkColor();
+ else if (attr->name() == vlinkAttr)
+ document()->resetVisitedLinkColor();
+ else
+ document()->resetActiveLinkColor();
+ } else {
+ if (!m_linkDecl)
+ createLinkDecl();
+ m_linkDecl->setProperty(CSSPropertyColor, attr->value(), false, false);
+ RefPtr<CSSValue> val = m_linkDecl->getPropertyCSSValue(CSSPropertyColor);
+ if (val && val->isPrimitiveValue()) {
+ Color col = document()->styleSelector()->getColorFromPrimitiveValue(static_cast<CSSPrimitiveValue*>(val.get()));
+ if (attr->name() == linkAttr)
+ document()->setLinkColor(col);
+ else if (attr->name() == vlinkAttr)
+ document()->setVisitedLinkColor(col);
+ else
+ document()->setActiveLinkColor(col);
+ }
+ }
+
+ if (attached())
+ document()->recalcStyle(Force);
+ } else if (attr->name() == onloadAttr)
+ document()->setWindowAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onbeforeunloadAttr)
+ document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onunloadAttr)
+ document()->setWindowAttributeEventListener(eventNames().unloadEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onpagehideAttr)
+ document()->setWindowAttributeEventListener(eventNames().pagehideEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onpageshowAttr)
+ document()->setWindowAttributeEventListener(eventNames().pageshowEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onpopstateAttr)
+ document()->setWindowAttributeEventListener(eventNames().popstateEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onblurAttr)
+ document()->setWindowAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onfocusAttr)
+ document()->setWindowAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(document()->frame(), attr));
+#if ENABLE(ORIENTATION_EVENTS)
+ else if (attr->name() == onorientationchangeAttr)
+ document()->setWindowAttributeEventListener(eventNames().orientationchangeEvent, createAttributeEventListener(document()->frame(), attr));
+#endif
+ else if (attr->name() == onhashchangeAttr)
+ document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onresizeAttr)
+ document()->setWindowAttributeEventListener(eventNames().resizeEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onscrollAttr)
+ document()->setWindowAttributeEventListener(eventNames().scrollEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onstorageAttr)
+ document()->setWindowAttributeEventListener(eventNames().storageEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == ononlineAttr)
+ document()->setWindowAttributeEventListener(eventNames().onlineEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onofflineAttr)
+ document()->setWindowAttributeEventListener(eventNames().offlineEvent, createAttributeEventListener(document()->frame(), attr));
+ else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+void HTMLBodyElement::insertedIntoDocument()
+{
+ HTMLElement::insertedIntoDocument();
+
+ // FIXME: Perhaps this code should be in attach() instead of here.
+ Element* ownerElement = document()->ownerElement();
+ if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) {
+ HTMLFrameElementBase* ownerFrameElement = static_cast<HTMLFrameElementBase*>(ownerElement);
+ int marginWidth = ownerFrameElement->marginWidth();
+ if (marginWidth != -1)
+ setAttribute(marginwidthAttr, String::number(marginWidth));
+ int marginHeight = ownerFrameElement->marginHeight();
+ if (marginHeight != -1)
+ setAttribute(marginheightAttr, String::number(marginHeight));
+ }
+
+#ifdef ANDROID_META_SUPPORT
+ Settings * settings = document()->settings();
+ if (settings) {
+ String host = document()->baseURI().host().lower();
+ if (settings->viewportWidth() == -1 && (host.startsWith("m.") || host.startsWith("mobile.")
+ || host.startsWith("wap.") || host.contains(".m.") || host.contains(".mobile." || host.contains(".wap.")))) {
+ // fit mobile sites directly in the screen
+ settings->setMetadataSettings("width", "device-width");
+ // update the meta data if it is the top document
+ if (!ownerElement) {
+ FrameView* view = document()->view();
+ if (view)
+ PlatformBridge::updateViewport(view);
+ }
+ }
+ }
+#endif
+
+ // FIXME: This call to scheduleRelayout should not be needed here.
+ // But without it we hang during WebKit tests; need to fix that and remove this.
+ if (FrameView* view = document()->view())
+ view->scheduleRelayout();
+
+ if (document() && document()->page())
+ document()->page()->updateViewportArguments();
+}
+
+bool HTMLBodyElement::isURLAttribute(Attribute *attr) const
+{
+ return attr->name() == backgroundAttr;
+}
+
+bool HTMLBodyElement::supportsFocus() const
+{
+ return isContentEditable() || HTMLElement::supportsFocus();
+}
+
+String HTMLBodyElement::aLink() const
+{
+ return getAttribute(alinkAttr);
+}
+
+void HTMLBodyElement::setALink(const String& value)
+{
+ setAttribute(alinkAttr, value);
+}
+
+String HTMLBodyElement::bgColor() const
+{
+ return getAttribute(bgcolorAttr);
+}
+
+void HTMLBodyElement::setBgColor(const String& value)
+{
+ setAttribute(bgcolorAttr, value);
+}
+
+String HTMLBodyElement::link() const
+{
+ return getAttribute(linkAttr);
+}
+
+void HTMLBodyElement::setLink(const String& value)
+{
+ setAttribute(linkAttr, value);
+}
+
+String HTMLBodyElement::text() const
+{
+ return getAttribute(textAttr);
+}
+
+void HTMLBodyElement::setText(const String& value)
+{
+ setAttribute(textAttr, value);
+}
+
+String HTMLBodyElement::vLink() const
+{
+ return getAttribute(vlinkAttr);
+}
+
+void HTMLBodyElement::setVLink(const String& value)
+{
+ setAttribute(vlinkAttr, value);
+}
+
+static int adjustForZoom(int value, Document* document)
+{
+ float zoomFactor = document->frame()->pageZoomFactor();
+ if (zoomFactor == 1)
+ return value;
+ // Needed because of truncation (rather than rounding) when scaling up.
+ if (zoomFactor > 1)
+ value++;
+ return static_cast<int>(value / zoomFactor);
+}
+
+int HTMLBodyElement::scrollLeft() const
+{
+ // Update the document's layout.
+ Document* document = this->document();
+ document->updateLayoutIgnorePendingStylesheets();
+ FrameView* view = document->view();
+ return view ? adjustForZoom(view->scrollX(), document) : 0;
+}
+
+void HTMLBodyElement::setScrollLeft(int scrollLeft)
+{
+ Document* document = this->document();
+ 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()), view->scrollY()));
+}
+
+int HTMLBodyElement::scrollTop() const
+{
+ // Update the document's layout.
+ Document* document = this->document();
+ document->updateLayoutIgnorePendingStylesheets();
+ FrameView* view = document->view();
+ return view ? adjustForZoom(view->scrollY(), document) : 0;
+}
+
+void HTMLBodyElement::setScrollTop(int scrollTop)
+{
+ Document* document = this->document();
+ 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())));
+}
+
+int HTMLBodyElement::scrollHeight() const
+{
+ // Update the document's layout.
+ Document* document = this->document();
+ document->updateLayoutIgnorePendingStylesheets();
+ FrameView* view = document->view();
+ return view ? adjustForZoom(view->contentsHeight(), document) : 0;
+}
+
+int HTMLBodyElement::scrollWidth() const
+{
+ // Update the document's layout.
+ Document* document = this->document();
+ document->updateLayoutIgnorePendingStylesheets();
+ FrameView* view = document->view();
+ return view ? adjustForZoom(view->contentsWidth(), document) : 0;
+}
+
+void HTMLBodyElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+{
+ HTMLElement::addSubresourceAttributeURLs(urls);
+
+ addSubresourceURL(urls, document()->completeURL(getAttribute(backgroundAttr)));
+}
+
+void HTMLBodyElement::didMoveToNewOwnerDocument()
+{
+ // When moving body elements between documents, we should have to reset the parent sheet for any
+ // link style declarations. If we don't we might crash later.
+ // In practice I can't reproduce this theoretical problem.
+ // webarchive/adopt-attribute-styled-body-webarchive.html tries to make sure this crash won't surface.
+ if (m_linkDecl)
+ m_linkDecl->setParent(document()->elementSheet());
+
+ HTMLElement::didMoveToNewOwnerDocument();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLBodyElement.h b/Source/WebCore/html/HTMLBodyElement.h
new file mode 100644
index 0000000..cd8a38f
--- /dev/null
+++ b/Source/WebCore/html/HTMLBodyElement.h
@@ -0,0 +1,102 @@
+/*
+ * 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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLBodyElement_h
+#define HTMLBodyElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class Document;
+
+class HTMLBodyElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLBodyElement> create(Document*);
+ static PassRefPtr<HTMLBodyElement> create(const QualifiedName&, Document*);
+ virtual ~HTMLBodyElement();
+
+ String aLink() const;
+ void setALink(const String&);
+ String bgColor() const;
+ void setBgColor(const String&);
+ String link() const;
+ void setLink(const String&);
+ String text() const;
+ void setText(const String&);
+ String vLink() const;
+ void setVLink(const String&);
+
+ // 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*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void insertedIntoDocument();
+
+ void createLinkDecl();
+
+ virtual bool isURLAttribute(Attribute*) const;
+
+ virtual bool supportsFocus() const;
+
+ virtual int scrollLeft() const;
+ virtual void setScrollLeft(int scrollLeft);
+
+ virtual int scrollTop() const;
+ virtual void setScrollTop(int scrollTop);
+
+ virtual int scrollHeight() const;
+ virtual int scrollWidth() const;
+
+ virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+
+ virtual void didMoveToNewOwnerDocument();
+
+ RefPtr<CSSMutableStyleDeclaration> m_linkDecl;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLBodyElement.idl b/Source/WebCore/html/HTMLBodyElement.idl
new file mode 100644
index 0000000..4709e3f
--- /dev/null
+++ b/Source/WebCore/html/HTMLBodyElement.idl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2006, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLBodyElement : HTMLElement {
+ attribute [Reflect] DOMString aLink;
+ attribute [Reflect] DOMString background;
+ attribute [Reflect] DOMString bgColor;
+ attribute [Reflect] DOMString link;
+ attribute [Reflect] DOMString text;
+ attribute [Reflect] DOMString vLink;
+
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
+ // Event handler attributes
+ attribute [DontEnum, WindowEventListener] EventListener onbeforeunload;
+ attribute [DontEnum, WindowEventListener] EventListener onhashchange;
+ attribute [DontEnum, WindowEventListener] EventListener onmessage;
+ attribute [DontEnum, WindowEventListener] EventListener onoffline;
+ attribute [DontEnum, WindowEventListener] EventListener ononline;
+ attribute [DontEnum, WindowEventListener] EventListener onpopstate;
+ attribute [DontEnum, WindowEventListener] EventListener onresize;
+ attribute [DontEnum, WindowEventListener] EventListener onstorage;
+ attribute [DontEnum, WindowEventListener] EventListener onunload;
+
+#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS
+ attribute [DontEnum, WindowEventListener] EventListener onorientationchange;
+#endif
+
+ // Overrides of Element attributes (with different implementation in bindings).
+ attribute [DontEnum, WindowEventListener] EventListener onblur;
+ attribute [DontEnum, WindowEventListener] EventListener onerror;
+ attribute [DontEnum, WindowEventListener] EventListener onfocus;
+ attribute [DontEnum, WindowEventListener] EventListener onload;
+
+ // Not implemented yet.
+ // attribute [DontEnum, WindowEventListener] EventListener onafterprint;
+ // attribute [DontEnum, WindowEventListener] EventListener onbeforeprint;
+ // attribute [DontEnum, WindowEventListener] EventListener onredo;
+ // attribute [DontEnum, WindowEventListener] EventListener onundo;
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLButtonElement.cpp b/Source/WebCore/html/HTMLButtonElement.cpp
new file mode 100644
index 0000000..686790d
--- /dev/null
+++ b/Source/WebCore/html/HTMLButtonElement.cpp
@@ -0,0 +1,187 @@
+/*
+ * 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, 2010 Apple Inc. All rights reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLButtonElement.h"
+
+#include "Attribute.h"
+#include "EventNames.h"
+#include "FormDataList.h"
+#include "HTMLFormElement.h"
+#include "HTMLNames.h"
+#include "KeyboardEvent.h"
+#include "RenderButton.h"
+#include "ScriptEventListener.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLButtonElement::HTMLButtonElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLFormControlElement(tagName, document, form)
+ , m_type(SUBMIT)
+ , m_isActivatedSubmit(false)
+{
+ ASSERT(hasTagName(buttonTag));
+}
+
+PassRefPtr<HTMLButtonElement> HTMLButtonElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLButtonElement(tagName, document, form));
+}
+
+RenderObject* HTMLButtonElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderButton(this);
+}
+
+const AtomicString& HTMLButtonElement::formControlType() const
+{
+ switch (m_type) {
+ case SUBMIT: {
+ DEFINE_STATIC_LOCAL(const AtomicString, submit, ("submit"));
+ return submit;
+ }
+ case BUTTON: {
+ DEFINE_STATIC_LOCAL(const AtomicString, button, ("button"));
+ return button;
+ }
+ case RESET: {
+ DEFINE_STATIC_LOCAL(const AtomicString, reset, ("reset"));
+ return reset;
+ }
+ }
+
+ ASSERT_NOT_REACHED();
+ return emptyAtom;
+}
+
+void HTMLButtonElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == typeAttr) {
+ if (equalIgnoringCase(attr->value(), "reset"))
+ m_type = RESET;
+ else if (equalIgnoringCase(attr->value(), "button"))
+ m_type = BUTTON;
+ else
+ m_type = SUBMIT;
+ setNeedsWillValidateCheck();
+ } else if (attr->name() == alignAttr) {
+ // Don't map 'align' attribute. This matches what Firefox and IE do, but not Opera.
+ // See http://bugs.webkit.org/show_bug.cgi?id=12071
+ } else
+ HTMLFormControlElement::parseMappedAttribute(attr);
+}
+
+void HTMLButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().DOMActivateEvent && !disabled()) {
+ if (form() && m_type == SUBMIT) {
+ m_isActivatedSubmit = true;
+ form()->prepareForSubmission(event);
+ m_isActivatedSubmit = false; // Do this in case submission was canceled.
+ }
+ if (form() && m_type == RESET)
+ form()->reset();
+ }
+
+ 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 (event->type() == eventNames().keypressEvent) {
+ switch (static_cast<KeyboardEvent*>(event)->charCode()) {
+ case '\r':
+ dispatchSimulatedClick(event);
+ event->setDefaultHandled();
+ return;
+ case ' ':
+ // Prevent scrolling down the page.
+ event->setDefaultHandled();
+ return;
+ }
+ }
+ if (event->type() == eventNames().keyupEvent && static_cast<KeyboardEvent*>(event)->keyIdentifier() == "U+0020") {
+ if (active())
+ dispatchSimulatedClick(event);
+ event->setDefaultHandled();
+ return;
+ }
+ }
+
+ HTMLFormControlElement::defaultEventHandler(event);
+}
+
+bool HTMLButtonElement::isSuccessfulSubmitButton() const
+{
+ // HTML spec says that buttons must have names to be considered successful.
+ // However, other browsers do not impose this constraint.
+ return m_type == SUBMIT && !disabled();
+}
+
+bool HTMLButtonElement::isActivatedSubmit() const
+{
+ return m_isActivatedSubmit;
+}
+
+void HTMLButtonElement::setActivatedSubmit(bool flag)
+{
+ m_isActivatedSubmit = flag;
+}
+
+bool HTMLButtonElement::appendFormData(FormDataList& formData, bool)
+{
+ if (m_type != SUBMIT || name().isEmpty() || !m_isActivatedSubmit)
+ return false;
+ formData.appendData(name(), value());
+ return true;
+}
+
+void HTMLButtonElement::accessKeyAction(bool sendToAnyElement)
+{
+ focus();
+ // send the mouse button events iff the caller specified sendToAnyElement
+ dispatchSimulatedClick(0, sendToAnyElement);
+}
+
+bool HTMLButtonElement::isURLAttribute(Attribute* attr) const
+{
+ return attr->name() == formactionAttr;
+}
+
+String HTMLButtonElement::value() const
+{
+ return getAttribute(valueAttr);
+}
+
+bool HTMLButtonElement::recalcWillValidate() const
+{
+ return m_type == SUBMIT && HTMLFormControlElement::recalcWillValidate();
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLButtonElement.h b/Source/WebCore/html/HTMLButtonElement.h
new file mode 100644
index 0000000..0d64f06
--- /dev/null
+++ b/Source/WebCore/html/HTMLButtonElement.h
@@ -0,0 +1,70 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLButtonElement_h
+#define HTMLButtonElement_h
+
+#include "HTMLFormControlElement.h"
+
+namespace WebCore {
+
+class HTMLButtonElement : public HTMLFormControlElement {
+public:
+ static PassRefPtr<HTMLButtonElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+
+ String value() const;
+
+private:
+ HTMLButtonElement(const QualifiedName& tagName, Document*, HTMLFormElement*);
+
+ enum Type { SUBMIT, RESET, BUTTON };
+
+ virtual const AtomicString& formControlType() const;
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void defaultEventHandler(Event*);
+ virtual bool appendFormData(FormDataList&, bool);
+
+ virtual bool isEnumeratable() const { return true; }
+
+ virtual bool isSuccessfulSubmitButton() const;
+ virtual bool isActivatedSubmit() const;
+ virtual void setActivatedSubmit(bool flag);
+
+ virtual void accessKeyAction(bool sendToAnyElement);
+ virtual bool isURLAttribute(Attribute*) const;
+
+ virtual bool canStartSelection() const { return false; }
+
+ virtual bool isOptionalFormControl() const { return true; }
+ virtual bool recalcWillValidate() const;
+
+ Type m_type;
+ bool m_isActivatedSubmit;
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLButtonElement.idl b/Source/WebCore/html/HTMLButtonElement.idl
new file mode 100644
index 0000000..2fbba41
--- /dev/null
+++ b/Source/WebCore/html/HTMLButtonElement.idl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLButtonElement : HTMLElement {
+ readonly attribute HTMLFormElement form;
+
+ attribute [Reflect, URL] DOMString formAction;
+ attribute [Reflect] DOMString formEnctype;
+ attribute [Reflect] DOMString formMethod;
+ attribute [Reflect] boolean formNoValidate;
+ attribute [Reflect] DOMString formTarget;
+ readonly attribute ValidityState validity;
+
+ attribute [Reflect] DOMString accessKey;
+ attribute [Reflect] boolean disabled;
+ attribute [Reflect] boolean autofocus;
+ attribute [Reflect] DOMString name;
+ readonly attribute DOMString type;
+ attribute [Reflect] DOMString value;
+
+ readonly attribute boolean willValidate;
+ readonly attribute DOMString validationMessage;
+ boolean checkValidity();
+ void setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error);
+
+ void click();
+
+ readonly attribute NodeList labels;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp
new file mode 100644
index 0000000..f286749
--- /dev/null
+++ b/Source/WebCore/html/HTMLCanvasElement.cpp
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. 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"
+#include "HTMLCanvasElement.h"
+
+#include "Attribute.h"
+#include "CanvasContextAttributes.h"
+#include "CanvasGradient.h"
+#include "CanvasPattern.h"
+#include "CanvasRenderingContext2D.h"
+#include "CanvasStyle.h"
+#include "Chrome.h"
+#include "Document.h"
+#include "ExceptionCode.h"
+#include "Frame.h"
+#include "GraphicsContext.h"
+#include "HTMLNames.h"
+#include "ImageBuffer.h"
+#include "MIMETypeRegistry.h"
+#include "Page.h"
+#include "RenderHTMLCanvas.h"
+#include "Settings.h"
+#include <math.h>
+#include <stdio.h>
+
+#if ENABLE(3D_CANVAS)
+#include "WebGLContextAttributes.h"
+#include "WebGLRenderingContext.h"
+#endif
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+// 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.
+static const float MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels
+
+//In Skia, we will also limit width/height to 32767.
+static const float MaxSkiaDim = 32767.0F; // Maximum width/height in CSS pixels.
+
+HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , m_size(DefaultWidth, DefaultHeight)
+ , m_ignoreReset(false)
+ , m_pageScaleFactor(document->frame() ? document->frame()->page()->chrome()->scaleFactor() : 1)
+ , m_originClean(true)
+ , m_hasCreatedImageBuffer(false)
+{
+ ASSERT(hasTagName(canvasTag));
+}
+
+PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(Document* document)
+{
+ return adoptRef(new HTMLCanvasElement(canvasTag, document));
+}
+
+PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLCanvasElement(tagName, document));
+}
+
+HTMLCanvasElement::~HTMLCanvasElement()
+{
+ HashSet<CanvasObserver*>::iterator end = m_observers.end();
+ for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
+ (*it)->canvasDestroyed(this);
+}
+
+void HTMLCanvasElement::parseMappedAttribute(Attribute* attr)
+{
+ const QualifiedName& attrName = attr->name();
+ if (attrName == widthAttr || attrName == heightAttr)
+ reset();
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+RenderObject* HTMLCanvasElement::createRenderer(RenderArena* arena, RenderStyle* style)
+{
+ Frame* frame = document()->frame();
+ if (frame && frame->script()->canExecuteScripts(NotAboutToExecuteScript)) {
+ m_rendererIsCanvas = true;
+ return new (arena) RenderHTMLCanvas(this);
+ }
+
+ m_rendererIsCanvas = false;
+ return HTMLElement::createRenderer(arena, style);
+}
+
+void HTMLCanvasElement::addObserver(CanvasObserver* observer)
+{
+ m_observers.add(observer);
+}
+
+void HTMLCanvasElement::removeObserver(CanvasObserver* observer)
+{
+ m_observers.remove(observer);
+}
+
+void HTMLCanvasElement::setHeight(int value)
+{
+ setAttribute(heightAttr, String::number(value));
+}
+
+void HTMLCanvasElement::setWidth(int value)
+{
+ setAttribute(widthAttr, String::number(value));
+}
+
+CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, CanvasContextAttributes* attrs)
+{
+ // A Canvas can either be "2D" or "webgl" but never both. If you request a 2D canvas and the existing
+ // context is already 2D, just return that. If the existing context is WebGL, then destroy it
+ // before creating a new 2D context. Vice versa when requesting a WebGL canvas. Requesting a
+ // context with any other type string will destroy any existing context.
+
+ // FIXME - The code depends on the context not going away once created, to prevent JS from
+ // seeing a dangling pointer. So for now we will disallow the context from being changed
+ // once it is created.
+ if (type == "2d") {
+ if (m_context && !m_context->is2d())
+ return 0;
+ if (!m_context) {
+ bool usesDashbardCompatibilityMode = false;
+#if ENABLE(DASHBOARD_SUPPORT)
+ if (Settings* settings = document()->settings())
+ usesDashbardCompatibilityMode = settings->usesDashboardBackwardCompatibilityMode();
+#endif
+ m_context = adoptPtr(new CanvasRenderingContext2D(this, document()->inQuirksMode(), usesDashbardCompatibilityMode));
+#if USE(IOSURFACE_CANVAS_BACKING_STORE) || (ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING))
+ if (m_context) {
+ // Need to make sure a RenderLayer and compositing layer get created for the Canvas
+ setNeedsStyleRecalc(SyntheticStyleChange);
+ }
+#endif
+ }
+ return m_context.get();
+ }
+#if ENABLE(3D_CANVAS)
+ Settings* settings = document()->settings();
+ if (settings && settings->webGLEnabled()
+#if !PLATFORM(CHROMIUM) && !PLATFORM(QT)
+ && settings->acceleratedCompositingEnabled()
+#endif
+ ) {
+ // Accept the legacy "webkit-3d" name as well as the provisional "experimental-webgl" name.
+ // Once ratified, we will also accept "webgl" as the context name.
+ if ((type == "webkit-3d") ||
+ (type == "experimental-webgl")) {
+ if (m_context && !m_context->is3d())
+ return 0;
+ if (!m_context) {
+ 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);
+ }
+ }
+ return m_context.get();
+ }
+ }
+#else
+ UNUSED_PARAM(attrs);
+#endif
+ return 0;
+}
+
+void HTMLCanvasElement::didDraw(const FloatRect& rect)
+{
+ m_copiedImage.clear(); // Clear our image snapshot if we have one.
+
+ if (RenderBox* ro = renderBox()) {
+ FloatRect destRect = ro->contentBoxRect();
+ FloatRect r = mapRect(rect, FloatRect(0, 0, size().width(), size().height()), destRect);
+ r.intersect(destRect);
+ if (r.isEmpty() || m_dirtyRect.contains(r))
+ return;
+
+ m_dirtyRect.unite(r);
+ ro->repaintRectangle(enclosingIntRect(m_dirtyRect));
+ }
+
+ HashSet<CanvasObserver*>::iterator end = m_observers.end();
+ for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
+ (*it)->canvasChanged(this, rect);
+}
+
+void HTMLCanvasElement::reset()
+{
+ if (m_ignoreReset)
+ return;
+
+ bool ok;
+ bool hadImageBuffer = hasCreatedImageBuffer();
+ int w = getAttribute(widthAttr).toInt(&ok);
+ if (!ok || w < 0)
+ w = DefaultWidth;
+ int h = getAttribute(heightAttr).toInt(&ok);
+ if (!ok || h < 0)
+ h = DefaultHeight;
+
+ IntSize oldSize = size();
+ setSurfaceSize(IntSize(w, h)); // The image buffer gets cleared here.
+
+#if ENABLE(3D_CANVAS)
+ if (m_context && m_context->is3d() && oldSize != size())
+ static_cast<WebGLRenderingContext*>(m_context.get())->reshape(width(), height());
+#endif
+
+ if (m_context && m_context->is2d())
+ static_cast<CanvasRenderingContext2D*>(m_context.get())->reset();
+
+ if (RenderObject* renderer = this->renderer()) {
+ if (m_rendererIsCanvas) {
+ if (oldSize != size())
+ toRenderHTMLCanvas(renderer)->canvasSizeChanged();
+ if (hadImageBuffer)
+ renderer->repaint();
+ }
+ }
+
+ HashSet<CanvasObserver*>::iterator end = m_observers.end();
+ for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
+ (*it)->canvasResized(this);
+}
+
+void HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r)
+{
+ // Clear the dirty rect
+ m_dirtyRect = FloatRect();
+
+ if (context->paintingDisabled())
+ return;
+
+ if (m_context) {
+ if (!m_context->paintsIntoCanvasBuffer())
+ return;
+ m_context->paintRenderingResultsToCanvas();
+ }
+
+ if (hasCreatedImageBuffer()) {
+ ImageBuffer* imageBuffer = buffer();
+ if (imageBuffer) {
+ if (imageBuffer->drawsUsingCopy())
+ context->drawImage(copiedImage(), ColorSpaceDeviceRGB, r);
+ else
+ context->drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, r);
+ }
+ }
+}
+
+#if ENABLE(3D_CANVAS)
+bool HTMLCanvasElement::is3D() const
+{
+ return m_context && m_context->is3d();
+}
+#endif
+
+void HTMLCanvasElement::makeRenderingResultsAvailable()
+{
+ if (m_context)
+ m_context->paintRenderingResultsToCanvas();
+}
+
+void HTMLCanvasElement::attach()
+{
+ HTMLElement::attach();
+
+ if (m_context && m_context->is2d()) {
+ CanvasRenderingContext2D* ctx = static_cast<CanvasRenderingContext2D*>(m_context.get());
+ ctx->updateFont();
+ }
+}
+
+void HTMLCanvasElement::recalcStyle(StyleChange change)
+{
+ HTMLElement::recalcStyle(change);
+
+ // Update font if needed.
+ if (change == Force && m_context && m_context->is2d()) {
+ CanvasRenderingContext2D* ctx = static_cast<CanvasRenderingContext2D*>(m_context.get());
+ ctx->updateFont();
+ }
+}
+
+void HTMLCanvasElement::setSurfaceSize(const IntSize& size)
+{
+ m_size = size;
+ m_hasCreatedImageBuffer = false;
+ m_imageBuffer.clear();
+ m_copiedImage.clear();
+}
+
+String HTMLCanvasElement::toDataURL(const String& mimeType, const double* quality, ExceptionCode& ec)
+{
+ if (!m_originClean) {
+ ec = SECURITY_ERR;
+ return String();
+ }
+
+ if (m_size.isEmpty() || !buffer())
+ return String("data:,");
+
+ String lowercaseMimeType = mimeType.lower();
+
+ makeRenderingResultsAvailable();
+
+ // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread).
+ if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(lowercaseMimeType))
+ return buffer()->toDataURL("image/png");
+
+ return buffer()->toDataURL(lowercaseMimeType, quality);
+}
+
+IntRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect) const
+{
+ float left = floorf(logicalRect.left() * m_pageScaleFactor);
+ float top = floorf(logicalRect.top() * m_pageScaleFactor);
+ float right = ceilf(logicalRect.right() * m_pageScaleFactor);
+ float bottom = ceilf(logicalRect.bottom() * m_pageScaleFactor);
+
+ return IntRect(IntPoint(left, top), convertToValidDeviceSize(right - left, bottom - top));
+}
+
+IntSize HTMLCanvasElement::convertLogicalToDevice(const FloatSize& logicalSize) const
+{
+ return convertToValidDeviceSize(logicalSize.width() * m_pageScaleFactor, logicalSize.height() * m_pageScaleFactor);
+}
+
+IntSize HTMLCanvasElement::convertToValidDeviceSize(float width, float height) const
+{
+ width = ceilf(width);
+ height = ceilf(height);
+
+ if (width < 1 || height < 1 || width * height > MaxCanvasArea)
+ return IntSize();
+
+#if PLATFORM(SKIA)
+ if (width > MaxSkiaDim || height > MaxSkiaDim)
+ return IntSize();
+#endif
+
+ return IntSize(width, height);
+}
+
+const SecurityOrigin& HTMLCanvasElement::securityOrigin() const
+{
+ return *document()->securityOrigin();
+}
+
+CSSStyleSelector* HTMLCanvasElement::styleSelector()
+{
+ return document()->styleSelector();
+}
+
+void HTMLCanvasElement::createImageBuffer() const
+{
+ ASSERT(!m_imageBuffer);
+
+ m_hasCreatedImageBuffer = true;
+
+ FloatSize unscaledSize(width(), height());
+ IntSize size = convertLogicalToDevice(unscaledSize);
+ if (!size.width() || !size.height())
+ return;
+
+#if USE(IOSURFACE_CANVAS_BACKING_STORE)
+ m_imageBuffer = ImageBuffer::create(size, ColorSpaceDeviceRGB, Accelerated);
+#else
+ m_imageBuffer = ImageBuffer::create(size);
+#endif
+ // The convertLogicalToDevice MaxCanvasArea check should prevent common cases
+ // where ImageBuffer::create() returns 0, however we could still be low on memory.
+ if (!m_imageBuffer)
+ return;
+ m_imageBuffer->context()->scale(FloatSize(size.width() / unscaledSize.width(), size.height() / unscaledSize.height()));
+ m_imageBuffer->context()->setShadowsIgnoreTransforms(true);
+ m_imageBuffer->context()->setImageInterpolationQuality(DefaultInterpolationQuality);
+}
+
+GraphicsContext* HTMLCanvasElement::drawingContext() const
+{
+ return buffer() ? m_imageBuffer->context() : 0;
+}
+
+ImageBuffer* HTMLCanvasElement::buffer() const
+{
+ if (!m_hasCreatedImageBuffer)
+ createImageBuffer();
+ return m_imageBuffer.get();
+}
+
+Image* HTMLCanvasElement::copiedImage() const
+{
+ if (!m_copiedImage && buffer()) {
+ if (m_context) {
+ // If we're not rendering to the ImageBuffer, copy the rendering results to it.
+ if (!m_context->paintsIntoCanvasBuffer())
+ m_context->paintRenderingResultsToCanvas();
+ }
+ m_copiedImage = buffer()->copyImage();
+ }
+ return m_copiedImage.get();
+}
+
+void HTMLCanvasElement::clearCopiedImage()
+{
+ m_copiedImage.clear();
+}
+
+AffineTransform HTMLCanvasElement::baseTransform() const
+{
+ ASSERT(m_hasCreatedImageBuffer);
+ FloatSize unscaledSize(width(), height());
+ IntSize size = convertLogicalToDevice(unscaledSize);
+ AffineTransform transform;
+ if (size.width() && size.height())
+ transform.scaleNonUniform(size.width() / unscaledSize.width(), size.height() / unscaledSize.height());
+ transform.multiply(m_imageBuffer->baseTransform());
+ return transform;
+}
+
+}
diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h
new file mode 100644
index 0000000..1f32dec
--- /dev/null
+++ b/Source/WebCore/html/HTMLCanvasElement.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2004, 2006, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. 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 HTMLCanvasElement_h
+#define HTMLCanvasElement_h
+
+#include "FloatRect.h"
+#include "HTMLElement.h"
+#include "IntSize.h"
+
+#if PLATFORM(CHROMIUM) || PLATFORM(QT)
+#define DefaultInterpolationQuality InterpolationMedium
+#elif PLATFORM(CG)
+#define DefaultInterpolationQuality InterpolationLow
+#else
+#define DefaultInterpolationQuality InterpolationDefault
+#endif
+
+namespace WebCore {
+
+class CanvasContextAttributes;
+class CanvasRenderingContext;
+class GraphicsContext;
+class HTMLCanvasElement;
+class Image;
+class ImageBuffer;
+class IntSize;
+
+class CanvasObserver {
+public:
+ virtual ~CanvasObserver() { }
+
+ virtual void canvasChanged(HTMLCanvasElement*, const FloatRect& changedRect) = 0;
+ virtual void canvasResized(HTMLCanvasElement*) = 0;
+ virtual void canvasDestroyed(HTMLCanvasElement*) = 0;
+};
+
+class HTMLCanvasElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLCanvasElement> create(Document*);
+ static PassRefPtr<HTMLCanvasElement> create(const QualifiedName&, Document*);
+ virtual ~HTMLCanvasElement();
+
+ void addObserver(CanvasObserver*);
+ void removeObserver(CanvasObserver*);
+
+ // Attributes and functions exposed to script
+ int width() const { return size().width(); }
+ int height() const { return size().height(); }
+
+ const IntSize& size() const { return m_size; }
+
+ void setWidth(int);
+ void setHeight(int);
+
+ void setSize(const IntSize& newSize)
+ {
+ if (newSize == size())
+ return;
+ m_ignoreReset = true;
+ setWidth(newSize.width());
+ setHeight(newSize.height());
+ m_ignoreReset = false;
+ reset();
+ }
+
+ CanvasRenderingContext* getContext(const String&, CanvasContextAttributes* attributes = 0);
+
+ String toDataURL(const String& mimeType, const double* quality, ExceptionCode&);
+ String toDataURL(const String& mimeType, ExceptionCode& ec) { return toDataURL(mimeType, 0, ec); }
+
+ // Used for rendering
+ void didDraw(const FloatRect&);
+
+ void paint(GraphicsContext*, const IntRect&);
+
+ GraphicsContext* drawingContext() const;
+
+ CanvasRenderingContext* renderingContext() const { return m_context.get(); }
+
+ ImageBuffer* buffer() const;
+ Image* copiedImage() const;
+ void clearCopiedImage();
+
+ IntRect convertLogicalToDevice(const FloatRect&) const;
+ IntSize convertLogicalToDevice(const FloatSize&) const;
+ IntSize convertToValidDeviceSize(float width, float height) const;
+
+ const SecurityOrigin& securityOrigin() const;
+ void setOriginTainted() { m_originClean = false; }
+ bool originClean() const { return m_originClean; }
+
+ CSSStyleSelector* styleSelector();
+
+ AffineTransform baseTransform() const;
+
+#if ENABLE(3D_CANVAS)
+ bool is3D() const;
+#endif
+
+ void makeRenderingResultsAvailable();
+
+#ifdef ANDROID_INSTRUMENT
+ void* operator new(size_t size) {
+ return HTMLElement::operator new(size);
+ }
+ void* operator new[](size_t size) {
+ return HTMLElement::operator new[](size);
+ }
+
+ void operator delete(void* p, size_t size) {
+ HTMLElement::operator delete(p, size);
+ }
+ void operator delete[](void* p, size_t size) {
+ HTMLElement::operator delete[](p, size);
+ }
+#endif
+
+private:
+ HTMLCanvasElement(const QualifiedName&, Document*);
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ virtual void attach();
+
+ virtual void recalcStyle(StyleChange);
+
+ void reset();
+
+ void createImageBuffer() const;
+
+ void setSurfaceSize(const IntSize&);
+ bool hasCreatedImageBuffer() const { return m_hasCreatedImageBuffer; }
+
+ HashSet<CanvasObserver*> m_observers;
+
+ IntSize m_size;
+
+ OwnPtr<CanvasRenderingContext> m_context;
+
+ bool m_rendererIsCanvas;
+
+ bool m_ignoreReset;
+ FloatRect m_dirtyRect;
+
+ float m_pageScaleFactor;
+ bool m_originClean;
+
+ // m_createdImageBuffer means we tried to malloc the buffer. We didn't necessarily get it.
+ mutable bool m_hasCreatedImageBuffer;
+ mutable OwnPtr<ImageBuffer> m_imageBuffer;
+
+ mutable RefPtr<Image> m_copiedImage; // FIXME: This is temporary for platforms that have to copy the image buffer to render (and for CSSCanvasValue).
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLCanvasElement.idl b/Source/WebCore/html/HTMLCanvasElement.idl
new file mode 100644
index 0000000..3a56330
--- /dev/null
+++ b/Source/WebCore/html/HTMLCanvasElement.idl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2006, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. 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.
+ */
+
+module html {
+
+ interface [
+ CustomMarkFunction,
+ GenerateNativeConverter
+ ] HTMLCanvasElement : HTMLElement {
+
+ attribute long width;
+ attribute long height;
+
+ [Custom] DOMString toDataURL(in [ConvertUndefinedOrNullToNullString] DOMString type)
+ raises(DOMException);
+
+#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] DOMObject getContext(in DOMString contextId);
+#endif
+#endif
+
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLCollection.cpp b/Source/WebCore/html/HTMLCollection.cpp
new file mode 100644
index 0000000..9b4e566
--- /dev/null
+++ b/Source/WebCore/html/HTMLCollection.cpp
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLCollection.h"
+
+#include "HTMLDocument.h"
+#include "HTMLElement.h"
+#include "HTMLNames.h"
+#include "HTMLObjectElement.h"
+#include "HTMLOptionElement.h"
+#include "NodeList.h"
+
+#include <utility>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLCollection::HTMLCollection(PassRefPtr<Node> base, CollectionType type)
+ : m_idsDone(false)
+ , m_base(base)
+ , m_type(type)
+ , m_info(m_base->isDocumentNode() ? static_cast<Document*>(m_base.get())->collectionInfo(type) : 0)
+ , m_ownsInfo(false)
+{
+}
+
+HTMLCollection::HTMLCollection(PassRefPtr<Node> base, CollectionType type, CollectionCache* info)
+ : m_idsDone(false)
+ , m_base(base)
+ , m_type(type)
+ , m_info(info)
+ , m_ownsInfo(false)
+{
+}
+
+PassRefPtr<HTMLCollection> HTMLCollection::create(PassRefPtr<Node> base, CollectionType type)
+{
+ return adoptRef(new HTMLCollection(base, type));
+}
+
+HTMLCollection::~HTMLCollection()
+{
+ if (m_ownsInfo)
+ delete m_info;
+}
+
+void HTMLCollection::resetCollectionInfo() const
+{
+ unsigned docversion = static_cast<HTMLDocument*>(m_base->document())->domTreeVersion();
+
+ if (!m_info) {
+ m_info = new CollectionCache;
+ m_ownsInfo = true;
+ m_info->version = docversion;
+ return;
+ }
+
+ if (m_info->version != docversion) {
+ m_info->reset();
+ m_info->version = docversion;
+ }
+}
+
+static Node* nextNodeOrSibling(Node* base, Node* node, bool includeChildren)
+{
+ return includeChildren ? node->traverseNextNode(base) : node->traverseNextSibling(base);
+}
+
+Element* HTMLCollection::itemAfter(Element* previous) const
+{
+ bool deep = true;
+
+ switch (m_type) {
+ case DocAll:
+ case DocAnchors:
+ case DocApplets:
+ case DocEmbeds:
+ case DocForms:
+ case DocImages:
+ case DocLinks:
+ case DocObjects:
+ case DocScripts:
+ case DocumentNamedItems:
+ case MapAreas:
+ case OtherCollection:
+ case SelectOptions:
+ case DataListOptions:
+ case WindowNamedItems:
+ break;
+ case NodeChildren:
+ case TRCells:
+ case TSectionRows:
+ case TableTBodies:
+ deep = false;
+ break;
+ }
+
+ Node* current;
+ if (!previous)
+ current = m_base->firstChild();
+ else
+ current = nextNodeOrSibling(m_base.get(), previous, deep);
+
+ for (; current; current = nextNodeOrSibling(m_base.get(), current, deep)) {
+ if (!current->isElementNode())
+ continue;
+ Element* e = static_cast<Element*>(current);
+ switch (m_type) {
+ case DocImages:
+ if (e->hasLocalName(imgTag))
+ return e;
+ break;
+ case DocScripts:
+ if (e->hasLocalName(scriptTag))
+ return e;
+ break;
+ case DocForms:
+ if (e->hasLocalName(formTag))
+ return e;
+ break;
+ case TableTBodies:
+ if (e->hasLocalName(tbodyTag))
+ return e;
+ break;
+ case TRCells:
+ if (e->hasLocalName(tdTag) || e->hasLocalName(thTag))
+ return e;
+ break;
+ case TSectionRows:
+ if (e->hasLocalName(trTag))
+ return e;
+ break;
+ case SelectOptions:
+ if (e->hasLocalName(optionTag))
+ return e;
+ break;
+ case DataListOptions:
+ if (e->hasLocalName(optionTag)) {
+ HTMLOptionElement* option = static_cast<HTMLOptionElement*>(e);
+ if (!option->disabled() && !option->value().isEmpty())
+ return e;
+ }
+ break;
+ case MapAreas:
+ if (e->hasLocalName(areaTag))
+ return e;
+ break;
+ case DocApplets: // all <applet> elements and <object> elements that contain Java Applets
+ if (e->hasLocalName(appletTag))
+ return e;
+ if (e->hasLocalName(objectTag) && static_cast<HTMLObjectElement*>(e)->containsJavaApplet())
+ return e;
+ break;
+ case DocEmbeds:
+ if (e->hasLocalName(embedTag))
+ return e;
+ break;
+ case DocObjects:
+ if (e->hasLocalName(objectTag))
+ return e;
+ break;
+ case DocLinks: // all <a> and <area> elements with a value for href
+ if ((e->hasLocalName(aTag) || e->hasLocalName(areaTag)) && e->fastHasAttribute(hrefAttr))
+ return e;
+ break;
+ case DocAnchors: // all <a> elements with a value for name
+ if (e->hasLocalName(aTag) && e->fastHasAttribute(nameAttr))
+ return e;
+ break;
+ case DocAll:
+ case NodeChildren:
+ return e;
+ case DocumentNamedItems:
+ case OtherCollection:
+ case WindowNamedItems:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+
+ return 0;
+}
+
+unsigned HTMLCollection::calcLength() const
+{
+ unsigned len = 0;
+ for (Element* current = itemAfter(0); current; current = itemAfter(current))
+ ++len;
+ return len;
+}
+
+// since the collections are to be "live", we have to do the
+// calculation every time if anything has changed
+unsigned HTMLCollection::length() const
+{
+ resetCollectionInfo();
+ if (!m_info->hasLength) {
+ m_info->length = calcLength();
+ m_info->hasLength = true;
+ }
+ return m_info->length;
+}
+
+Node* HTMLCollection::item(unsigned index) const
+{
+ resetCollectionInfo();
+ if (m_info->current && m_info->position == index)
+ return m_info->current;
+ if (m_info->hasLength && m_info->length <= index)
+ return 0;
+ if (!m_info->current || m_info->position > index) {
+ m_info->current = itemAfter(0);
+ m_info->position = 0;
+ if (!m_info->current)
+ return 0;
+ }
+ Element* e = m_info->current;
+ for (unsigned pos = m_info->position; e && pos < index; pos++)
+ e = itemAfter(e);
+ m_info->current = e;
+ m_info->position = index;
+ return m_info->current;
+}
+
+Node* HTMLCollection::firstItem() const
+{
+ return item(0);
+}
+
+Node* HTMLCollection::nextItem() const
+{
+ resetCollectionInfo();
+
+ // Look for the 'second' item. The first one is currentItem, already given back.
+ Element* retval = itemAfter(m_info->current);
+ m_info->current = retval;
+ m_info->position++;
+ return retval;
+}
+
+bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const AtomicString& name) const
+{
+ if (!element->isHTMLElement())
+ return false;
+
+ HTMLElement* e = static_cast<HTMLElement*>(element);
+ if (!checkName)
+ return e->getIdAttribute() == name;
+
+ // document.all returns only images, forms, applets, objects and embeds
+ // by name (though everything by id)
+ if (m_type == DocAll &&
+ !(e->hasLocalName(imgTag) || e->hasLocalName(formTag) ||
+ e->hasLocalName(appletTag) || e->hasLocalName(objectTag) ||
+ e->hasLocalName(embedTag) || e->hasLocalName(inputTag) ||
+ e->hasLocalName(selectTag)))
+ return false;
+
+ return e->getAttribute(nameAttr) == name && e->getIdAttribute() != name;
+}
+
+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
+ // 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.
+ resetCollectionInfo();
+ m_idsDone = false;
+
+ for (Element* e = itemAfter(0); e; e = itemAfter(e)) {
+ if (checkForNameMatch(e, m_idsDone, name)) {
+ m_info->current = e;
+ return e;
+ }
+ }
+
+ m_idsDone = true;
+
+ for (Element* e = itemAfter(0); e; e = itemAfter(e)) {
+ if (checkForNameMatch(e, m_idsDone, name)) {
+ m_info->current = e;
+ return e;
+ }
+ }
+
+ m_info->current = 0;
+ return 0;
+}
+
+void HTMLCollection::updateNameCache() const
+{
+ if (m_info->hasNameCache)
+ return;
+
+ for (Element* element = itemAfter(0); element; element = itemAfter(element)) {
+ if (!element->isHTMLElement())
+ continue;
+ HTMLElement* e = static_cast<HTMLElement*>(element);
+ const AtomicString& idAttrVal = e->getIdAttribute();
+ const AtomicString& nameAttrVal = e->getAttribute(nameAttr);
+ if (!idAttrVal.isEmpty()) {
+ // add to id cache
+ Vector<Element*>* idVector = m_info->idCache.get(idAttrVal.impl());
+ if (!idVector) {
+ idVector = new Vector<Element*>;
+ m_info->idCache.add(idAttrVal.impl(), idVector);
+ }
+ idVector->append(e);
+ }
+ if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal
+ && (m_type != DocAll ||
+ (e->hasLocalName(imgTag) || e->hasLocalName(formTag) ||
+ e->hasLocalName(appletTag) || e->hasLocalName(objectTag) ||
+ e->hasLocalName(embedTag) || e->hasLocalName(inputTag) ||
+ e->hasLocalName(selectTag)))) {
+ // add to name cache
+ Vector<Element*>* nameVector = m_info->nameCache.get(nameAttrVal.impl());
+ if (!nameVector) {
+ nameVector = new Vector<Element*>;
+ m_info->nameCache.add(nameAttrVal.impl(), nameVector);
+ }
+ nameVector->append(e);
+ }
+ }
+
+ m_info->hasNameCache = true;
+}
+
+void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& result) const
+{
+ ASSERT(result.isEmpty());
+
+ if (name.isEmpty())
+ return;
+
+ resetCollectionInfo();
+ updateNameCache();
+ m_info->checkConsistency();
+
+ Vector<Element*>* idResults = m_info->idCache.get(name.impl());
+ Vector<Element*>* nameResults = m_info->nameCache.get(name.impl());
+
+ for (unsigned i = 0; idResults && i < idResults->size(); ++i)
+ result.append(idResults->at(i));
+
+ for (unsigned i = 0; nameResults && i < nameResults->size(); ++i)
+ result.append(nameResults->at(i));
+}
+
+
+Node* HTMLCollection::nextNamedItem(const AtomicString& name) const
+{
+ resetCollectionInfo();
+ m_info->checkConsistency();
+
+ for (Element* e = itemAfter(m_info->current); e; e = itemAfter(e)) {
+ if (checkForNameMatch(e, m_idsDone, name)) {
+ m_info->current = e;
+ return e;
+ }
+ }
+
+ if (m_idsDone) {
+ m_info->current = 0;
+ return 0;
+ }
+ m_idsDone = true;
+
+ for (Element* e = itemAfter(m_info->current); e; e = itemAfter(e)) {
+ if (checkForNameMatch(e, m_idsDone, name)) {
+ m_info->current = e;
+ return e;
+ }
+ }
+
+ return 0;
+}
+
+PassRefPtr<NodeList> HTMLCollection::tags(const String& name)
+{
+ return m_base->getElementsByTagName(name);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLCollection.h b/Source/WebCore/html/HTMLCollection.h
new file mode 100644
index 0000000..4359724
--- /dev/null
+++ b/Source/WebCore/html/HTMLCollection.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLCollection_h
+#define HTMLCollection_h
+
+#include "CollectionType.h"
+#include <wtf/RefCounted.h>
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Element;
+class Node;
+class NodeList;
+
+struct CollectionCache;
+
+class HTMLCollection : public RefCounted<HTMLCollection> {
+public:
+ static PassRefPtr<HTMLCollection> create(PassRefPtr<Node> base, CollectionType);
+ virtual ~HTMLCollection();
+
+ unsigned length() const;
+
+ virtual Node* item(unsigned index) const;
+ virtual Node* nextItem() const;
+
+ virtual Node* namedItem(const AtomicString& name) const;
+ virtual Node* nextNamedItem(const AtomicString& name) const; // In case of multiple items named the same way
+
+ Node* firstItem() const;
+
+ void namedItems(const AtomicString& name, Vector<RefPtr<Node> >&) const;
+
+ PassRefPtr<NodeList> tags(const String&);
+
+ Node* base() const { return m_base.get(); }
+ CollectionType type() const { return m_type; }
+
+protected:
+ HTMLCollection(PassRefPtr<Node> base, CollectionType, CollectionCache*);
+ HTMLCollection(PassRefPtr<Node> base, CollectionType);
+
+ CollectionCache* info() const { return m_info; }
+ void resetCollectionInfo() const;
+
+ mutable bool m_idsDone; // for nextNamedItem()
+
+private:
+ virtual Element* itemAfter(Element*) const;
+ virtual unsigned calcLength() const;
+ virtual void updateNameCache() const;
+
+ bool checkForNameMatch(Element*, bool checkName, const AtomicString& name) const;
+
+ RefPtr<Node> m_base;
+ CollectionType m_type;
+
+ mutable CollectionCache* m_info;
+ mutable bool m_ownsInfo;
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLCollection.idl b/Source/WebCore/html/HTMLCollection.idl
new file mode 100644
index 0000000..a3e4332
--- /dev/null
+++ b/Source/WebCore/html/HTMLCollection.idl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ HasIndexGetter,
+ HasNameGetter,
+ CustomCall,
+ CustomToJS,
+ Polymorphic
+ ] HTMLCollection {
+ readonly attribute unsigned long length;
+ [Custom] Node item(in unsigned long index);
+ [Custom] Node namedItem(in DOMString name);
+
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+ NodeList tags(in DOMString name);
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLDListElement.cpp b/Source/WebCore/html/HTMLDListElement.cpp
new file mode 100644
index 0000000..cc9fabb
--- /dev/null
+++ b/Source/WebCore/html/HTMLDListElement.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLDListElement.h"
+
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLDListElement::HTMLDListElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(dlTag));
+}
+
+PassRefPtr<HTMLDListElement> HTMLDListElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLDListElement(tagName, document));
+}
+
+}
diff --git a/Source/WebCore/html/HTMLDListElement.h b/Source/WebCore/html/HTMLDListElement.h
new file mode 100644
index 0000000..25697a1
--- /dev/null
+++ b/Source/WebCore/html/HTMLDListElement.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLDListElement_h
+#define HTMLDListElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLDListElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLDListElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLDListElement(const QualifiedName&, Document*);
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLDListElement.idl b/Source/WebCore/html/HTMLDListElement.idl
new file mode 100644
index 0000000..1a9326f
--- /dev/null
+++ b/Source/WebCore/html/HTMLDListElement.idl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLDListElement : HTMLElement {
+ attribute [Reflect] boolean compact;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLDataGridCellElement.cpp b/Source/WebCore/html/HTMLDataGridCellElement.cpp
new file mode 100644
index 0000000..9596d63
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataGridCellElement.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 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 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(DATAGRID)
+
+#include "HTMLDataGridCellElement.h"
+
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLDataGridCellElement::HTMLDataGridCellElement(const QualifiedName& name, Document* document)
+ : HTMLElement(name, document)
+{
+}
+
+PassRefPtr<HTMLDataGridCellElement> HTMLDataGridCellElement::create(const QualifiedName& name, Document* document)
+{
+ return adoptRef(new HTMLDataGridCellElement(name, document));
+}
+
+String HTMLDataGridCellElement::label() const
+{
+ return getAttribute(labelAttr);
+}
+
+void HTMLDataGridCellElement::setLabel(const String& label)
+{
+ setAttribute(labelAttr, label);
+}
+
+bool HTMLDataGridCellElement::focused() const
+{
+ return hasAttribute(focusedAttr);
+}
+
+void HTMLDataGridCellElement::setFocused(bool focused)
+{
+ setAttribute(focusedAttr, focused ? "" : 0);
+}
+
+bool HTMLDataGridCellElement::checked() const
+{
+ return hasAttribute(checkedAttr);
+}
+
+void HTMLDataGridCellElement::setChecked(bool checked)
+{
+ setAttribute(checkedAttr, checked ? "" : 0);
+}
+
+bool HTMLDataGridCellElement::indeterminate() const
+{
+ return hasAttribute(indeterminateAttr);
+}
+
+void HTMLDataGridCellElement::setIndeterminate(bool indeterminate)
+{
+ setAttribute(indeterminateAttr, indeterminate ? "" : 0);
+}
+
+float HTMLDataGridCellElement::progress() const
+{
+ return getAttribute(progressAttr).toInt();
+}
+
+void HTMLDataGridCellElement::setProgress(float progress)
+{
+ setAttribute(progressAttr, String::number(progress));
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/HTMLDataGridCellElement.h b/Source/WebCore/html/HTMLDataGridCellElement.h
new file mode 100644
index 0000000..60af155
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataGridCellElement.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 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 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 HTMLDataGridCellElement_h
+#define HTMLDataGridCellElement_h
+
+#if ENABLE(DATAGRID)
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLDataGridCellElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLDataGridCellElement> create(const QualifiedName&, Document*);
+
+ String label() const;
+ void setLabel(const String&);
+
+ bool focused() const;
+ void setFocused(bool);
+
+ bool checked() const;
+ void setChecked(bool);
+
+ bool indeterminate() const;
+ void setIndeterminate(bool);
+
+ float progress() const;
+ void setProgress(float);
+
+private:
+ HTMLDataGridCellElement(const QualifiedName&, Document*);
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // HTMLDataGridCellElement_h
diff --git a/Source/WebCore/html/HTMLDataGridCellElement.idl b/Source/WebCore/html/HTMLDataGridCellElement.idl
new file mode 100644
index 0000000..1064cf7
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataGridCellElement.idl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ * 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 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.
+ */
+
+module html {
+
+ interface [
+ Conditional=DATAGRID
+ ] HTMLDataGridCellElement : HTMLElement {
+ attribute DOMString label; // The text to display in the column, assuming the type supports text.
+
+ attribute boolean focused; // Whether or not this cell is currently focused.
+
+ attribute boolean checked; // The checked state of the column, assuming the type of the column is checkbox.
+ attribute boolean indeterminate; // If the checked state is indeterminate.
+
+ attribute float progress; // For progress cells, a value from 0-1.0 indicating the state of progress.
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLDataGridColElement.cpp b/Source/WebCore/html/HTMLDataGridColElement.cpp
new file mode 100644
index 0000000..196c7b6
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataGridColElement.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 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 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(DATAGRID)
+
+#include "Attribute.h"
+#include "DataGridColumn.h"
+#include "HTMLDataGridColElement.h"
+#include "HTMLDataGridElement.h"
+#include "HTMLNames.h"
+#include "Text.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLDataGridColElement::HTMLDataGridColElement(const QualifiedName& name, Document* document)
+ : HTMLElement(name, document)
+ , m_dataGrid(0)
+{
+}
+
+PassRefPtr<HTMLDataGridColElement> HTMLDataGridColElement::create(const QualifiedName& name, Document* document)
+{
+ return adoptRef(new HTMLDataGridColElement(name, document));
+}
+
+HTMLDataGridElement* HTMLDataGridColElement::findDataGridAncestor() const
+{
+ if (parent() && parent()->hasTagName(datagridTag))
+ return static_cast<HTMLDataGridElement*>(parent());
+ return 0;
+}
+
+void HTMLDataGridColElement::ensureColumn()
+{
+ if (m_column)
+ return;
+ m_column = DataGridColumn::create(getIdAttribute(), label(), type(), primary(), sortable());
+}
+
+void HTMLDataGridColElement::insertedIntoTree(bool deep)
+{
+ HTMLElement::insertedIntoTree(deep);
+ if (dataGrid()) // We're connected to a datagrid already.
+ return;
+ m_dataGrid = findDataGridAncestor();
+ if (dataGrid() && dataGrid()->dataSource()->isDOMDataGridDataSource()) {
+ ensureColumn();
+ m_dataGrid->columns()->add(column()); // FIXME: Deal with ordering issues (complicated, since columns can be made outside the DOM).
+ }
+}
+
+void HTMLDataGridColElement::removedFromTree(bool deep)
+{
+ HTMLElement::removedFromTree(deep);
+ if (dataGrid() && dataGrid()->dataSource()->isDOMDataGridDataSource()) {
+ HTMLDataGridElement* grid = findDataGridAncestor();
+ if (!grid && column()) {
+ dataGrid()->columns()->remove(column());
+ m_dataGrid = 0;
+ }
+ }
+}
+
+String HTMLDataGridColElement::label() const
+{
+ return getAttribute(labelAttr);
+}
+
+void HTMLDataGridColElement::setLabel(const String& label)
+{
+ setAttribute(labelAttr, label);
+}
+
+String HTMLDataGridColElement::type() const
+{
+ return getAttribute(typeAttr);
+}
+
+void HTMLDataGridColElement::setType(const String& type)
+{
+ setAttribute(typeAttr, type);
+}
+
+unsigned short HTMLDataGridColElement::sortable() const
+{
+ if (!hasAttribute(sortableAttr))
+ return 2;
+ return getAttribute(sortableAttr).toInt(0);
+}
+
+void HTMLDataGridColElement::setSortable(unsigned short sortable)
+{
+ setAttribute(sortableAttr, String::number(sortable));
+}
+
+unsigned short HTMLDataGridColElement::sortDirection() const
+{
+ String sortDirection = getAttribute(sortdirectionAttr);
+ if (equalIgnoringCase(sortDirection, "ascending"))
+ return 1;
+ if (equalIgnoringCase(sortDirection, "descending"))
+ return 2;
+ return 0;
+}
+
+void HTMLDataGridColElement::setSortDirection(unsigned short sortDirection)
+{
+ // FIXME: Check sortable rules.
+ if (sortDirection == 0)
+ setAttribute(sortdirectionAttr, "natural");
+ else if (sortDirection == 1)
+ setAttribute(sortdirectionAttr, "ascending");
+ else if (sortDirection == 2)
+ setAttribute(sortdirectionAttr, "descending");
+}
+
+bool HTMLDataGridColElement::primary() const
+{
+ return hasAttribute(primaryAttr);
+}
+
+void HTMLDataGridColElement::setPrimary(bool primary)
+{
+ setAttribute(primaryAttr, primary ? "" : 0);
+}
+
+void HTMLDataGridColElement::parseMappedAttribute(Attribute* attr)
+{
+ HTMLElement::parseMappedAttribute(attr);
+
+ if (!column())
+ return;
+
+ if (attr->name() == labelAttr)
+ column()->setLabel(label());
+ else if (attr->name() == typeAttr)
+ column()->setType(type());
+ else if (attr->name() == primaryAttr)
+ column()->setPrimary(primary());
+ else if (attr->name() == sortableAttr)
+ column()->setSortable(sortable());
+ else if (attr->name() == sortdirectionAttr)
+ column()->setSortDirection(sortDirection());
+ else if (isIdAttributeName(attr->name()))
+ column()->setId(getIdAttribute());
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/HTMLDataGridColElement.h b/Source/WebCore/html/HTMLDataGridColElement.h
new file mode 100644
index 0000000..5198190
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataGridColElement.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 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 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 HTMLDataGridColElement_h
+#define HTMLDataGridColElement_h
+
+#if ENABLE(DATAGRID)
+
+#include "DataGridColumn.h"
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLDataGridElement;
+
+class HTMLDataGridColElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLDataGridColElement> create(const QualifiedName&, Document*);
+
+ String label() const;
+ void setLabel(const String&);
+
+ String type() const;
+ void setType(const String&);
+
+ unsigned short sortable() const;
+ void setSortable(unsigned short);
+
+ unsigned short sortDirection() const;
+ void setSortDirection(unsigned short);
+
+ bool primary() const;
+ void setPrimary(bool);
+
+ DataGridColumn* column() const { return m_column.get(); }
+ void setColumn(PassRefPtr<DataGridColumn> col) { m_column = col; }
+
+private:
+ HTMLDataGridColElement(const QualifiedName&, Document*);
+
+ virtual void insertedIntoTree(bool /*deep*/);
+ virtual void removedFromTree(bool /*deep*/);
+ virtual void parseMappedAttribute(Attribute*);
+
+ HTMLDataGridElement* dataGrid() const { return m_dataGrid; }
+ HTMLDataGridElement* findDataGridAncestor() const;
+ void ensureColumn();
+
+ RefPtr<DataGridColumn> m_column;
+ HTMLDataGridElement* m_dataGrid; // Not refcounted. We will null out our reference if we get removed from the grid.
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // HTMLDataGridColElement_h
diff --git a/Source/WebCore/html/HTMLDataGridColElement.idl b/Source/WebCore/html/HTMLDataGridColElement.idl
new file mode 100644
index 0000000..7a67c7e
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataGridColElement.idl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ * 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 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.
+ */
+
+module html {
+
+ interface [
+ Conditional=DATAGRID
+ ] HTMLDataGridColElement : HTMLElement {
+ attribute DOMString label; // The text to display in the column.
+ attribute DOMString type; // The type of data displayed in this column.
+
+ attribute unsigned short sortable; // Whether or not the column can be sorted. Values are none, ascending/descending, and ascending/descending/na
+ attribute unsigned short sortDirection; // The sort direction for the column. Valid values are ascending, descending and natural (no sort applied).
+
+ attribute boolean primary; // Whether or not this is the primary column of the tree (this will be where the disclosure triangle and connecting tree lines will display)
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLDataGridElement.cpp b/Source/WebCore/html/HTMLDataGridElement.cpp
new file mode 100644
index 0000000..d9ffa27
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataGridElement.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 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 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(DATAGRID)
+
+#include "HTMLDataGridElement.h"
+
+#include "DOMDataGridDataSource.h"
+#include "HTMLNames.h"
+#include "RenderDataGrid.h"
+#include "Text.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLDataGridElement::HTMLDataGridElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , m_columns(DataGridColumnList::create(this))
+{
+ setDataSource(DOMDataGridDataSource::create());
+}
+
+PassRefPtr<HTMLDataGridElement> HTMLDataGridElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLDataGridElement(tagName, document));
+}
+
+HTMLDataGridElement::~HTMLDataGridElement()
+{
+ m_columns->clearDataGrid();
+}
+
+RenderObject* HTMLDataGridElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderDataGrid(this);
+}
+
+bool HTMLDataGridElement::autofocus() const
+{
+ return hasAttribute(autofocusAttr);
+}
+
+void HTMLDataGridElement::setAutofocus(bool autofocus)
+{
+ setAttribute(autofocusAttr, autofocus ? "" : 0);
+}
+
+bool HTMLDataGridElement::disabled() const
+{
+ return hasAttribute(disabledAttr);
+}
+
+void HTMLDataGridElement::setDisabled(bool disabled)
+{
+ setAttribute(disabledAttr, disabled ? "" : 0);
+}
+
+bool HTMLDataGridElement::multiple() const
+{
+ return hasAttribute(multipleAttr);
+}
+
+void HTMLDataGridElement::setMultiple(bool multiple)
+{
+ setAttribute(multipleAttr, multiple ? "" : 0);
+}
+
+void HTMLDataGridElement::setDataSource(PassRefPtr<DataGridDataSource> ds)
+{
+ if (m_dataSource == ds)
+ return;
+
+ RefPtr<DataGridDataSource> dataSource = ds;
+ if (!dataSource)
+ dataSource = DOMDataGridDataSource::create();
+ m_dataSource = dataSource;
+
+ // Always clear our columns when a data source changes.
+ // The register callback will rebuild the columns.
+ m_columns->clear();
+}
+
+DataGridDataSource* HTMLDataGridElement::dataSource() const
+{
+ ASSERT(m_dataSource);
+ return m_dataSource.get();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DATAGRID)
diff --git a/Source/WebCore/html/HTMLDataGridElement.h b/Source/WebCore/html/HTMLDataGridElement.h
new file mode 100644
index 0000000..c594623
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataGridElement.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 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 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 HTMLDataGridElement_h
+#define HTMLDataGridElement_h
+
+#if ENABLE(DATAGRID)
+
+#include "DataGridColumnList.h"
+#include "DataGridDataSource.h"
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLDataGridElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLDataGridElement> create(const QualifiedName&, Document*);
+ virtual ~HTMLDataGridElement();
+
+ bool autofocus() const;
+ void setAutofocus(bool);
+
+ bool disabled() const;
+ void setDisabled(bool);
+
+ bool multiple() const;
+ void setMultiple(bool);
+
+ void setDataSource(PassRefPtr<DataGridDataSource>);
+ DataGridDataSource* dataSource() const;
+
+ DataGridColumnList* columns() const { return m_columns.get(); }
+
+private:
+ HTMLDataGridElement(const QualifiedName&, Document*);
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ RefPtr<DataGridDataSource> m_dataSource;
+ RefPtr<DataGridColumnList> m_columns;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // HTMLDataGridElement_h
diff --git a/Source/WebCore/html/HTMLDataGridElement.idl b/Source/WebCore/html/HTMLDataGridElement.idl
new file mode 100644
index 0000000..e9a800b
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataGridElement.idl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ * 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 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.
+ */
+
+module html {
+
+ interface [
+ Conditional=DATAGRID
+ ] HTMLDataGridElement : HTMLElement {
+ attribute [Custom] DataGridDataSource dataSource;
+
+ readonly attribute DataGridColumnList columns;
+
+ attribute boolean autofocus; // Whether or not the datagrid should autofocus.
+ attribute boolean disabled; // Whether or not the datagrid can be interacted with.
+ attribute boolean multiple; // Whether or not the datagrid supports multiple selection.
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLDataGridRowElement.cpp b/Source/WebCore/html/HTMLDataGridRowElement.cpp
new file mode 100644
index 0000000..74c88ba
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataGridRowElement.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 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 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(DATAGRID)
+
+#include "HTMLDataGridRowElement.h"
+
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLDataGridRowElement::HTMLDataGridRowElement(const QualifiedName& name, Document* document)
+ : HTMLElement(name, document)
+{
+}
+
+PassRefPtr<HTMLDataGridRowElement> HTMLDataGridRowElement::create(const QualifiedName& name, Document* document)
+{
+ return adoptRef(new HTMLDataGridRowElement(name, document));
+}
+
+bool HTMLDataGridRowElement::selected() const
+{
+ return hasAttribute(selectedAttr);
+}
+
+void HTMLDataGridRowElement::setSelected(bool selected)
+{
+ setAttribute(selectedAttr, selected ? "" : 0);
+}
+
+bool HTMLDataGridRowElement::focused() const
+{
+ return hasAttribute(focusedAttr);
+}
+
+void HTMLDataGridRowElement::setFocused(bool focused)
+{
+ setAttribute(focusedAttr, focused ? "" : 0);
+}
+
+bool HTMLDataGridRowElement::expanded() const
+{
+ return hasAttribute(expandedAttr);
+}
+
+void HTMLDataGridRowElement::setExpanded(bool expanded)
+{
+ setAttribute(expandedAttr, expanded ? "" : 0);
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/HTMLDataGridRowElement.h b/Source/WebCore/html/HTMLDataGridRowElement.h
new file mode 100644
index 0000000..3ee5bc6
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataGridRowElement.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 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 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 HTMLDataGridRowElement_h
+#define HTMLDataGridRowElement_h
+
+#if ENABLE(DATAGRID)
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLDataGridRowElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLDataGridRowElement> create(const QualifiedName&, Document*);
+
+ bool selected() const;
+ void setSelected(bool);
+
+ bool focused() const;
+ void setFocused(bool);
+
+ bool expanded() const;
+ void setExpanded(bool);
+
+private:
+ HTMLDataGridRowElement(const QualifiedName&, Document*);
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // HTMLDataGridRowElement_h
diff --git a/Source/WebCore/html/HTMLDataGridRowElement.idl b/Source/WebCore/html/HTMLDataGridRowElement.idl
new file mode 100644
index 0000000..7b3e68f
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataGridRowElement.idl
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ * 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 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.
+ */
+
+module html {
+
+ interface [
+ Conditional=DATAGRID
+ ] HTMLDataGridRowElement : HTMLElement {
+ attribute boolean selected; // Whether or not the row is currently selected.
+ attribute boolean focused; // Whether or not the row is the current object in the tree for keyboard navigation (or as the principal item of a multiple selection).
+
+ attribute boolean expanded; // Whether or not the row is open (if it is, child rows will be shown).
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLDataListElement.cpp b/Source/WebCore/html/HTMLDataListElement.cpp
new file mode 100644
index 0000000..b73606d
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataListElement.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 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:
+ *
+ * * 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(DATALIST)
+#include "HTMLDataListElement.h"
+
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+inline HTMLDataListElement::HTMLDataListElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+}
+
+PassRefPtr<HTMLDataListElement> HTMLDataListElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLDataListElement(tagName, document));
+}
+
+PassRefPtr<HTMLCollection> HTMLDataListElement::options()
+{
+ return HTMLCollection::create(this, DataListOptions);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DATALIST)
diff --git a/Source/WebCore/html/HTMLDataListElement.h b/Source/WebCore/html/HTMLDataListElement.h
new file mode 100644
index 0000000..97e608f
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataListElement.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009, Google Inc. All rights reserved.
+ * Copyright (C) 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:
+ *
+ * * 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 HTMLDataListElement_h
+#define HTMLDataListElement_h
+
+#if ENABLE(DATALIST)
+
+#include "HTMLCollection.h"
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLDataListElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLDataListElement> create(const QualifiedName&, Document*);
+
+ PassRefPtr<HTMLCollection> options();
+
+private:
+ HTMLDataListElement(const QualifiedName&, Document*);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(DATALIST)
+
+#endif // HTMLDataListElement_h
diff --git a/Source/WebCore/html/HTMLDataListElement.idl b/Source/WebCore/html/HTMLDataListElement.idl
new file mode 100644
index 0000000..a971fa7
--- /dev/null
+++ b/Source/WebCore/html/HTMLDataListElement.idl
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=DATALIST
+ ] HTMLDataListElement : HTMLElement {
+ readonly attribute HTMLCollection options;
+ };
+}
diff --git a/Source/WebCore/html/HTMLDetailsElement.cpp b/Source/WebCore/html/HTMLDetailsElement.cpp
new file mode 100644
index 0000000..0bcae0b
--- /dev/null
+++ b/Source/WebCore/html/HTMLDetailsElement.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLDetailsElement.h"
+
+#include "HTMLNames.h"
+#include "RenderDetails.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+PassRefPtr<HTMLDetailsElement> HTMLDetailsElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLDetailsElement(tagName, document));
+}
+
+HTMLDetailsElement::HTMLDetailsElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(detailsTag));
+}
+
+RenderObject* HTMLDetailsElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderDetails(this);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLDetailsElement.h b/Source/WebCore/html/HTMLDetailsElement.h
new file mode 100644
index 0000000..16427ef
--- /dev/null
+++ b/Source/WebCore/html/HTMLDetailsElement.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLDetailsElement_h
+#define HTMLDetailsElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLDetailsElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLDetailsElement> create(const QualifiedName& tagName, Document* document);
+
+private:
+ HTMLDetailsElement(const QualifiedName&, Document*);
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+};
+
+} // namespace WebCore
+
+#endif // HTMLDetailsElement_h
diff --git a/Source/WebCore/html/HTMLDetailsElement.idl b/Source/WebCore/html/HTMLDetailsElement.idl
new file mode 100644
index 0000000..5ad9508
--- /dev/null
+++ b/Source/WebCore/html/HTMLDetailsElement.idl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLDetailsElement : HTMLElement {
+ attribute [Reflect] boolean open;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLDirectoryElement.cpp b/Source/WebCore/html/HTMLDirectoryElement.cpp
new file mode 100644
index 0000000..64cbef8
--- /dev/null
+++ b/Source/WebCore/html/HTMLDirectoryElement.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLDirectoryElement.h"
+
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLDirectoryElement::HTMLDirectoryElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(dirTag));
+}
+
+PassRefPtr<HTMLDirectoryElement> HTMLDirectoryElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLDirectoryElement(tagName, document));
+}
+
+}
diff --git a/Source/WebCore/html/HTMLDirectoryElement.h b/Source/WebCore/html/HTMLDirectoryElement.h
new file mode 100644
index 0000000..afd3876
--- /dev/null
+++ b/Source/WebCore/html/HTMLDirectoryElement.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLDirectoryElement_h
+#define HTMLDirectoryElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLDirectoryElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLDirectoryElement> create(const QualifiedName& tagName, Document*);
+
+private:
+ HTMLDirectoryElement(const QualifiedName&, Document*);
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLDirectoryElement.idl b/Source/WebCore/html/HTMLDirectoryElement.idl
new file mode 100644
index 0000000..b096974
--- /dev/null
+++ b/Source/WebCore/html/HTMLDirectoryElement.idl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLDirectoryElement : HTMLElement {
+ attribute [Reflect] boolean compact;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLDivElement.cpp b/Source/WebCore/html/HTMLDivElement.cpp
new file mode 100644
index 0000000..ca2a914
--- /dev/null
+++ b/Source/WebCore/html/HTMLDivElement.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLDivElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLDivElement::HTMLDivElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(divTag));
+}
+
+PassRefPtr<HTMLDivElement> HTMLDivElement::create(Document* document)
+{
+ return adoptRef(new HTMLDivElement(divTag, document));
+}
+
+PassRefPtr<HTMLDivElement> HTMLDivElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLDivElement(tagName, document));
+}
+
+bool HTMLDivElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == alignAttr) {
+ result = eBlock;
+ return false;
+ }
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLDivElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == alignAttr) {
+ String v = attr->value();
+ if (equalIgnoringCase(attr->value(), "middle") || equalIgnoringCase(attr->value(), "center"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitCenter);
+ else if (equalIgnoringCase(attr->value(), "left"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitLeft);
+ else if (equalIgnoringCase(attr->value(), "right"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitRight);
+ else
+ addCSSProperty(attr, CSSPropertyTextAlign, v);
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLDivElement.h b/Source/WebCore/html/HTMLDivElement.h
new file mode 100644
index 0000000..2e2b417
--- /dev/null
+++ b/Source/WebCore/html/HTMLDivElement.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLDivElement_h
+#define HTMLDivElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLDivElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLDivElement> create(Document*);
+ static PassRefPtr<HTMLDivElement> create(const QualifiedName&, Document*);
+
+protected:
+ HTMLDivElement(const QualifiedName&, Document*);
+
+private:
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+};
+
+} // namespace WebCore
+
+#endif // HTMLDivElement_h
diff --git a/Source/WebCore/html/HTMLDivElement.idl b/Source/WebCore/html/HTMLDivElement.idl
new file mode 100644
index 0000000..90fb84f
--- /dev/null
+++ b/Source/WebCore/html/HTMLDivElement.idl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLDivElement : HTMLElement {
+ attribute [Reflect] DOMString align;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLDocument.cpp b/Source/WebCore/html/HTMLDocument.cpp
new file mode 100644
index 0000000..84ad706
--- /dev/null
+++ b/Source/WebCore/html/HTMLDocument.cpp
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * Portions are Copyright (C) 2002 Netscape Communications Corporation.
+ * Other contributors: David Baron <dbaron@fas.harvard.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Alternatively, the document type parsing portions of this file may be used
+ * under the terms of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#include "config.h"
+#include "HTMLDocument.h"
+
+#include "CSSPropertyNames.h"
+#include "CSSStyleSelector.h"
+#include "CookieJar.h"
+#include "DocumentLoader.h"
+#include "DocumentType.h"
+#include "ExceptionCode.h"
+#include "FocusController.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameTree.h"
+#include "FrameView.h"
+#include "HashTools.h"
+#include "HTMLDocumentParser.h"
+#include "HTMLBodyElement.h"
+#include "HTMLElementFactory.h"
+#include "HTMLNames.h"
+#include "InspectorController.h"
+#include "KURL.h"
+#include "Page.h"
+#include "Settings.h"
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLDocument::HTMLDocument(Frame* frame, const KURL& url, const KURL& baseURL)
+ : Document(frame, url, false, true, baseURL)
+{
+ clearXMLVersion();
+}
+
+HTMLDocument::~HTMLDocument()
+{
+}
+
+int HTMLDocument::width()
+{
+ updateLayoutIgnorePendingStylesheets();
+ FrameView* frameView = view();
+ return frameView ? frameView->contentsWidth() : 0;
+}
+
+int HTMLDocument::height()
+{
+ updateLayoutIgnorePendingStylesheets();
+ FrameView* frameView = view();
+ return frameView ? frameView->contentsHeight() : 0;
+}
+
+String HTMLDocument::dir()
+{
+ HTMLElement* b = body();
+ if (!b)
+ return String();
+ return b->getAttribute(dirAttr);
+}
+
+void HTMLDocument::setDir(const String& value)
+{
+ HTMLElement* b = body();
+ if (b)
+ b->setAttribute(dirAttr, value);
+}
+
+String HTMLDocument::designMode() const
+{
+ return inDesignMode() ? "on" : "off";
+}
+
+void HTMLDocument::setDesignMode(const String& value)
+{
+ InheritedBool mode;
+ if (equalIgnoringCase(value, "on"))
+ mode = on;
+ else if (equalIgnoringCase(value, "off"))
+ mode = off;
+ else
+ mode = inherit;
+ Document::setDesignMode(mode);
+}
+
+Element* HTMLDocument::activeElement()
+{
+ if (Node* node = focusedNode())
+ if (node->isElementNode())
+ return static_cast<Element*>(node);
+ 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;
+}
+
+String HTMLDocument::bgColor()
+{
+ HTMLElement* b = body();
+ HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;
+
+ if (!bodyElement)
+ return String();
+ return bodyElement->bgColor();
+}
+
+void HTMLDocument::setBgColor(const String& value)
+{
+ HTMLElement* b = body();
+ HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;
+
+ if (bodyElement)
+ bodyElement->setBgColor(value);
+}
+
+String HTMLDocument::fgColor()
+{
+ HTMLElement* b = body();
+ HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;
+
+ if (!bodyElement)
+ return String();
+ return bodyElement->text();
+}
+
+void HTMLDocument::setFgColor(const String& value)
+{
+ HTMLElement* b = body();
+ HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;
+
+ if (bodyElement)
+ bodyElement->setText(value);
+}
+
+String HTMLDocument::alinkColor()
+{
+ HTMLElement* b = body();
+ HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;
+
+ if (!bodyElement)
+ return String();
+ return bodyElement->aLink();
+}
+
+void HTMLDocument::setAlinkColor(const String& value)
+{
+ HTMLElement* b = body();
+ HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;
+
+ if (bodyElement) {
+ // This check is a bit silly, but some benchmarks like to set the
+ // document's link colors over and over to the same value and we
+ // don't want to incur a style update each time.
+ if (bodyElement->aLink() != value)
+ bodyElement->setALink(value);
+ }
+}
+
+String HTMLDocument::linkColor()
+{
+ HTMLElement* b = body();
+ HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;
+
+ if (!bodyElement)
+ return String();
+ return bodyElement->link();
+}
+
+void HTMLDocument::setLinkColor(const String& value)
+{
+ HTMLElement* b = body();
+ HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;
+
+ if (bodyElement) {
+ // This check is a bit silly, but some benchmarks like to set the
+ // document's link colors over and over to the same value and we
+ // don't want to incur a style update each time.
+ if (bodyElement->link() != value)
+ bodyElement->setLink(value);
+ }
+}
+
+String HTMLDocument::vlinkColor()
+{
+ HTMLElement* b = body();
+ HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;
+
+ if (!bodyElement)
+ return String();
+ return bodyElement->vLink();
+}
+
+void HTMLDocument::setVlinkColor(const String& value)
+{
+ HTMLElement* b = body();
+ HTMLBodyElement* bodyElement = (b && b->hasTagName(bodyTag)) ? static_cast<HTMLBodyElement*>(b) : 0;
+
+ if (bodyElement) {
+ // This check is a bit silly, but some benchmarks like to set the
+ // document's link colors over and over to the same value and we
+ // don't want to incur a style update each time.
+ if (bodyElement->vLink() != value)
+ bodyElement->setVLink(value);
+ }
+}
+
+void HTMLDocument::captureEvents()
+{
+}
+
+void HTMLDocument::releaseEvents()
+{
+}
+
+PassRefPtr<DocumentParser> HTMLDocument::createParser()
+{
+ bool reportErrors = false;
+#if ENABLE(INSPECTOR)
+ if (Page* page = this->page())
+ reportErrors = page->inspectorController()->hasFrontend();
+#endif
+ return HTMLDocumentParser::create(this, reportErrors);
+}
+
+// --------------------------------------------------------------------------
+// not part of the DOM
+// --------------------------------------------------------------------------
+
+PassRefPtr<Element> HTMLDocument::createElement(const AtomicString& name, ExceptionCode& ec)
+{
+ if (!isValidName(name)) {
+ ec = INVALID_CHARACTER_ERR;
+ return 0;
+ }
+ return HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, name.lower(), xhtmlNamespaceURI), this, 0, false);
+}
+
+void HTMLDocument::addItemToMap(HashCountedSet<AtomicStringImpl*>& map, const AtomicString& name)
+{
+ if (name.isEmpty())
+ return;
+ map.add(name.impl());
+ if (Frame* f = frame())
+ f->script()->namedItemAdded(this, name);
+}
+
+void HTMLDocument::removeItemFromMap(HashCountedSet<AtomicStringImpl*>& map, const AtomicString& name)
+{
+ if (name.isEmpty())
+ return;
+ map.remove(name.impl());
+ if (Frame* f = frame())
+ f->script()->namedItemRemoved(this, name);
+}
+
+void HTMLDocument::addNamedItem(const AtomicString& name)
+{
+ addItemToMap(m_namedItemCounts, name);
+}
+
+void HTMLDocument::removeNamedItem(const AtomicString& name)
+{
+ removeItemFromMap(m_namedItemCounts, name);
+}
+
+void HTMLDocument::addExtraNamedItem(const AtomicString& name)
+{
+ addItemToMap(m_extraNamedItemCounts, name);
+}
+
+void HTMLDocument::removeExtraNamedItem(const AtomicString& name)
+{
+ removeItemFromMap(m_extraNamedItemCounts, name);
+}
+
+void HTMLDocument::setCompatibilityModeFromDoctype()
+{
+ // There are three possible compatibility modes:
+ // Quirks - quirks mode emulates WinIE and NS4. CSS parsing is also relaxed in this mode, e.g., unit types can
+ // be omitted from numbers.
+ // Limited Quirks - This mode is identical to no-quirks mode except for its treatment of line-height in the inline box model.
+ // No Quirks - no quirks apply. Web pages will obey the specifications to the letter.
+ DocumentType* docType = doctype();
+ if (!docType)
+ return;
+
+ // Check for Quirks Mode.
+ const String& publicId = docType->publicId();
+ if (docType->name() != "html"
+ || publicId.startsWith("+//Silmaril//dtd html Pro v0r11 19970101//", false)
+ || publicId.startsWith("-//AdvaSoft Ltd//DTD HTML 3.0 asWedit + extensions//", false)
+ || publicId.startsWith("-//AS//DTD HTML 3.0 asWedit + extensions//", false)
+ || publicId.startsWith("-//IETF//DTD HTML 2.0 Level 1//", false)
+ || publicId.startsWith("-//IETF//DTD HTML 2.0 Level 2//", false)
+ || publicId.startsWith("-//IETF//DTD HTML 2.0 Strict Level 1//", false)
+ || publicId.startsWith("-//IETF//DTD HTML 2.0 Strict Level 2//", false)
+ || publicId.startsWith("-//IETF//DTD HTML 2.0 Strict//", false)
+ || publicId.startsWith("-//IETF//DTD HTML 2.0//", false)
+ || publicId.startsWith("-//IETF//DTD HTML 2.1E//", false)
+ || publicId.startsWith("-//IETF//DTD HTML 3.0//", false)
+ || publicId.startsWith("-//IETF//DTD HTML 3.2 Final//", false)
+ || publicId.startsWith("-//IETF//DTD HTML 3.2//", false)
+ || publicId.startsWith("-//IETF//DTD HTML 3//", false)
+ || publicId.startsWith("-//IETF//DTD HTML Level 0//", false)
+ || publicId.startsWith("-//IETF//DTD HTML Level 1//", false)
+ || publicId.startsWith("-//IETF//DTD HTML Level 2//", false)
+ || publicId.startsWith("-//IETF//DTD HTML Level 3//", false)
+ || publicId.startsWith("-//IETF//DTD HTML Strict Level 0//", false)
+ || publicId.startsWith("-//IETF//DTD HTML Strict Level 1//", false)
+ || publicId.startsWith("-//IETF//DTD HTML Strict Level 2//", false)
+ || publicId.startsWith("-//IETF//DTD HTML Strict Level 3//", false)
+ || publicId.startsWith("-//IETF//DTD HTML Strict//", false)
+ || publicId.startsWith("-//IETF//DTD HTML//", false)
+ || publicId.startsWith("-//Metrius//DTD Metrius Presentational//", false)
+ || publicId.startsWith("-//Microsoft//DTD Internet Explorer 2.0 HTML Strict//", false)
+ || publicId.startsWith("-//Microsoft//DTD Internet Explorer 2.0 HTML//", false)
+ || publicId.startsWith("-//Microsoft//DTD Internet Explorer 2.0 Tables//", false)
+ || publicId.startsWith("-//Microsoft//DTD Internet Explorer 3.0 HTML Strict//", false)
+ || publicId.startsWith("-//Microsoft//DTD Internet Explorer 3.0 HTML//", false)
+ || publicId.startsWith("-//Microsoft//DTD Internet Explorer 3.0 Tables//", false)
+ || publicId.startsWith("-//Netscape Comm. Corp.//DTD HTML//", false)
+ || publicId.startsWith("-//Netscape Comm. Corp.//DTD Strict HTML//", false)
+ || publicId.startsWith("-//O'Reilly and Associates//DTD HTML 2.0//", false)
+ || publicId.startsWith("-//O'Reilly and Associates//DTD HTML Extended 1.0//", false)
+ || publicId.startsWith("-//O'Reilly and Associates//DTD HTML Extended Relaxed 1.0//", false)
+ || publicId.startsWith("-//SoftQuad Software//DTD HoTMetaL PRO 6.0::19990601::extensions to HTML 4.0//", false)
+ || publicId.startsWith("-//SoftQuad//DTD HoTMetaL PRO 4.0::19971010::extensions to HTML 4.0//", false)
+ || publicId.startsWith("-//Spyglass//DTD HTML 2.0 Extended//", false)
+ || publicId.startsWith("-//SQ//DTD HTML 2.0 HoTMetaL + extensions//", false)
+ || publicId.startsWith("-//Sun Microsystems Corp.//DTD HotJava HTML//", false)
+ || publicId.startsWith("-//Sun Microsystems Corp.//DTD HotJava Strict HTML//", false)
+ || publicId.startsWith("-//W3C//DTD HTML 3 1995-03-24//", false)
+ || publicId.startsWith("-//W3C//DTD HTML 3.2 Draft//", false)
+ || publicId.startsWith("-//W3C//DTD HTML 3.2 Final//", false)
+ || publicId.startsWith("-//W3C//DTD HTML 3.2//", false)
+ || publicId.startsWith("-//W3C//DTD HTML 3.2S Draft//", false)
+ || publicId.startsWith("-//W3C//DTD HTML 4.0 Frameset//", false)
+ || publicId.startsWith("-//W3C//DTD HTML 4.0 Transitional//", false)
+ || publicId.startsWith("-//W3C//DTD HTML Experimental 19960712//", false)
+ || publicId.startsWith("-//W3C//DTD HTML Experimental 970421//", false)
+ || publicId.startsWith("-//W3C//DTD W3 HTML//", false)
+ || publicId.startsWith("-//W3O//DTD W3 HTML 3.0//", false)
+ || equalIgnoringCase(publicId, "-//W3O//DTD W3 HTML Strict 3.0//EN//")
+ || publicId.startsWith("-//WebTechs//DTD Mozilla HTML 2.0//", false)
+ || publicId.startsWith("-//WebTechs//DTD Mozilla HTML//", false)
+ || equalIgnoringCase(publicId, "-/W3C/DTD HTML 4.0 Transitional/EN")
+ || equalIgnoringCase(publicId, "HTML")
+ || equalIgnoringCase(docType->systemId(), "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd")
+ || (docType->systemId().isEmpty() && publicId.startsWith("-//W3C//DTD HTML 4.01 Frameset//", false))
+ || (docType->systemId().isEmpty() && publicId.startsWith("-//W3C//DTD HTML 4.01 Transitional//", false))) {
+ setCompatibilityMode(QuirksMode);
+ return;
+ }
+
+ // Check for Limited Quirks Mode.
+ if (publicId.startsWith("-//W3C//DTD XHTML 1.0 Frameset//", false)
+ || publicId.startsWith("-//W3C//DTD XHTML 1.0 Transitional//", false)
+ || (!docType->systemId().isEmpty() && publicId.startsWith("-//W3C//DTD HTML 4.01 Frameset//", false))
+ || (!docType->systemId().isEmpty() && publicId.startsWith("-//W3C//DTD HTML 4.01 Transitional//", false))) {
+ setCompatibilityMode(LimitedQuirksMode);
+ return;
+ }
+
+ // Otherwise we are No Quirks Mode.
+ setCompatibilityMode(NoQuirksMode);
+ return;
+}
+
+void HTMLDocument::clear()
+{
+ // FIXME: This does nothing, and that seems unlikely to be correct.
+ // We've long had a comment saying that IE doesn't support this.
+ // But I do see it in the documentation for Mozilla.
+}
+
+bool HTMLDocument::isFrameSet() const
+{
+ HTMLElement* bodyElement = body();
+ return bodyElement && bodyElement->hasTagName(framesetTag);
+}
+
+#ifdef ANDROID_INSTRUMENT
+void* HTMLDocument::operator new(size_t size)
+{
+ return Node::operator new(size);
+}
+
+void* HTMLDocument::operator new[](size_t size)
+{
+ return Node::operator new[](size);
+}
+
+void HTMLDocument::operator delete(void* p, size_t size)
+{
+ Node::operator delete(p, size);
+}
+
+void HTMLDocument::operator delete[](void* p, size_t size)
+{
+ Node::operator delete[](p, size);
+}
+#endif
+
+}
diff --git a/Source/WebCore/html/HTMLDocument.h b/Source/WebCore/html/HTMLDocument.h
new file mode 100644
index 0000000..37edd87
--- /dev/null
+++ b/Source/WebCore/html/HTMLDocument.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2004, 2006, 2007, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLDocument_h
+#define HTMLDocument_h
+
+#include "CachedResourceClient.h"
+#include "Document.h"
+#include <wtf/HashCountedSet.h>
+#include <wtf/text/AtomicStringHash.h>
+
+namespace WebCore {
+
+class FrameView;
+class HTMLElement;
+
+class HTMLDocument : public Document, public CachedResourceClient {
+public:
+ static PassRefPtr<HTMLDocument> create(Frame* frame, const KURL& url, const KURL& baseURL = KURL())
+ {
+ return adoptRef(new HTMLDocument(frame, url, baseURL));
+ }
+ virtual ~HTMLDocument();
+
+ int width();
+ int height();
+
+ String dir();
+ void setDir(const String&);
+
+ String designMode() const;
+ void setDesignMode(const String&);
+
+ virtual void setCompatibilityModeFromDoctype();
+
+ Element* activeElement();
+ bool hasFocus();
+
+ String bgColor();
+ void setBgColor(const String&);
+ String fgColor();
+ void setFgColor(const String&);
+ String alinkColor();
+ void setAlinkColor(const String&);
+ String linkColor();
+ void setLinkColor(const String&);
+ String vlinkColor();
+ void setVlinkColor(const String&);
+
+ void clear();
+
+ void captureEvents();
+ void releaseEvents();
+
+ void addNamedItem(const AtomicString& name);
+ void removeNamedItem(const AtomicString& name);
+ bool hasNamedItem(AtomicStringImpl* name);
+
+ void addExtraNamedItem(const AtomicString& name);
+ void removeExtraNamedItem(const AtomicString& name);
+ bool hasExtraNamedItem(AtomicStringImpl* name);
+
+protected:
+ HTMLDocument(Frame* frame, const KURL& url, const KURL& baseURL = KURL());
+
+#ifdef ANDROID_INSTRUMENT
+ // Overridden to resolve the ambiguous
+ void* operator new(size_t size);
+ void* operator new[](size_t size);
+ void operator delete(void* p, size_t size);
+ void operator delete[](void* p, size_t size);
+#endif
+
+private:
+ virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&);
+
+ virtual bool isFrameSet() const;
+ virtual PassRefPtr<DocumentParser> createParser();
+
+ void addItemToMap(HashCountedSet<AtomicStringImpl*>&, const AtomicString&);
+ void removeItemFromMap(HashCountedSet<AtomicStringImpl*>&, const AtomicString&);
+
+ HashCountedSet<AtomicStringImpl*> m_namedItemCounts;
+ HashCountedSet<AtomicStringImpl*> m_extraNamedItemCounts;
+};
+
+inline bool HTMLDocument::hasNamedItem(AtomicStringImpl* name)
+{
+ ASSERT(name);
+ return m_namedItemCounts.contains(name);
+}
+
+inline bool HTMLDocument::hasExtraNamedItem(AtomicStringImpl* name)
+{
+ ASSERT(name);
+ return m_extraNamedItemCounts.contains(name);
+}
+
+} // namespace WebCore
+
+#endif // HTMLDocument_h
diff --git a/Source/WebCore/html/HTMLDocument.idl b/Source/WebCore/html/HTMLDocument.idl
new file mode 100644
index 0000000..9684373
--- /dev/null
+++ b/Source/WebCore/html/HTMLDocument.idl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ HasOverridingNameGetter
+ ] HTMLDocument : Document {
+ [Custom, NoCPPCustom] void open();
+ void close();
+ [Custom] void write(in DOMString text);
+ [Custom] void writeln(in DOMString text);
+
+ readonly attribute HTMLCollection embeds;
+ readonly attribute HTMLCollection plugins;
+ readonly attribute HTMLCollection scripts;
+
+ // Extensions
+
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ // FIXME: This should eventually be available (if they are wanted) for all languages.
+ attribute [Custom, Deletable] HTMLAllCollection all;
+#endif
+
+ void clear();
+
+ void captureEvents();
+ void releaseEvents();
+
+ readonly attribute long width;
+ readonly attribute long height;
+ attribute [ConvertNullToNullString] DOMString dir;
+ attribute [ConvertNullToNullString] DOMString designMode;
+ readonly attribute DOMString compatMode;
+
+ readonly attribute Element activeElement;
+ boolean hasFocus();
+
+ // Deprecated attributes
+ attribute [ConvertNullToNullString] DOMString bgColor;
+ attribute [ConvertNullToNullString] DOMString fgColor;
+ attribute [ConvertNullToNullString] DOMString alinkColor;
+ attribute [ConvertNullToNullString] DOMString linkColor;
+ attribute [ConvertNullToNullString] DOMString vlinkColor;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp
new file mode 100644
index 0000000..a504f75
--- /dev/null
+++ b/Source/WebCore/html/HTMLElement.cpp
@@ -0,0 +1,833 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "DocumentFragment.h"
+#include "Event.h"
+#include "EventListener.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
+#include "Frame.h"
+#include "HTMLBRElement.h"
+#include "HTMLCollection.h"
+#include "HTMLDocument.h"
+#include "HTMLElementFactory.h"
+#include "HTMLFormElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "RenderWordBreak.h"
+#include "ScriptEventListener.h"
+#include "Settings.h"
+#include "Text.h"
+#include "TextIterator.h"
+#include "markup.h"
+#include <wtf/StdLibExtras.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+using std::min;
+using std::max;
+
+PassRefPtr<HTMLElement> HTMLElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLElement(tagName, document));
+}
+
+String HTMLElement::nodeName() const
+{
+ // FIXME: Would be nice to have an atomicstring lookup based off uppercase
+ // chars that does not have to copy the string on a hit in the hash.
+ // FIXME: We should have a way to detect XHTML elements and replace the hasPrefix() check with it.
+ if (document()->isHTMLDocument() && !tagQName().hasPrefix())
+ return tagQName().localNameUpper();
+ return Element::nodeName();
+}
+
+bool HTMLElement::ieForbidsInsertHTML() const
+{
+ // FIXME: Supposedly IE disallows settting innerHTML, outerHTML
+ // and createContextualFragment on these tags. We have no tests to
+ // verify this however, so this list could be totally wrong.
+ // This list was moved from the previous endTagRequirement() implementation.
+ // 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 (hasLocalName(areaTag)
+ || hasLocalName(baseTag)
+ || hasLocalName(basefontTag)
+ || hasLocalName(brTag)
+ || hasLocalName(colTag)
+#if ENABLE(DATAGRID)
+ || hasLocalName(dcellTag)
+ || hasLocalName(dcolTag)
+#endif
+ || 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 (hasLocalName(canvasTag)) {
+ Settings* settings = document()->settings();
+ if (settings && settings->usesDashboardBackwardCompatibilityMode())
+ return true;
+ }
+#endif
+ return false;
+}
+
+bool HTMLElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == alignAttr
+ || attrName == contenteditableAttr
+ || attrName == hiddenAttr) {
+ result = eUniversal;
+ return false;
+ }
+ if (attrName == dirAttr) {
+ result = hasLocalName(bdoTag) ? eBDO : eUniversal;
+ return false;
+ }
+
+ return StyledElement::mapToEntry(attrName, result);
+}
+
+void HTMLElement::parseMappedAttribute(Attribute* attr)
+{
+ if (isIdAttributeName(attr->name()) || attr->name() == classAttr || attr->name() == styleAttr)
+ return StyledElement::parseMappedAttribute(attr);
+
+ String indexstring;
+ if (attr->name() == alignAttr) {
+ if (equalIgnoringCase(attr->value(), "middle"))
+ addCSSProperty(attr, CSSPropertyTextAlign, "center");
+ else
+ addCSSProperty(attr, CSSPropertyTextAlign, attr->value());
+ } else if (attr->name() == contenteditableAttr) {
+ setContentEditable(attr);
+ } else if (attr->name() == hiddenAttr) {
+ addCSSProperty(attr, CSSPropertyDisplay, CSSValueNone);
+ } else if (attr->name() == tabindexAttr) {
+ indexstring = getAttribute(tabindexAttr);
+ int tabindex = 0;
+ if (parseHTMLInteger(indexstring, tabindex)) {
+ // Clamp tabindex to the range of 'short' to match Firefox's behavior.
+ setTabIndexExplicitly(max(static_cast<int>(std::numeric_limits<short>::min()), min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
+ }
+ } else if (attr->name() == langAttr) {
+ // FIXME: Implement
+ } else if (attr->name() == dirAttr) {
+ addCSSProperty(attr, CSSPropertyDirection, attr->value());
+ addCSSProperty(attr, CSSPropertyUnicodeBidi, hasLocalName(bdoTag) ? CSSValueBidiOverride : CSSValueEmbed);
+ } else if (attr->name() == draggableAttr) {
+ const AtomicString& value = attr->value();
+ if (equalIgnoringCase(value, "true")) {
+ addCSSProperty(attr, CSSPropertyWebkitUserDrag, CSSValueElement);
+ addCSSProperty(attr, CSSPropertyWebkitUserSelect, CSSValueNone);
+ } else if (equalIgnoringCase(value, "false"))
+ addCSSProperty(attr, CSSPropertyWebkitUserDrag, CSSValueNone);
+ }
+// standard events
+ else if (attr->name() == onclickAttr) {
+ setAttributeEventListener(eventNames().clickEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == oncontextmenuAttr) {
+ setAttributeEventListener(eventNames().contextmenuEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ondblclickAttr) {
+ setAttributeEventListener(eventNames().dblclickEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onmousedownAttr) {
+ setAttributeEventListener(eventNames().mousedownEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onmousemoveAttr) {
+ setAttributeEventListener(eventNames().mousemoveEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onmouseoutAttr) {
+ setAttributeEventListener(eventNames().mouseoutEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onmouseoverAttr) {
+ setAttributeEventListener(eventNames().mouseoverEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onmouseupAttr) {
+ setAttributeEventListener(eventNames().mouseupEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onmousewheelAttr) {
+ setAttributeEventListener(eventNames().mousewheelEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onfocusAttr) {
+ setAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onfocusinAttr) {
+ setAttributeEventListener(eventNames().focusinEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onfocusoutAttr) {
+ setAttributeEventListener(eventNames().focusoutEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onblurAttr) {
+ setAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onkeydownAttr) {
+ setAttributeEventListener(eventNames().keydownEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onkeypressAttr) {
+ setAttributeEventListener(eventNames().keypressEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onkeyupAttr) {
+ setAttributeEventListener(eventNames().keyupEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onscrollAttr) {
+ setAttributeEventListener(eventNames().scrollEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onbeforecutAttr) {
+ setAttributeEventListener(eventNames().beforecutEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == oncutAttr) {
+ setAttributeEventListener(eventNames().cutEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onbeforecopyAttr) {
+ setAttributeEventListener(eventNames().beforecopyEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == oncopyAttr) {
+ setAttributeEventListener(eventNames().copyEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onbeforepasteAttr) {
+ setAttributeEventListener(eventNames().beforepasteEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onpasteAttr) {
+ setAttributeEventListener(eventNames().pasteEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ondragenterAttr) {
+ setAttributeEventListener(eventNames().dragenterEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ondragoverAttr) {
+ setAttributeEventListener(eventNames().dragoverEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ondragleaveAttr) {
+ setAttributeEventListener(eventNames().dragleaveEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ondropAttr) {
+ setAttributeEventListener(eventNames().dropEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ondragstartAttr) {
+ setAttributeEventListener(eventNames().dragstartEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ondragAttr) {
+ setAttributeEventListener(eventNames().dragEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ondragendAttr) {
+ setAttributeEventListener(eventNames().dragendEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onselectstartAttr) {
+ setAttributeEventListener(eventNames().selectstartEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onsubmitAttr) {
+ setAttributeEventListener(eventNames().submitEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onerrorAttr) {
+ setAttributeEventListener(eventNames().errorEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onwebkitanimationstartAttr) {
+ setAttributeEventListener(eventNames().webkitAnimationStartEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onwebkitanimationiterationAttr) {
+ setAttributeEventListener(eventNames().webkitAnimationIterationEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onwebkitanimationendAttr) {
+ setAttributeEventListener(eventNames().webkitAnimationEndEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onwebkittransitionendAttr) {
+ setAttributeEventListener(eventNames().webkitTransitionEndEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == oninputAttr) {
+ setAttributeEventListener(eventNames().inputEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == oninvalidAttr) {
+ setAttributeEventListener(eventNames().invalidEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ontouchstartAttr) {
+ setAttributeEventListener(eventNames().touchstartEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ontouchmoveAttr) {
+ setAttributeEventListener(eventNames().touchmoveEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ontouchendAttr) {
+ setAttributeEventListener(eventNames().touchendEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ontouchcancelAttr) {
+ setAttributeEventListener(eventNames().touchcancelEvent, createAttributeEventListener(this, attr));
+#if ENABLE(FULLSCREEN_API)
+ } else if (attr->name() == onwebkitfullscreenchangeAttr) {
+ setAttributeEventListener(eventNames().webkitfullscreenchangeEvent, createAttributeEventListener(this, attr));
+#endif
+ }
+}
+
+String HTMLElement::innerHTML() const
+{
+ return createMarkup(this, ChildrenOnly);
+}
+
+String HTMLElement::outerHTML() const
+{
+ return createMarkup(this);
+}
+
+// FIXME: This logic should move into Range::createContextualFragment
+PassRefPtr<DocumentFragment> HTMLElement::deprecatedCreateContextualFragment(const String& markup, FragmentScriptingPermission scriptingPermission)
+{
+ // The following is in accordance with the definition as used by IE.
+ if (ieForbidsInsertHTML())
+ return 0;
+
+ if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag)
+ || hasLocalName(headTag) || hasLocalName(styleTag) || hasLocalName(titleTag))
+ return 0;
+
+ return Element::deprecatedCreateContextualFragment(markup, scriptingPermission);
+}
+
+static inline bool hasOneChild(ContainerNode* node)
+{
+ Node* firstChild = node->firstChild();
+ return firstChild && !firstChild->nextSibling();
+}
+
+static inline bool hasOneTextChild(ContainerNode* node)
+{
+ return hasOneChild(node) && node->firstChild()->isTextNode();
+}
+
+static void replaceChildrenWithFragment(HTMLElement* element, PassRefPtr<DocumentFragment> fragment, ExceptionCode& ec)
+{
+ if (!fragment->firstChild()) {
+ element->removeChildren();
+ return;
+ }
+
+ if (hasOneTextChild(element) && hasOneTextChild(fragment.get())) {
+ static_cast<Text*>(element->firstChild())->setData(static_cast<Text*>(fragment->firstChild())->data(), ec);
+ return;
+ }
+
+ if (hasOneChild(element)) {
+ element->replaceChild(fragment, element->firstChild(), ec);
+ return;
+ }
+
+ element->removeChildren();
+ element->appendChild(fragment, ec);
+}
+
+static void replaceChildrenWithText(HTMLElement* element, const String& text, ExceptionCode& ec)
+{
+ if (hasOneTextChild(element)) {
+ static_cast<Text*>(element->firstChild())->setData(text, ec);
+ return;
+ }
+
+ RefPtr<Text> textNode = Text::create(element->document(), text);
+
+ if (hasOneChild(element)) {
+ element->replaceChild(textNode.release(), element->firstChild(), ec);
+ return;
+ }
+
+ element->removeChildren();
+ element->appendChild(textNode.release(), ec);
+}
+
+// We may want to move a version of this function into DocumentFragment.h/cpp
+static PassRefPtr<DocumentFragment> createFragmentFromSource(const String& markup, Element* contextElement, ExceptionCode& ec)
+{
+ Document* document = contextElement->document();
+ RefPtr<DocumentFragment> fragment;
+
+ fragment = DocumentFragment::create(document);
+ if (document->isHTMLDocument()) {
+ fragment->parseHTML(markup, contextElement);
+ return fragment;
+ }
+
+ bool wasValid = fragment->parseXML(markup, contextElement);
+ if (!wasValid) {
+ ec = INVALID_STATE_ERR;
+ return 0;
+ }
+ return fragment;
+}
+
+void HTMLElement::setInnerHTML(const String& html, ExceptionCode& ec)
+{
+ RefPtr<DocumentFragment> fragment = createFragmentFromSource(html, this, ec);
+ if (fragment)
+ replaceChildrenWithFragment(this, fragment.release(), ec);
+}
+
+void HTMLElement::setOuterHTML(const String& html, ExceptionCode& ec)
+{
+ Node* p = parentNode();
+ if (!p || !p->isHTMLElement()) {
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+ return;
+ }
+ HTMLElement* parent = static_cast<HTMLElement*>(p);
+
+ RefPtr<DocumentFragment> fragment = createFragmentFromSource(html, parent, ec);
+ if (fragment) {
+ // FIXME: Why doesn't this have code to merge neighboring text nodes the way setOuterText does?
+ parent->replaceChild(fragment.release(), this, ec);
+ }
+}
+
+void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
+{
+ if (ieForbidsInsertHTML()) {
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+ return;
+ }
+ 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;
+ }
+
+ // FIXME: This doesn't take whitespace collapsing into account at all.
+
+ if (!text.contains('\n') && !text.contains('\r')) {
+ if (text.isEmpty()) {
+ removeChildren();
+ return;
+ }
+ replaceChildrenWithText(this, text, ec);
+ return;
+ }
+
+ // FIXME: Do we need to be able to detect preserveNewline style even when there's no renderer?
+ // FIXME: Can the renderer be out of date here? Do we need to call updateStyleIfNeeded?
+ // For example, for the contents of textarea elements that are display:none?
+ RenderObject* r = renderer();
+ if (r && r->style()->preserveNewline()) {
+ if (!text.contains('\r')) {
+ replaceChildrenWithText(this, text, ec);
+ return;
+ }
+ String textWithConsistentLineBreaks = text;
+ textWithConsistentLineBreaks.replace("\r\n", "\n");
+ textWithConsistentLineBreaks.replace('\r', '\n');
+ replaceChildrenWithText(this, textWithConsistentLineBreaks, ec);
+ return;
+ }
+
+ // Add text nodes and <br> elements.
+ ec = 0;
+ RefPtr<DocumentFragment> fragment = DocumentFragment::create(document());
+ int lineStart = 0;
+ UChar prev = 0;
+ int length = text.length();
+ for (int i = 0; i < length; ++i) {
+ UChar c = text[i];
+ if (c == '\n' || c == '\r') {
+ if (i > lineStart) {
+ fragment->appendChild(Text::create(document(), text.substring(lineStart, i - lineStart)), ec);
+ if (ec)
+ return;
+ }
+ if (!(c == '\n' && i != 0 && prev == '\r')) {
+ fragment->appendChild(HTMLBRElement::create(document()), ec);
+ if (ec)
+ return;
+ }
+ lineStart = i + 1;
+ }
+ prev = c;
+ }
+ if (length > lineStart)
+ fragment->appendChild(Text::create(document(), text.substring(lineStart, length - lineStart)), ec);
+ replaceChildrenWithFragment(this, fragment.release(), ec);
+}
+
+void HTMLElement::setOuterText(const String &text, ExceptionCode& ec)
+{
+ if (ieForbidsInsertHTML()) {
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+ return;
+ }
+ 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;
+ }
+
+ ContainerNode* parent = parentNode();
+ if (!parent) {
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+ return;
+ }
+
+ // FIXME: This creates a new text node even when the text is empty.
+ // FIXME: This creates a single text node even when the text has CR and LF
+ // characters in it. Instead it should create <br> elements.
+ RefPtr<Text> t = Text::create(document(), text);
+ ec = 0;
+ parent->replaceChild(t, this, ec);
+ if (ec)
+ return;
+
+ // Is previous node a text node? If so, merge into it.
+ Node* prev = t->previousSibling();
+ if (prev && prev->isTextNode()) {
+ Text* textPrev = static_cast<Text*>(prev);
+ textPrev->appendData(t->data(), ec);
+ if (ec)
+ return;
+ t->remove(ec);
+ if (ec)
+ return;
+ t = textPrev;
+ }
+
+ // Is next node a text node? If so, merge it in.
+ Node* next = t->nextSibling();
+ if (next && next->isTextNode()) {
+ Text* textNext = static_cast<Text*>(next);
+ t->appendData(textNext->data(), ec);
+ if (ec)
+ return;
+ textNext->remove(ec);
+ if (ec)
+ return;
+ }
+}
+
+Node* HTMLElement::insertAdjacent(const String& where, Node* newChild, ExceptionCode& ec)
+{
+ // In Internet Explorer if the element has no parent and where is "beforeBegin" or "afterEnd",
+ // a document fragment is created and the elements appended in the correct order. This document
+ // fragment isn't returned anywhere.
+ //
+ // This is impossible for us to implement as the DOM tree does not allow for such structures,
+ // Opera also appears to disallow such usage.
+
+ if (equalIgnoringCase(where, "beforeBegin")) {
+ ContainerNode* parent = this->parentNode();
+ return (parent && parent->insertBefore(newChild, this, ec)) ? newChild : 0;
+ }
+
+ if (equalIgnoringCase(where, "afterBegin"))
+ return insertBefore(newChild, firstChild(), ec) ? newChild : 0;
+
+ if (equalIgnoringCase(where, "beforeEnd"))
+ return appendChild(newChild, ec) ? newChild : 0;
+
+ if (equalIgnoringCase(where, "afterEnd")) {
+ ContainerNode* parent = this->parentNode();
+ return (parent && parent->insertBefore(newChild, nextSibling(), ec)) ? newChild : 0;
+ }
+
+ // IE throws COM Exception E_INVALIDARG; this is the best DOM exception alternative.
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+}
+
+Element* HTMLElement::insertAdjacentElement(const String& where, Element* newChild, ExceptionCode& ec)
+{
+ if (!newChild) {
+ // IE throws COM Exception E_INVALIDARG; this is the best DOM exception alternative.
+ ec = TYPE_MISMATCH_ERR;
+ return 0;
+ }
+
+ Node* returnValue = insertAdjacent(where, newChild, ec);
+ ASSERT(!returnValue || returnValue->isElementNode());
+ return static_cast<Element*>(returnValue);
+}
+
+// Step 3 of http://www.whatwg.org/specs/web-apps/current-work/multipage/apis-in-html-documents.html#insertadjacenthtml()
+static Element* contextElementForInsertion(const String& where, Element* element, ExceptionCode& ec)
+{
+ if (equalIgnoringCase(where, "beforeBegin") || equalIgnoringCase(where, "afterEnd")) {
+ ContainerNode* parent = element->parentNode();
+ if (parent && parent->isDocumentNode()) {
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+ return 0;
+ }
+ ASSERT(!parent || parent->isElementNode());
+ return static_cast<Element*>(parent);
+ }
+ if (equalIgnoringCase(where, "afterBegin") || equalIgnoringCase(where, "beforeEnd"))
+ return element;
+ ec = SYNTAX_ERR;
+ return 0;
+}
+
+void HTMLElement::insertAdjacentHTML(const String& where, const String& markup, ExceptionCode& ec)
+{
+ RefPtr<DocumentFragment> fragment = document()->createDocumentFragment();
+ Element* contextElement = contextElementForInsertion(where, this, ec);
+ if (!contextElement)
+ return;
+
+ if (document()->isHTMLDocument())
+ fragment->parseHTML(markup, contextElement);
+ else {
+ if (!fragment->parseXML(markup, contextElement))
+ // FIXME: We should propagate a syntax error exception out here.
+ return;
+ }
+
+ insertAdjacent(where, fragment.get(), ec);
+}
+
+void HTMLElement::insertAdjacentText(const String& where, const String& text, ExceptionCode& ec)
+{
+ RefPtr<Text> textNode = document()->createTextNode(text);
+ insertAdjacent(where, textNode.get(), ec);
+}
+
+void HTMLElement::addHTMLAlignment(Attribute* attr)
+{
+ addHTMLAlignmentToStyledElement(this, attr);
+}
+
+void HTMLElement::addHTMLAlignmentToStyledElement(StyledElement* element, Attribute* attr)
+{
+ // Vertical alignment with respect to the current baseline of the text
+ // right or left means floating images.
+ int floatValue = CSSValueInvalid;
+ int verticalAlignValue = CSSValueInvalid;
+
+ const AtomicString& alignment = attr->value();
+ if (equalIgnoringCase(alignment, "absmiddle"))
+ verticalAlignValue = CSSValueMiddle;
+ else if (equalIgnoringCase(alignment, "absbottom"))
+ verticalAlignValue = CSSValueBottom;
+ else if (equalIgnoringCase(alignment, "left")) {
+ floatValue = CSSValueLeft;
+ verticalAlignValue = CSSValueTop;
+ } else if (equalIgnoringCase(alignment, "right")) {
+ floatValue = CSSValueRight;
+ verticalAlignValue = CSSValueTop;
+ } else if (equalIgnoringCase(alignment, "top"))
+ verticalAlignValue = CSSValueTop;
+ else if (equalIgnoringCase(alignment, "middle"))
+ verticalAlignValue = CSSValueWebkitBaselineMiddle;
+ else if (equalIgnoringCase(alignment, "center"))
+ verticalAlignValue = CSSValueMiddle;
+ else if (equalIgnoringCase(alignment, "bottom"))
+ verticalAlignValue = CSSValueBaseline;
+ else if (equalIgnoringCase(alignment, "texttop"))
+ verticalAlignValue = CSSValueTextTop;
+
+ if (floatValue != CSSValueInvalid)
+ element->addCSSProperty(attr, CSSPropertyFloat, floatValue);
+
+ if (verticalAlignValue != CSSValueInvalid)
+ element->addCSSProperty(attr, CSSPropertyVerticalAlign, verticalAlignValue);
+}
+
+bool HTMLElement::supportsFocus() const
+{
+ return Element::supportsFocus() || (isContentEditable() && parentNode() && !parentNode()->isContentEditable());
+}
+
+bool HTMLElement::isContentEditable() const
+{
+ if (document()->frame() && document()->frame()->isContentEditable())
+ return true;
+
+ // Ideally we'd call ASSERT!needsStyleRecalc()) here, but
+ // ContainerNode::setFocus() calls setNeedsStyleRecalc(), so the assertion
+ // would fire in the middle of Document::setFocusedNode().
+
+ if (!renderer()) {
+ if (parentNode())
+ return parentNode()->isContentEditable();
+ else
+ return false;
+ }
+
+ return renderer()->style()->userModify() == READ_WRITE || renderer()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY;
+}
+
+bool HTMLElement::isContentRichlyEditable() const
+{
+ if (document()->frame() && document()->frame()->isContentEditable())
+ return true;
+
+ if (!renderer()) {
+ if (parentNode())
+ return parentNode()->isContentEditable();
+ else
+ return false;
+ }
+
+ return renderer()->style()->userModify() == READ_WRITE;
+}
+
+String HTMLElement::contentEditable() const
+{
+ if (!renderer())
+ return "false";
+
+ switch (renderer()->style()->userModify()) {
+ case READ_WRITE:
+ return "true";
+ case READ_ONLY:
+ return "false";
+ case READ_WRITE_PLAINTEXT_ONLY:
+ return "plaintext-only";
+ default:
+ return "inherit";
+ }
+}
+
+void HTMLElement::setContentEditable(Attribute* attr)
+{
+ const AtomicString& enabled = attr->value();
+ if (enabled.isEmpty() || equalIgnoringCase(enabled, "true")) {
+ addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadWrite);
+ addCSSProperty(attr, CSSPropertyWordWrap, CSSValueBreakWord);
+ addCSSProperty(attr, CSSPropertyWebkitNbspMode, CSSValueSpace);
+ addCSSProperty(attr, CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);
+ } else if (equalIgnoringCase(enabled, "false")) {
+ addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadOnly);
+ attr->decl()->removeProperty(CSSPropertyWordWrap, false);
+ attr->decl()->removeProperty(CSSPropertyWebkitNbspMode, false);
+ attr->decl()->removeProperty(CSSPropertyWebkitLineBreak, false);
+ } else if (equalIgnoringCase(enabled, "inherit")) {
+ addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueInherit);
+ attr->decl()->removeProperty(CSSPropertyWordWrap, false);
+ attr->decl()->removeProperty(CSSPropertyWebkitNbspMode, false);
+ attr->decl()->removeProperty(CSSPropertyWebkitLineBreak, false);
+ } else if (equalIgnoringCase(enabled, "plaintext-only")) {
+ addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadWritePlaintextOnly);
+ addCSSProperty(attr, CSSPropertyWordWrap, CSSValueBreakWord);
+ addCSSProperty(attr, CSSPropertyWebkitNbspMode, CSSValueSpace);
+ addCSSProperty(attr, CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);
+ }
+}
+
+void HTMLElement::setContentEditable(const String &enabled)
+{
+ if (enabled == "inherit") {
+ ExceptionCode ec;
+ removeAttribute(contenteditableAttr, ec);
+ }
+ else
+ setAttribute(contenteditableAttr, enabled.isEmpty() ? "true" : enabled);
+}
+
+bool HTMLElement::draggable() const
+{
+ return equalIgnoringCase(getAttribute(draggableAttr), "true");
+}
+
+void HTMLElement::setDraggable(bool value)
+{
+ setAttribute(draggableAttr, value ? "true" : "false");
+}
+
+bool HTMLElement::spellcheck() const
+{
+ return isSpellCheckingEnabled();
+}
+
+void HTMLElement::setSpellcheck(bool enable)
+{
+ setAttribute(spellcheckAttr, enable ? "true" : "false");
+}
+
+
+void HTMLElement::click()
+{
+ dispatchSimulatedClick(0, false, false);
+}
+
+// accessKeyAction is used by the accessibility support code
+// to send events to elements that our JavaScript caller does
+// does not. The elements JS is interested in have subclasses
+// that override this method to direct the click appropriately.
+// Here in the base class, then, we only send the click if
+// the caller wants it to go to any HTMLElement, and we say
+// to send the mouse events in addition to the click.
+void HTMLElement::accessKeyAction(bool sendToAnyElement)
+{
+ if (sendToAnyElement)
+ dispatchSimulatedClick(0, true);
+}
+
+String HTMLElement::title() const
+{
+ return getAttribute(titleAttr);
+}
+
+short HTMLElement::tabIndex() const
+{
+ if (supportsFocus())
+ return Element::tabIndex();
+ return -1;
+}
+
+void HTMLElement::setTabIndex(int value)
+{
+ setAttribute(tabindexAttr, String::number(value));
+}
+
+PassRefPtr<HTMLCollection> HTMLElement::children()
+{
+ return HTMLCollection::create(this, NodeChildren);
+}
+
+bool HTMLElement::rendererIsNeeded(RenderStyle *style)
+{
+ if (hasLocalName(noscriptTag)) {
+ Frame* frame = document()->frame();
+#if ENABLE(XHTMLMP)
+ if (!document()->shouldProcessNoscriptElement())
+ return false;
+#else
+ if (frame && frame->script()->canExecuteScripts(NotAboutToExecuteScript))
+ return false;
+#endif
+ } else if (hasLocalName(noembedTag)) {
+ Frame* frame = document()->frame();
+ if (frame && frame->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin))
+ return false;
+ }
+ return StyledElement::rendererIsNeeded(style);
+}
+
+RenderObject* HTMLElement::createRenderer(RenderArena* arena, RenderStyle* style)
+{
+ if (hasLocalName(wbrTag))
+ return new (arena) RenderWordBreak(this);
+ return RenderObject::createObject(this, style);
+}
+
+HTMLFormElement* HTMLElement::findFormAncestor() const
+{
+ for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
+ if (ancestor->hasTagName(formTag))
+ return static_cast<HTMLFormElement*>(ancestor);
+ }
+ return 0;
+}
+
+HTMLFormElement* HTMLElement::virtualForm() const
+{
+ return findFormAncestor();
+}
+
+} // namespace WebCore
+
+#ifndef NDEBUG
+
+// For use in the debugger
+void dumpInnerHTML(WebCore::HTMLElement*);
+
+void dumpInnerHTML(WebCore::HTMLElement* element)
+{
+ printf("%s\n", element->innerHTML().ascii().data());
+}
+#endif
diff --git a/Source/WebCore/html/HTMLElement.h b/Source/WebCore/html/HTMLElement.h
new file mode 100644
index 0000000..63ce110
--- /dev/null
+++ b/Source/WebCore/html/HTMLElement.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLElement_h
+#define HTMLElement_h
+
+#include "StyledElement.h"
+
+namespace WebCore {
+
+class DocumentFragment;
+class HTMLCollection;
+class HTMLFormElement;
+
+class HTMLElement : public StyledElement {
+public:
+ static PassRefPtr<HTMLElement> create(const QualifiedName& tagName, Document*);
+
+ PassRefPtr<HTMLCollection> children();
+
+ virtual String title() const;
+
+ virtual short tabIndex() const;
+ void setTabIndex(int);
+
+ String innerHTML() const;
+ String outerHTML() const;
+ // deprecatedCreateContextualFragment logic should be moved into Range::createContextualFragment
+ PassRefPtr<DocumentFragment> deprecatedCreateContextualFragment(const String&, FragmentScriptingPermission = FragmentScriptingAllowed);
+ void setInnerHTML(const String&, ExceptionCode&);
+ void setOuterHTML(const String&, ExceptionCode&);
+ void setInnerText(const String&, ExceptionCode&);
+ void setOuterText(const String&, ExceptionCode&);
+
+ Element* insertAdjacentElement(const String& where, Element* newChild, ExceptionCode&);
+ void insertAdjacentHTML(const String& where, const String& html, ExceptionCode&);
+ void insertAdjacentText(const String& where, const String& text, ExceptionCode&);
+
+ virtual bool supportsFocus() const;
+
+ virtual bool isContentEditable() const;
+ virtual bool isContentRichlyEditable() const;
+
+ String contentEditable() const;
+ void setContentEditable(const String&);
+
+ virtual bool draggable() const;
+ void setDraggable(bool);
+
+ bool spellcheck() const;
+ void setSpellcheck(bool);
+
+ void click();
+
+ virtual void accessKeyAction(bool sendToAnyElement);
+
+ bool ieForbidsInsertHTML() const;
+
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ HTMLFormElement* form() const { return virtualForm(); }
+
+ static void addHTMLAlignmentToStyledElement(StyledElement*, Attribute*);
+
+ HTMLFormElement* findFormAncestor() const;
+
+protected:
+ HTMLElement(const QualifiedName& tagName, Document*);
+
+ void addHTMLAlignment(Attribute*);
+
+ virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+private:
+ virtual String nodeName() const;
+
+ void setContentEditable(Attribute*);
+
+ virtual HTMLFormElement* virtualForm() const;
+
+ Node* insertAdjacent(const String& where, Node* newChild, ExceptionCode&);
+};
+
+inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document* document)
+ : StyledElement(tagName, document, CreateHTMLElement)
+{
+ ASSERT(tagName.localName().impl());
+}
+
+} // namespace WebCore
+
+#endif // HTMLElement_h
diff --git a/Source/WebCore/html/HTMLElement.idl b/Source/WebCore/html/HTMLElement.idl
new file mode 100644
index 0000000..77423fc
--- /dev/null
+++ b/Source/WebCore/html/HTMLElement.idl
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ GenerateNativeConverter,
+ CustomPushEventHandlerScope
+ ] HTMLElement : Element {
+ // iht.com relies on id returning the empty string when no id is present.
+ // Other browsers do this as well. So we don't convert null to JS null.
+ attribute [Reflect] DOMString id;
+ attribute [Reflect] DOMString title;
+ attribute [Reflect] DOMString lang;
+ attribute [Reflect] DOMString dir;
+ attribute [Reflect=class] DOMString className;
+ readonly attribute DOMTokenList classList;
+
+ attribute long tabIndex;
+ attribute boolean draggable;
+ attribute [Reflect] boolean hidden;
+
+ // Extensions
+ attribute [ConvertNullToNullString] DOMString innerHTML
+ setter raises(DOMException);
+ attribute [ConvertNullToNullString] DOMString innerText
+ setter raises(DOMException);
+ attribute [ConvertNullToNullString] DOMString outerHTML
+ setter raises(DOMException);
+ attribute [ConvertNullToNullString] DOMString outerText
+ setter raises(DOMException);
+
+ Element insertAdjacentElement(in DOMString where,
+ in Element element)
+ raises(DOMException);
+ void insertAdjacentHTML(in DOMString where,
+ in DOMString html)
+ raises(DOMException);
+ void insertAdjacentText(in DOMString where,
+ in DOMString text)
+ raises(DOMException);
+
+ readonly attribute HTMLCollection children;
+
+ attribute [ConvertNullToNullString] DOMString contentEditable;
+ readonly attribute boolean isContentEditable;
+
+ attribute boolean spellcheck;
+
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+ readonly attribute DOMString titleDisplayString;
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLElementsAllInOne.cpp b/Source/WebCore/html/HTMLElementsAllInOne.cpp
new file mode 100644
index 0000000..785a94b
--- /dev/null
+++ b/Source/WebCore/html/HTMLElementsAllInOne.cpp
@@ -0,0 +1,110 @@
+/*
+ * 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.
+
+#include "HTMLAnchorElement.cpp"
+#include "HTMLAppletElement.cpp"
+#include "HTMLAreaElement.cpp"
+#include "HTMLAudioElement.cpp"
+#include "HTMLBRElement.cpp"
+#include "HTMLBaseElement.cpp"
+#include "HTMLBaseFontElement.cpp"
+#include "HTMLBlockquoteElement.cpp"
+#include "HTMLBodyElement.cpp"
+#include "HTMLButtonElement.cpp"
+#include "HTMLCanvasElement.cpp"
+#include "HTMLDataGridElement.cpp"
+#include "HTMLDataGridCellElement.cpp"
+#include "HTMLDataGridColElement.cpp"
+#include "HTMLDataGridRowElement.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 "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 "HTMLIsIndexElement.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 "HTMLNoScriptElement.cpp"
+#include "HTMLOListElement.cpp"
+#include "HTMLObjectElement.cpp"
+#include "HTMLOptGroupElement.cpp"
+#include "HTMLOptionElement.cpp"
+#include "HTMLParagraphElement.cpp"
+#include "HTMLParamElement.cpp"
+#include "HTMLPlugInElement.cpp"
+#include "HTMLPlugInImageElement.cpp"
+#include "HTMLPreElement.cpp"
+#include "HTMLProgressElement.cpp"
+#include "HTMLQuoteElement.cpp"
+#include "HTMLScriptElement.cpp"
+#include "HTMLSelectElement.cpp"
+#include "HTMLSourceElement.cpp"
+#include "HTMLStyleElement.cpp"
+#include "HTMLTableCaptionElement.cpp"
+#include "HTMLTableCellElement.cpp"
+#include "HTMLTableColElement.cpp"
+#include "HTMLTableElement.cpp"
+#include "HTMLTablePartElement.cpp"
+#include "HTMLTableRowElement.cpp"
+#include "HTMLTableSectionElement.cpp"
+#include "HTMLTextAreaElement.cpp"
+#include "HTMLTitleElement.cpp"
+#include "HTMLUListElement.cpp"
+#include "HTMLVideoElement.cpp"
diff --git a/Source/WebCore/html/HTMLEmbedElement.cpp b/Source/WebCore/html/HTMLEmbedElement.cpp
new file mode 100644
index 0000000..df97280
--- /dev/null
+++ b/Source/WebCore/html/HTMLEmbedElement.cpp
@@ -0,0 +1,275 @@
+/*
+ * 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, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLEmbedElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "DocumentLoader.h"
+#include "Frame.h"
+#include "HTMLDocument.h"
+#include "HTMLImageLoader.h"
+#include "HTMLNames.h"
+#include "HTMLObjectElement.h"
+#include "HTMLParserIdioms.h"
+#include "MainResourceLoader.h"
+#include "PluginDocument.h"
+#include "RenderEmbeddedObject.h"
+#include "RenderImage.h"
+#include "RenderWidget.h"
+#include "ScriptController.h"
+#include "Settings.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLEmbedElement::HTMLEmbedElement(const QualifiedName& tagName, Document* document, bool createdByParser)
+ : HTMLPlugInImageElement(tagName, document, createdByParser)
+{
+ ASSERT(hasTagName(embedTag));
+}
+
+PassRefPtr<HTMLEmbedElement> HTMLEmbedElement::create(const QualifiedName& tagName, Document* document, bool createdByParser)
+{
+ return adoptRef(new HTMLEmbedElement(tagName, document, createdByParser));
+}
+
+static inline RenderWidget* findWidgetRenderer(const Node* n)
+{
+ if (!n->renderer())
+ do
+ n = n->parentNode();
+ while (n && !n->hasTagName(objectTag));
+
+ if (n && n->renderer() && n->renderer()->isWidget())
+ return toRenderWidget(n->renderer());
+
+ return 0;
+}
+
+RenderWidget* HTMLEmbedElement::renderWidgetForJSBindings() const
+{
+ document()->updateLayoutIgnorePendingStylesheets();
+ return findWidgetRenderer(this);
+}
+
+bool HTMLEmbedElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == hiddenAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ return HTMLPlugInImageElement::mapToEntry(attrName, result);
+}
+
+void HTMLEmbedElement::parseMappedAttribute(Attribute* attr)
+{
+ const AtomicString& value = attr->value();
+
+ if (attr->name() == typeAttr) {
+ m_serviceType = value.string().lower();
+ size_t pos = m_serviceType.find(";");
+ if (pos != notFound)
+ m_serviceType = m_serviceType.left(pos);
+ if (!isImageType() && m_imageLoader)
+ m_imageLoader.clear();
+ } else if (attr->name() == codeAttr)
+ m_url = stripLeadingAndTrailingHTMLSpaces(value.string());
+ else if (attr->name() == srcAttr) {
+ m_url = stripLeadingAndTrailingHTMLSpaces(value.string());
+ if (renderer() && isImageType()) {
+ if (!m_imageLoader)
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader->updateFromElementIgnoringPreviousError();
+ }
+ } else if (attr->name() == hiddenAttr) {
+ if (equalIgnoringCase(value.string(), "yes") || equalIgnoringCase(value.string(), "true")) {
+ // FIXME: Not dynamic, since we add this but don't remove it, but it may be OK for now
+ // that this rarely-used attribute won't work properly if you remove it.
+ addCSSLength(attr, CSSPropertyWidth, "0");
+ addCSSLength(attr, CSSPropertyHeight, "0");
+ }
+ } else if (attr->name() == nameAttr) {
+ if (inDocument() && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->addNamedItem(value);
+ }
+ m_name = value;
+ } else
+ HTMLPlugInImageElement::parseMappedAttribute(attr);
+}
+
+void HTMLEmbedElement::parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues)
+{
+ NamedNodeMap* attributes = this->attributes(true);
+ if (!attributes)
+ return;
+
+ for (unsigned i = 0; i < attributes->length(); ++i) {
+ Attribute* it = attributes->attributeItem(i);
+ paramNames.append(it->localName().string());
+ paramValues.append(it->value().string());
+ }
+}
+
+// FIXME: This should be unified with HTMLObjectElement::updateWidget and
+// moved down into HTMLPluginImageElement.cpp
+void HTMLEmbedElement::updateWidget(bool onlyCreateNonNetscapePlugins)
+{
+ ASSERT(!renderEmbeddedObject()->pluginCrashedOrWasMissing());
+ // FIXME: We should ASSERT(needsWidgetUpdate()), but currently
+ // FrameView::updateWidget() calls updateWidget(false) without checking if
+ // the widget actually needs updating!
+ setNeedsWidgetUpdate(false);
+
+ if (m_url.isEmpty() && m_serviceType.isEmpty())
+ return;
+
+ // Note these pass m_url and m_serviceType to allow better code sharing with
+ // <object> which modifies url and serviceType before calling these.
+ if (!allowedToLoadFrameURL(m_url))
+ return;
+ if (onlyCreateNonNetscapePlugins && wouldLoadAsNetscapePlugin(m_url, m_serviceType))
+ return;
+
+ // FIXME: These should be joined into a PluginParameters class.
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+ parametersForPlugin(paramNames, paramValues);
+
+ ASSERT(!m_inBeforeLoadEventHandler);
+ m_inBeforeLoadEventHandler = true;
+ bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(m_url);
+ m_inBeforeLoadEventHandler = false;
+
+ if (!beforeLoadAllowedLoad) {
+ 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.
+ toPluginDocument(document())->cancelManualPluginLoad();
+ }
+ return;
+ }
+
+ SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
+ // FIXME: beforeLoad could have detached the renderer! Just like in the <object> case above.
+ loader->requestObject(this, m_url, getAttribute(nameAttr), m_serviceType, paramNames, paramValues);
+}
+
+bool HTMLEmbedElement::rendererIsNeeded(RenderStyle* style)
+{
+ if (isImageType())
+ return HTMLPlugInImageElement::rendererIsNeeded(style);
+
+ Frame* frame = document()->frame();
+ if (!frame)
+ return false;
+
+ // If my parent is an <object> and is not set to use fallback content, I
+ // should be ignored and not get a renderer.
+ ContainerNode* p = parentNode();
+ if (p && p->hasTagName(objectTag)) {
+ ASSERT(p->renderer());
+ if (!static_cast<HTMLObjectElement*>(p)->useFallbackContent()) {
+ ASSERT(!p->renderer()->isEmbeddedObject());
+ return false;
+ }
+ }
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ // Workaround for <rdar://problem/6642221>.
+ if (Settings* settings = frame->settings()) {
+ if (settings->usesDashboardBackwardCompatibilityMode())
+ return true;
+ }
+#endif
+
+ return HTMLPlugInImageElement::rendererIsNeeded(style);
+}
+
+void HTMLEmbedElement::insertedIntoDocument()
+{
+ if (document()->isHTMLDocument())
+ static_cast<HTMLDocument*>(document())->addNamedItem(m_name);
+
+ String width = getAttribute(widthAttr);
+ String height = getAttribute(heightAttr);
+ if (!width.isEmpty() || !height.isEmpty()) {
+ Node* n = parentNode();
+ while (n && !n->hasTagName(objectTag))
+ n = n->parentNode();
+ if (n) {
+ if (!width.isEmpty())
+ static_cast<HTMLObjectElement*>(n)->setAttribute(widthAttr, width);
+ if (!height.isEmpty())
+ static_cast<HTMLObjectElement*>(n)->setAttribute(heightAttr, height);
+ }
+ }
+
+ HTMLPlugInImageElement::insertedIntoDocument();
+}
+
+void HTMLEmbedElement::removedFromDocument()
+{
+ if (document()->isHTMLDocument())
+ static_cast<HTMLDocument*>(document())->removeNamedItem(m_name);
+
+ HTMLPlugInImageElement::removedFromDocument();
+}
+
+void HTMLEmbedElement::attributeChanged(Attribute* attr, bool preserveDecls)
+{
+ HTMLPlugInImageElement::attributeChanged(attr, preserveDecls);
+
+ if ((attr->name() == widthAttr || attr->name() == heightAttr) && !attr->isEmpty()) {
+ ContainerNode* n = parentNode();
+ while (n && !n->hasTagName(objectTag))
+ n = n->parentNode();
+ if (n)
+ static_cast<HTMLObjectElement*>(n)->setAttribute(attr->name(), attr->value());
+ }
+}
+
+bool HTMLEmbedElement::isURLAttribute(Attribute* attr) const
+{
+ return attr->name() == srcAttr;
+}
+
+const QualifiedName& HTMLEmbedElement::imageSourceAttributeName() const
+{
+ return srcAttr;
+}
+
+void HTMLEmbedElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+{
+ HTMLPlugInImageElement::addSubresourceAttributeURLs(urls);
+
+ addSubresourceURL(urls, document()->completeURL(getAttribute(srcAttr)));
+}
+
+}
diff --git a/Source/WebCore/html/HTMLEmbedElement.h b/Source/WebCore/html/HTMLEmbedElement.h
new file mode 100644
index 0000000..70eb0dc
--- /dev/null
+++ b/Source/WebCore/html/HTMLEmbedElement.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2004, 2006, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLEmbedElement_h
+#define HTMLEmbedElement_h
+
+#include "HTMLPlugInImageElement.h"
+
+namespace WebCore {
+
+class HTMLEmbedElement : public HTMLPlugInImageElement {
+public:
+ static PassRefPtr<HTMLEmbedElement> create(const QualifiedName&, Document*, bool createdByParser);
+
+private:
+ HTMLEmbedElement(const QualifiedName&, Document*, bool createdByParser);
+
+ virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+ virtual void attributeChanged(Attribute*, bool preserveDecls = false);
+
+ virtual bool isURLAttribute(Attribute*) const;
+ virtual const QualifiedName& imageSourceAttributeName() const;
+
+ virtual RenderWidget* renderWidgetForJSBindings() const;
+
+ virtual void updateWidget(bool onlyCreateNonNetscapePlugins);
+
+ virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+
+ void parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues);
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/HTMLEmbedElement.idl b/Source/WebCore/html/HTMLEmbedElement.idl
new file mode 100644
index 0000000..e395fc6
--- /dev/null
+++ b/Source/WebCore/html/HTMLEmbedElement.idl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ DelegatingPutFunction,
+ DelegatingGetOwnPropertySlot,
+ CustomCall
+ ] HTMLEmbedElement : HTMLElement {
+ attribute [Reflect] DOMString align;
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ attribute [Reflect] DOMString height;
+#else
+ attribute [Reflect] long height;
+#endif
+ attribute [Reflect] DOMString name;
+ attribute [Reflect, URL] DOMString src;
+ attribute [Reflect] DOMString type;
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ attribute [Reflect] DOMString width;
+#else
+ attribute [Reflect] long width;
+#endif
+
+#if defined(ENABLE_SVG) && ENABLE_SVG
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS
+ [SVGCheckSecurityDocument] SVGDocument getSVGDocument() raises(DOMException);
+#endif
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLFieldSetElement.cpp b/Source/WebCore/html/HTMLFieldSetElement.cpp
new file mode 100644
index 0000000..4b90412
--- /dev/null
+++ b/Source/WebCore/html/HTMLFieldSetElement.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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, 2010 Apple Inc. All rights reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLFieldSetElement.h"
+
+#include "HTMLNames.h"
+#include "RenderFieldset.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLFieldSetElement::HTMLFieldSetElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLFormControlElement(tagName, document, form)
+{
+ ASSERT(hasTagName(fieldsetTag));
+}
+
+PassRefPtr<HTMLFieldSetElement> HTMLFieldSetElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLFieldSetElement(tagName, document, form));
+}
+
+bool HTMLFieldSetElement::supportsFocus() const
+{
+ return HTMLElement::supportsFocus();
+}
+
+const AtomicString& HTMLFieldSetElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, fieldset, ("fieldset"));
+ return fieldset;
+}
+
+RenderObject* HTMLFieldSetElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderFieldset(this);
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLFieldSetElement.h b/Source/WebCore/html/HTMLFieldSetElement.h
new file mode 100644
index 0000000..dcc8d0c
--- /dev/null
+++ b/Source/WebCore/html/HTMLFieldSetElement.h
@@ -0,0 +1,47 @@
+/*
+ * 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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLFieldSetElement_h
+#define HTMLFieldSetElement_h
+
+#include "HTMLFormControlElement.h"
+
+namespace WebCore {
+
+class HTMLFieldSetElement : public HTMLFormControlElement {
+public:
+ static PassRefPtr<HTMLFieldSetElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+
+private:
+ HTMLFieldSetElement(const QualifiedName&, Document*, HTMLFormElement*);
+
+ virtual bool isEnumeratable() const { return true; }
+ virtual bool supportsFocus() const;
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+ virtual const AtomicString& formControlType() const;
+ virtual bool recalcWillValidate() const { return false; }
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLFieldSetElement.idl b/Source/WebCore/html/HTMLFieldSetElement.idl
new file mode 100644
index 0000000..8cffe3d
--- /dev/null
+++ b/Source/WebCore/html/HTMLFieldSetElement.idl
@@ -0,0 +1,31 @@
+/*
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLFieldSetElement : HTMLElement {
+ readonly attribute HTMLFormElement form;
+ readonly attribute ValidityState validity;
+ readonly attribute boolean willValidate;
+ readonly attribute DOMString validationMessage;
+ boolean checkValidity();
+ void setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error);
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLFontElement.cpp b/Source/WebCore/html/HTMLFontElement.cpp
new file mode 100644
index 0000000..5239834
--- /dev/null
+++ b/Source/WebCore/html/HTMLFontElement.cpp
@@ -0,0 +1,185 @@
+/*
+ * 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, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLFontElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+
+using namespace WTF;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLFontElement::HTMLFontElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(fontTag));
+}
+
+PassRefPtr<HTMLFontElement> HTMLFontElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLFontElement(tagName, document));
+}
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#fonts-and-colors
+static bool parseFontSize(const String& input, int& size)
+{
+
+ // Step 1
+ // Step 2
+ const UChar* position = input.characters();
+ const UChar* end = position + input.length();
+
+ // Step 3
+ while (position < end) {
+ if (!isHTMLSpace(*position))
+ break;
+ ++position;
+ }
+
+ // Step 4
+ if (position == end)
+ return false;
+ ASSERT(position < end);
+
+ // Step 5
+ enum {
+ RelativePlus,
+ RelativeMinus,
+ Absolute
+ } mode;
+
+ switch (*position) {
+ case '+':
+ mode = RelativePlus;
+ ++position;
+ break;
+ case '-':
+ mode = RelativeMinus;
+ ++position;
+ break;
+ default:
+ mode = Absolute;
+ break;
+ }
+
+ // Step 6
+ Vector<UChar, 16> digits;
+ while (position < end) {
+ if (!isASCIIDigit(*position))
+ break;
+ digits.append(*position++);
+ }
+
+ // Step 7
+ if (digits.isEmpty())
+ return false;
+
+ // Step 8
+ int value = charactersToIntStrict(digits.data(), digits.size());
+
+ // Step 9
+ if (mode == RelativePlus)
+ value += 3;
+ else if (mode == RelativeMinus)
+ value = 3 - value;
+
+ // Step 10
+ if (value > 7)
+ value = 7;
+
+ // Step 11
+ if (value < 1)
+ value = 1;
+
+ size = value;
+ return true;
+}
+
+bool HTMLFontElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == sizeAttr ||
+ attrName == colorAttr ||
+ attrName == faceAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+bool HTMLFontElement::cssValueFromFontSizeNumber(const String& s, int& size)
+{
+ int num = 0;
+ if (!parseFontSize(s, num))
+ return false;
+
+ switch (num) {
+ case 1:
+ // FIXME: The spec says that we're supposed to use CSSValueXxSmall here.
+ size = CSSValueXSmall;
+ break;
+ case 2:
+ size = CSSValueSmall;
+ break;
+ case 3:
+ size = CSSValueMedium;
+ break;
+ case 4:
+ size = CSSValueLarge;
+ break;
+ case 5:
+ size = CSSValueXLarge;
+ break;
+ case 6:
+ size = CSSValueXxLarge;
+ break;
+ case 7:
+ size = CSSValueWebkitXxxLarge;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ return true;
+}
+
+void HTMLFontElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == sizeAttr) {
+ int size = 0;
+ if (cssValueFromFontSizeNumber(attr->value(), size))
+ addCSSProperty(attr, CSSPropertyFontSize, size);
+ } else if (attr->name() == colorAttr) {
+ addCSSColor(attr, CSSPropertyColor, attr->value());
+ } else if (attr->name() == faceAttr) {
+ addCSSProperty(attr, CSSPropertyFontFamily, attr->value());
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLFontElement.h b/Source/WebCore/html/HTMLFontElement.h
new file mode 100644
index 0000000..f97ab08
--- /dev/null
+++ b/Source/WebCore/html/HTMLFontElement.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2000 Simon Hausmann <hausmann@kde.org>
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLFontElement_h
+#define HTMLFontElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLFontElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLFontElement> create(const QualifiedName&, Document*);
+
+ static bool cssValueFromFontSizeNumber(const String&, int&);
+
+private:
+ HTMLFontElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLFontElement.idl b/Source/WebCore/html/HTMLFontElement.idl
new file mode 100644
index 0000000..141816d
--- /dev/null
+++ b/Source/WebCore/html/HTMLFontElement.idl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLFontElement : HTMLElement {
+ attribute [Reflect] DOMString color;
+ attribute [Reflect] DOMString face;
+ attribute [Reflect] DOMString size;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLFormCollection.cpp b/Source/WebCore/html/HTMLFormCollection.cpp
new file mode 100644
index 0000000..4f52b9d
--- /dev/null
+++ b/Source/WebCore/html/HTMLFormCollection.cpp
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLFormCollection.h"
+
+#include "CollectionCache.h"
+#include "HTMLFormControlElement.h"
+#include "HTMLFormElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+// Since the collections are to be "live", we have to do the
+// calculation every time if anything has changed.
+
+inline CollectionCache* HTMLFormCollection::formCollectionInfo(HTMLFormElement* form)
+{
+ if (!form->m_collectionCache)
+ form->m_collectionCache = adoptPtr(new CollectionCache);
+ return form->m_collectionCache.get();
+}
+
+HTMLFormCollection::HTMLFormCollection(PassRefPtr<HTMLFormElement> form)
+ : HTMLCollection(form.get(), OtherCollection, formCollectionInfo(form.get()))
+{
+}
+
+PassRefPtr<HTMLFormCollection> HTMLFormCollection::create(PassRefPtr<HTMLFormElement> form)
+{
+ return adoptRef(new HTMLFormCollection(form));
+}
+
+HTMLFormCollection::~HTMLFormCollection()
+{
+}
+
+unsigned HTMLFormCollection::calcLength() const
+{
+ return static_cast<HTMLFormElement*>(base())->length();
+}
+
+Node* HTMLFormCollection::item(unsigned index) const
+{
+ resetCollectionInfo();
+
+ if (info()->current && info()->position == index)
+ return info()->current;
+
+ if (info()->hasLength && info()->length <= index)
+ return 0;
+
+ if (!info()->current || info()->position > index) {
+ info()->current = 0;
+ info()->position = 0;
+ info()->elementsArrayPosition = 0;
+ }
+
+ Vector<FormAssociatedElement*>& elementsArray = static_cast<HTMLFormElement*>(base())->m_associatedElements;
+ unsigned currentIndex = info()->position;
+
+ for (unsigned i = info()->elementsArrayPosition; i < elementsArray.size(); i++) {
+ if (elementsArray[i]->isEnumeratable()) {
+ HTMLElement* element = toHTMLElement(elementsArray[i]);
+ if (index == currentIndex) {
+ info()->position = index;
+ info()->current = element;
+ info()->elementsArrayPosition = i;
+ return element;
+ }
+
+ currentIndex++;
+ }
+ }
+
+ return 0;
+}
+
+Element* HTMLFormCollection::getNamedItem(const QualifiedName& attrName, const AtomicString& name) const
+{
+ info()->position = 0;
+ return getNamedFormItem(attrName, name, 0);
+}
+
+Element* HTMLFormCollection::getNamedFormItem(const QualifiedName& attrName, const String& name, int duplicateNumber) const
+{
+ HTMLFormElement* form = static_cast<HTMLFormElement*>(base());
+
+ bool foundInputElements = false;
+ for (unsigned i = 0; i < form->m_associatedElements.size(); ++i) {
+ FormAssociatedElement* associatedElement = form->m_associatedElements[i];
+ HTMLElement* element = toHTMLElement(associatedElement);
+ if (associatedElement->isEnumeratable() && element->getAttribute(attrName) == name) {
+ foundInputElements = true;
+ if (!duplicateNumber)
+ return element;
+ --duplicateNumber;
+ }
+ }
+
+ if (!foundInputElements) {
+ for (unsigned i = 0; i < form->m_imageElements.size(); ++i) {
+ HTMLImageElement* element = form->m_imageElements[i];
+ if (element->getAttribute(attrName) == name) {
+ if (!duplicateNumber)
+ return element;
+ --duplicateNumber;
+ }
+ }
+ }
+
+ return 0;
+}
+
+Node* HTMLFormCollection::nextItem() const
+{
+ return item(info()->position + 1);
+}
+
+Element* HTMLFormCollection::nextNamedItemInternal(const String &name) const
+{
+ Element* retval = getNamedFormItem(m_idsDone ? nameAttr : idAttr, name, ++info()->position);
+ if (retval)
+ return retval;
+ if (m_idsDone) // we're done
+ return 0;
+ // After doing id, do name
+ m_idsDone = true;
+ return getNamedItem(nameAttr, name);
+}
+
+Node* HTMLFormCollection::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.
+ resetCollectionInfo();
+ m_idsDone = false;
+ info()->current = getNamedItem(idAttr, name);
+ if (info()->current)
+ return info()->current;
+ m_idsDone = true;
+ info()->current = getNamedItem(nameAttr, name);
+ return info()->current;
+}
+
+Node* HTMLFormCollection::nextNamedItem(const AtomicString& name) const
+{
+ // The nextNamedItemInternal function can return the same item twice if it has
+ // both an id and name that are equal to the name parameter. So this function
+ // checks if we are on the nameAttr half of the iteration and skips over any
+ // that also have the same idAttributeName.
+ Element* impl = nextNamedItemInternal(name);
+ if (m_idsDone) {
+ while (impl && impl->getIdAttribute() == name)
+ impl = nextNamedItemInternal(name);
+ }
+ return impl;
+}
+
+void HTMLFormCollection::updateNameCache() const
+{
+ if (info()->hasNameCache)
+ return;
+
+ HashSet<AtomicStringImpl*> foundInputElements;
+
+ HTMLFormElement* f = static_cast<HTMLFormElement*>(base());
+
+ for (unsigned i = 0; i < f->m_associatedElements.size(); ++i) {
+ FormAssociatedElement* associatedElement = f->m_associatedElements[i];
+ if (associatedElement->isEnumeratable()) {
+ HTMLElement* element = toHTMLElement(associatedElement);
+ const AtomicString& idAttrVal = element->getIdAttribute();
+ const AtomicString& nameAttrVal = element->getAttribute(nameAttr);
+ if (!idAttrVal.isEmpty()) {
+ // add to id cache
+ Vector<Element*>* idVector = info()->idCache.get(idAttrVal.impl());
+ if (!idVector) {
+ idVector = new Vector<Element*>;
+ info()->idCache.add(idAttrVal.impl(), idVector);
+ }
+ idVector->append(element);
+ foundInputElements.add(idAttrVal.impl());
+ }
+ if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal) {
+ // add to name cache
+ Vector<Element*>* nameVector = info()->nameCache.get(nameAttrVal.impl());
+ if (!nameVector) {
+ nameVector = new Vector<Element*>;
+ info()->nameCache.add(nameAttrVal.impl(), nameVector);
+ }
+ nameVector->append(element);
+ foundInputElements.add(nameAttrVal.impl());
+ }
+ }
+ }
+
+ for (unsigned i = 0; i < f->m_imageElements.size(); ++i) {
+ HTMLImageElement* element = f->m_imageElements[i];
+ const AtomicString& idAttrVal = element->getIdAttribute();
+ const AtomicString& nameAttrVal = element->getAttribute(nameAttr);
+ if (!idAttrVal.isEmpty() && !foundInputElements.contains(idAttrVal.impl())) {
+ // add to id cache
+ Vector<Element*>* idVector = info()->idCache.get(idAttrVal.impl());
+ if (!idVector) {
+ idVector = new Vector<Element*>;
+ info()->idCache.add(idAttrVal.impl(), idVector);
+ }
+ idVector->append(element);
+ }
+ if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && !foundInputElements.contains(nameAttrVal.impl())) {
+ // add to name cache
+ Vector<Element*>* nameVector = info()->nameCache.get(nameAttrVal.impl());
+ if (!nameVector) {
+ nameVector = new Vector<Element*>;
+ info()->nameCache.add(nameAttrVal.impl(), nameVector);
+ }
+ nameVector->append(element);
+ }
+ }
+
+ info()->hasNameCache = true;
+}
+
+}
diff --git a/Source/WebCore/html/HTMLFormCollection.h b/Source/WebCore/html/HTMLFormCollection.h
new file mode 100644
index 0000000..a204446
--- /dev/null
+++ b/Source/WebCore/html/HTMLFormCollection.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLFormCollection_h
+#define HTMLFormCollection_h
+
+#include "HTMLCollection.h"
+
+namespace WebCore {
+
+class HTMLFormElement;
+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 HTMLFormCollection : public HTMLCollection {
+public:
+ static PassRefPtr<HTMLFormCollection> create(PassRefPtr<HTMLFormElement>);
+
+ virtual ~HTMLFormCollection();
+
+ virtual Node* item(unsigned index) const;
+ virtual Node* nextItem() const;
+
+ virtual Node* namedItem(const AtomicString& name) const;
+ virtual Node* nextNamedItem(const AtomicString& name) const;
+
+private:
+ HTMLFormCollection(PassRefPtr<HTMLFormElement>);
+
+ virtual void updateNameCache() const;
+ virtual unsigned calcLength() const;
+
+ static CollectionCache* formCollectionInfo(HTMLFormElement*);
+
+ Element* getNamedItem(const QualifiedName& attrName, const AtomicString& name) const;
+ Element* nextNamedItemInternal(const String& name) const;
+
+ Element* getNamedFormItem(const QualifiedName& attrName, const String& name, int duplicateNumber) const;
+
+ mutable int currentPos;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLFormControlElement.cpp b/Source/WebCore/html/HTMLFormControlElement.cpp
new file mode 100644
index 0000000..8556c1e
--- /dev/null
+++ b/Source/WebCore/html/HTMLFormControlElement.cpp
@@ -0,0 +1,635 @@
+/*
+ * 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 Apple Inc. All rights reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLFormControlElement.h"
+
+#include "Attribute.h"
+#include "CharacterNames.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "Document.h"
+#include "DocumentParser.h"
+#include "ElementRareData.h"
+#include "Event.h"
+#include "EventHandler.h"
+#include "EventNames.h"
+#include "Frame.h"
+#include "HTMLFormElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "LabelsNodeList.h"
+#include "Page.h"
+#include "RenderBox.h"
+#include "RenderTextControl.h"
+#include "RenderTheme.h"
+#include "ScriptEventListener.h"
+#include "ValidationMessage.h"
+#include "ValidityState.h"
+#include <limits>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+using namespace std;
+
+HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLElement(tagName, document)
+ , FormAssociatedElement(form)
+ , m_disabled(false)
+ , m_readOnly(false)
+ , m_required(false)
+ , m_valueMatchesRenderer(false)
+ , m_willValidateInitialized(false)
+ , m_willValidate(true)
+ , m_isValid(true)
+{
+ if (!this->form())
+ setForm(findFormAncestor());
+ if (this->form())
+ this->form()->registerFormElement(this);
+}
+
+HTMLFormControlElement::~HTMLFormControlElement()
+{
+ if (form())
+ form()->removeFormElement(this);
+}
+
+void HTMLFormControlElement::detach()
+{
+ hideVisibleValidationMessage();
+ HTMLElement::detach();
+}
+
+bool HTMLFormControlElement::formNoValidate() const
+{
+ return fastHasAttribute(formnovalidateAttr);
+}
+
+void HTMLFormControlElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == disabledAttr) {
+ bool oldDisabled = m_disabled;
+ m_disabled = !attr->isNull();
+ if (oldDisabled != m_disabled) {
+ setNeedsStyleRecalc();
+ if (renderer() && renderer()->style()->hasAppearance())
+ renderer()->theme()->stateChanged(renderer(), EnabledState);
+ }
+ } else if (attr->name() == readonlyAttr) {
+ bool oldReadOnly = m_readOnly;
+ m_readOnly = !attr->isNull();
+ if (oldReadOnly != m_readOnly) {
+ setNeedsStyleRecalc();
+ if (renderer() && renderer()->style()->hasAppearance())
+ renderer()->theme()->stateChanged(renderer(), ReadOnlyState);
+ }
+ } else if (attr->name() == requiredAttr) {
+ bool oldRequired = m_required;
+ m_required = !attr->isNull();
+ if (oldRequired != m_required) {
+ setNeedsValidityCheck();
+ setNeedsStyleRecalc(); // Updates for :required :optional classes.
+ }
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+ setNeedsWillValidateCheck();
+}
+
+void HTMLFormControlElement::attach()
+{
+ ASSERT(!attached());
+
+ HTMLElement::attach();
+
+ // The call to updateFromElement() needs to go after the call through
+ // to the base class's attach() because that can sometimes do a close
+ // on the renderer.
+ if (renderer())
+ renderer()->updateFromElement();
+
+ // Focus the element if it should honour its autofocus attribute.
+ // We have to determine if the element is a TextArea/Input/Button/Select,
+ // if input type hidden ignore autofocus. So if disabled or readonly.
+ bool isInputTypeHidden = false;
+ if (hasTagName(inputTag))
+ isInputTypeHidden = static_cast<HTMLInputElement*>(this)->isInputTypeHidden();
+
+ if (autofocus() && renderer() && !document()->ignoreAutofocus() && !isReadOnlyFormControl() &&
+ ((hasTagName(inputTag) && !isInputTypeHidden) || hasTagName(selectTag) ||
+ hasTagName(buttonTag) || hasTagName(textareaTag)))
+ focus();
+}
+
+void HTMLFormControlElement::insertedIntoTree(bool deep)
+{
+ FormAssociatedElement::insertedIntoTree();
+ if (!form())
+ document()->checkedRadioButtons().addButton(this);
+
+ HTMLElement::insertedIntoTree(deep);
+}
+
+void HTMLFormControlElement::removedFromTree(bool deep)
+{
+ FormAssociatedElement::removedFromTree();
+ HTMLElement::removedFromTree(deep);
+}
+
+const AtomicString& HTMLFormControlElement::formControlName() const
+{
+ const AtomicString& name = fastGetAttribute(nameAttr);
+ return name.isNull() ? emptyAtom : name;
+}
+
+void HTMLFormControlElement::setName(const AtomicString& value)
+{
+ setAttribute(nameAttr, value);
+}
+
+void HTMLFormControlElement::dispatchFormControlChangeEvent()
+{
+ dispatchEvent(Event::create(eventNames().changeEvent, true, false));
+}
+
+void HTMLFormControlElement::setDisabled(bool b)
+{
+ setAttribute(disabledAttr, b ? "" : 0);
+}
+
+bool HTMLFormControlElement::autofocus() const
+{
+ return hasAttribute(autofocusAttr);
+}
+
+bool HTMLFormControlElement::required() const
+{
+ return m_required;
+}
+
+static void updateFromElementCallback(Node* node)
+{
+ ASSERT_ARG(node, node->isElementNode());
+ ASSERT_ARG(node, static_cast<Element*>(node)->isFormControlElement());
+ ASSERT(node->renderer());
+ if (RenderObject* renderer = node->renderer())
+ renderer->updateFromElement();
+}
+
+void HTMLFormControlElement::recalcStyle(StyleChange change)
+{
+ HTMLElement::recalcStyle(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())
+ queuePostAttachCallback(updateFromElementCallback, this);
+}
+
+bool HTMLFormControlElement::supportsFocus() const
+{
+ return !m_disabled;
+}
+
+bool HTMLFormControlElement::isFocusable() const
+{
+ if (!renderer() ||
+ !renderer()->isBox() || toRenderBox(renderer())->size().isEmpty())
+ return false;
+ // HTMLElement::isFocusable handles visibility and calls suportsFocus which
+ // will cover the disabled case.
+ return HTMLElement::isFocusable();
+}
+
+bool HTMLFormControlElement::isKeyboardFocusable(KeyboardEvent* event) const
+{
+ if (isFocusable())
+ if (document()->frame())
+ return document()->frame()->eventHandler()->tabsToAllControls(event);
+ return false;
+}
+
+bool HTMLFormControlElement::isMouseFocusable() const
+{
+#if PLATFORM(GTK) || PLATFORM(QT)
+ return HTMLElement::isMouseFocusable();
+#else
+ return false;
+#endif
+}
+
+short HTMLFormControlElement::tabIndex() const
+{
+ // Skip the supportsFocus check in HTMLElement.
+ return Element::tabIndex();
+}
+
+bool HTMLFormControlElement::recalcWillValidate() const
+{
+ // FIXME: Should return false if this element has a datalist element as an
+ // ancestor. See HTML5 4.10.10 'The datalist element.'
+ return !m_disabled && !m_readOnly;
+}
+
+bool HTMLFormControlElement::willValidate() const
+{
+ if (!m_willValidateInitialized) {
+ m_willValidateInitialized = true;
+ m_willValidate = recalcWillValidate();
+ } else {
+ // If the following assertion fails, setNeedsWillValidateCheck() is not
+ // called correctly when something which changes recalcWillValidate() result
+ // is updated.
+ ASSERT(m_willValidate == recalcWillValidate());
+ }
+ return m_willValidate;
+}
+
+void HTMLFormControlElement::setNeedsWillValidateCheck()
+{
+ // We need to recalculate willValidte immediately because willValidate
+ // change can causes style change.
+ bool newWillValidate = recalcWillValidate();
+ if (m_willValidateInitialized && m_willValidate == newWillValidate)
+ return;
+ m_willValidateInitialized = true;
+ m_willValidate = newWillValidate;
+ setNeedsStyleRecalc();
+ if (!m_willValidate)
+ hideVisibleValidationMessage();
+}
+
+String HTMLFormControlElement::validationMessage()
+{
+ return validity()->validationMessage();
+}
+
+void HTMLFormControlElement::updateVisibleValidationMessage()
+{
+ Page* page = document()->page();
+ if (!page)
+ return;
+ String message;
+ if (renderer() && willValidate()) {
+ message = validationMessage().stripWhiteSpace();
+ // 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.
+ const AtomicString& title = getAttribute(titleAttr);
+ if (!message.isEmpty() && !title.isEmpty()) {
+ message.append('\n');
+ message.append(title);
+ }
+ }
+ if (!m_validationMessage) {
+ m_validationMessage = ValidationMessage::create(this);
+ m_validationMessage->setMessage(message);
+ } else if (message.isEmpty())
+ hideVisibleValidationMessage();
+ else if (m_validationMessage->message() != message)
+ m_validationMessage->setMessage(message);
+}
+
+void HTMLFormControlElement::hideVisibleValidationMessage()
+{
+ m_validationMessage = 0;
+}
+
+String HTMLFormControlElement::visibleValidationMessage() const
+{
+ return m_validationMessage ? m_validationMessage->message() : String();
+}
+
+bool HTMLFormControlElement::checkValidity(Vector<RefPtr<FormAssociatedElement> >* unhandledInvalidControls)
+{
+ if (!willValidate() || isValidFormControlElement())
+ return true;
+ // An event handler can deref this object.
+ RefPtr<HTMLFormControlElement> protector(this);
+ RefPtr<Document> originalDocument(document());
+ bool needsDefaultAction = dispatchEvent(Event::create(eventNames().invalidEvent, false, true));
+ if (needsDefaultAction && unhandledInvalidControls && inDocument() && originalDocument == document())
+ unhandledInvalidControls->append(this);
+ return false;
+}
+
+bool HTMLFormControlElement::isValidFormControlElement()
+{
+ // If the following assertion fails, setNeedsValidityCheck() is not called
+ // correctly when something which changes validity is updated.
+ ASSERT(m_isValid == validity()->valid());
+ return m_isValid;
+}
+
+void HTMLFormControlElement::setNeedsValidityCheck()
+{
+ bool newIsValid = validity()->valid();
+ if (willValidate() && newIsValid != m_isValid) {
+ // Update style for pseudo classes such as :valid :invalid.
+ setNeedsStyleRecalc();
+ }
+ m_isValid = newIsValid;
+
+ // Updates only if this control already has a validtion message.
+ if (!visibleValidationMessage().isEmpty()) {
+ // Calls updateVisibleValidationMessage() even if m_isValid is not
+ // changed because a validation message can be chagned.
+ updateVisibleValidationMessage();
+ }
+}
+
+void HTMLFormControlElement::setCustomValidity(const String& error)
+{
+ validity()->setCustomErrorMessage(error);
+}
+
+void HTMLFormControlElement::dispatchFocusEvent()
+{
+ if (document()->page())
+ document()->page()->chrome()->client()->formDidFocus(this);
+
+ HTMLElement::dispatchFocusEvent();
+}
+
+void HTMLFormControlElement::dispatchBlurEvent()
+{
+ if (document()->page())
+ document()->page()->chrome()->client()->formDidBlur(this);
+
+ HTMLElement::dispatchBlurEvent();
+ hideVisibleValidationMessage();
+}
+
+HTMLFormElement* HTMLFormControlElement::virtualForm() const
+{
+ return FormAssociatedElement::form();
+}
+
+bool HTMLFormControlElement::isDefaultButtonForForm() const
+{
+ return isSuccessfulSubmitButton() && form() && form()->defaultButton() == this;
+}
+
+void HTMLFormControlElement::attributeChanged(Attribute* attr, bool preserveDecls)
+{
+ if (attr->name() == formAttr) {
+ formAttributeChanged();
+ if (!form())
+ document()->checkedRadioButtons().addButton(this);
+ } else
+ HTMLElement::attributeChanged(attr, preserveDecls);
+}
+
+bool HTMLFormControlElement::isLabelable() const
+{
+ // FIXME: Add meterTag and outputTag to the list once we support them.
+ return hasTagName(buttonTag) || hasTagName(inputTag) || hasTagName(keygenTag)
+#if ENABLE(METER_TAG)
+ || hasTagName(meterTag)
+#endif
+#if ENABLE(PROGRESS_TAG)
+ || hasTagName(progressTag)
+#endif
+ || hasTagName(selectTag) || hasTagName(textareaTag);
+}
+
+PassRefPtr<NodeList> HTMLFormControlElement::labels()
+{
+ if (!isLabelable())
+ return 0;
+ if (!document())
+ return 0;
+
+ NodeRareData* data = Node::ensureRareData();
+ if (!data->nodeLists()) {
+ data->setNodeLists(NodeListsNodeData::create());
+ document()->addNodeListCache();
+ }
+
+ return LabelsNodeList::create(this);
+}
+
+HTMLFormControlElementWithState::HTMLFormControlElementWithState(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
+ : HTMLFormControlElement(tagName, doc, f)
+{
+ document()->registerFormElementWithState(this);
+}
+
+HTMLFormControlElementWithState::~HTMLFormControlElementWithState()
+{
+ document()->unregisterFormElementWithState(this);
+}
+
+void HTMLFormControlElementWithState::willMoveToNewOwnerDocument()
+{
+ document()->unregisterFormElementWithState(this);
+ HTMLFormControlElement::willMoveToNewOwnerDocument();
+}
+
+void HTMLFormControlElementWithState::didMoveToNewOwnerDocument()
+{
+ document()->registerFormElementWithState(this);
+ HTMLFormControlElement::didMoveToNewOwnerDocument();
+}
+
+bool HTMLFormControlElementWithState::autoComplete() const
+{
+ if (!form())
+ return true;
+ return form()->autoComplete();
+}
+
+bool HTMLFormControlElementWithState::shouldSaveAndRestoreFormControlState() const
+{
+ // We don't save/restore control state in a form with autocomplete=off.
+ return attached() && autoComplete();
+}
+
+void HTMLFormControlElementWithState::finishParsingChildren()
+{
+ HTMLFormControlElement::finishParsingChildren();
+
+ // We don't save state of a control with shouldSaveAndRestoreFormControlState()=false.
+ // But we need to skip restoring process too because a control in another
+ // form might have the same pair of name and type and saved its state.
+ if (!shouldSaveAndRestoreFormControlState())
+ return;
+
+ Document* doc = document();
+ if (doc->hasStateForNewFormElements()) {
+ String state;
+ if (doc->takeStateForFormElement(name().impl(), type().impl(), state))
+ restoreFormControlState(state);
+ }
+}
+
+void HTMLFormControlElementWithState::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().webkitEditableContentChangedEvent && renderer() && renderer()->isTextControl()) {
+ toRenderTextControl(renderer())->subtreeHasChanged();
+ return;
+ }
+
+ HTMLFormControlElement::defaultEventHandler(event);
+}
+
+HTMLTextFormControlElement::HTMLTextFormControlElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* form)
+ : HTMLFormControlElementWithState(tagName, doc, form)
+{
+}
+
+HTMLTextFormControlElement::~HTMLTextFormControlElement()
+{
+}
+
+void HTMLTextFormControlElement::dispatchFocusEvent()
+{
+ if (supportsPlaceholder())
+ updatePlaceholderVisibility(false);
+ handleFocusEvent();
+ HTMLFormControlElementWithState::dispatchFocusEvent();
+}
+
+void HTMLTextFormControlElement::dispatchBlurEvent()
+{
+ if (supportsPlaceholder())
+ updatePlaceholderVisibility(false);
+ handleBlurEvent();
+ HTMLFormControlElementWithState::dispatchBlurEvent();
+}
+
+String HTMLTextFormControlElement::strippedPlaceholder() const
+{
+ // According to the HTML5 specification, we need to remove CR and LF from
+ // the attribute value.
+ const AtomicString& attributeValue = getAttribute(placeholderAttr);
+ if (!attributeValue.contains(newlineCharacter) && !attributeValue.contains(carriageReturn))
+ return attributeValue;
+
+ Vector<UChar> stripped;
+ unsigned length = attributeValue.length();
+ stripped.reserveCapacity(length);
+ for (unsigned i = 0; i < length; ++i) {
+ UChar character = attributeValue[i];
+ if (character == newlineCharacter || character == carriageReturn)
+ continue;
+ stripped.append(character);
+ }
+ return String::adopt(stripped);
+}
+
+static bool isNotLineBreak(UChar ch) { return ch != newlineCharacter && ch != carriageReturn; }
+
+bool HTMLTextFormControlElement::isPlaceholderEmpty() const
+{
+ const AtomicString& attributeValue = getAttribute(placeholderAttr);
+ return attributeValue.string().find(isNotLineBreak) == notFound;
+}
+
+bool HTMLTextFormControlElement::placeholderShouldBeVisible() const
+{
+ return supportsPlaceholder()
+ && isEmptyValue()
+ && document()->focusedNode() != this
+ && !isPlaceholderEmpty();
+}
+
+void HTMLTextFormControlElement::updatePlaceholderVisibility(bool placeholderValueChanged)
+{
+ if (supportsPlaceholder() && renderer())
+ toRenderTextControl(renderer())->updatePlaceholderVisibility(placeholderShouldBeVisible(), placeholderValueChanged);
+}
+
+RenderTextControl* HTMLTextFormControlElement::textRendererAfterUpdateLayout()
+{
+ if (!isTextFormControl())
+ return 0;
+ document()->updateLayoutIgnorePendingStylesheets();
+ return toRenderTextControl(renderer());
+}
+
+void HTMLTextFormControlElement::setSelectionStart(int start)
+{
+ setSelectionRange(start, max(start, selectionEnd()));
+}
+
+void HTMLTextFormControlElement::setSelectionEnd(int end)
+{
+ setSelectionRange(min(end, selectionStart()), end);
+}
+
+void HTMLTextFormControlElement::select()
+{
+ setSelectionRange(0, numeric_limits<int>::max());
+}
+
+void HTMLTextFormControlElement::setSelectionRange(int start, int end)
+{
+ WebCore::setSelectionRange(this, start, end);
+}
+
+int HTMLTextFormControlElement::selectionStart() const
+{
+ if (!isTextFormControl())
+ return 0;
+ if (document()->focusedNode() != this && cachedSelectionStart() >= 0)
+ return cachedSelectionStart();
+ if (!renderer())
+ return 0;
+ return toRenderTextControl(renderer())->selectionStart();
+}
+
+int HTMLTextFormControlElement::selectionEnd() const
+{
+ if (!isTextFormControl())
+ return 0;
+ if (document()->focusedNode() != this && cachedSelectionEnd() >= 0)
+ return cachedSelectionEnd();
+ if (!renderer())
+ return 0;
+ return toRenderTextControl(renderer())->selectionEnd();
+}
+
+PassRefPtr<Range> HTMLTextFormControlElement::selection() const
+{
+ if (!renderer() || !isTextFormControl() || cachedSelectionStart() < 0 || cachedSelectionEnd() < 0)
+ return 0;
+ return toRenderTextControl(renderer())->selection(cachedSelectionStart(), cachedSelectionEnd());
+}
+
+void HTMLTextFormControlElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == placeholderAttr)
+ updatePlaceholderVisibility(true);
+ else if (attr->name() == onselectAttr)
+ setAttributeEventListener(eventNames().selectEvent, createAttributeEventListener(this, attr));
+ else if (attr->name() == onchangeAttr)
+ setAttributeEventListener(eventNames().changeEvent, createAttributeEventListener(this, attr));
+ else
+ HTMLFormControlElementWithState::parseMappedAttribute(attr);
+}
+
+} // namespace Webcore
diff --git a/Source/WebCore/html/HTMLFormControlElement.h b/Source/WebCore/html/HTMLFormControlElement.h
new file mode 100644
index 0000000..e5d741b
--- /dev/null
+++ b/Source/WebCore/html/HTMLFormControlElement.h
@@ -0,0 +1,232 @@
+/*
+ * 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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLFormControlElement_h
+#define HTMLFormControlElement_h
+
+#include "FormAssociatedElement.h"
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class FormDataList;
+class HTMLFormElement;
+class RenderTextControl;
+class ValidationMessage;
+class ValidityState;
+class VisibleSelection;
+
+// HTMLFormControlElement is the default implementation of FormAssociatedElement,
+// and form-associated element implementations should use HTMLFormControlElement
+// unless there is a special reason.
+class HTMLFormControlElement : public HTMLElement, public FormAssociatedElement {
+public:
+ virtual ~HTMLFormControlElement();
+
+ HTMLFormElement* form() const { return FormAssociatedElement::form(); }
+
+ bool formNoValidate() const;
+
+ virtual void reset() { }
+
+ virtual bool formControlValueMatchesRenderer() const { return m_valueMatchesRenderer; }
+ virtual void setFormControlValueMatchesRenderer(bool b) { m_valueMatchesRenderer = b; }
+
+ virtual void dispatchFormControlChangeEvent();
+
+ virtual bool disabled() const { return m_disabled; }
+ void setDisabled(bool);
+
+ virtual bool isFocusable() const;
+ virtual bool isEnumeratable() const { return false; }
+
+ // Determines whether or not a control will be automatically focused.
+ virtual bool autofocus() const;
+
+ bool required() const;
+
+ const AtomicString& type() const { return formControlType(); }
+
+ void setName(const AtomicString& name);
+
+ virtual bool isEnabledFormControl() const { return !disabled(); }
+ virtual bool isReadOnlyFormControl() const { return readOnly(); }
+
+ virtual bool isRadioButton() const { return false; }
+ virtual bool canTriggerImplicitSubmission() const { return false; }
+
+ // Override in derived classes to get the encoded name=value pair for submitting.
+ // Return true for a successful control (see HTML4-17.13.2).
+ virtual bool appendFormData(FormDataList&, bool) { return false; }
+
+ virtual bool isSuccessfulSubmitButton() const { return false; }
+ virtual bool isActivatedSubmit() const { return false; }
+ virtual void setActivatedSubmit(bool) { }
+
+ virtual bool willValidate() const;
+ String validationMessage();
+ 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 setNeedsValidityCheck();
+ void setCustomValidity(const String&);
+
+ bool isLabelable() const;
+ PassRefPtr<NodeList> labels();
+
+ bool readOnly() const { return m_readOnly; }
+
+ virtual void attributeChanged(Attribute*, bool preserveDecls = false);
+
+ using TreeShared<ContainerNode>::ref;
+ using TreeShared<ContainerNode>::deref;
+
+protected:
+ HTMLFormControlElement(const QualifiedName& tagName, Document*, HTMLFormElement*);
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void attach();
+ virtual void insertedIntoTree(bool deep);
+ virtual void removedFromTree(bool deep);
+
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const;
+ virtual bool isMouseFocusable() const;
+
+ virtual void recalcStyle(StyleChange);
+
+ virtual void dispatchFocusEvent();
+ virtual void dispatchBlurEvent();
+ virtual void detach();
+
+ // This must be called any time the result of willValidate() has changed.
+ void setNeedsWillValidateCheck();
+ virtual bool recalcWillValidate() const;
+
+private:
+ virtual const AtomicString& formControlName() const;
+ virtual const AtomicString& formControlType() const = 0;
+
+ virtual void refFormAssociatedElement() { ref(); }
+ virtual void derefFormAssociatedElement() { deref(); }
+
+ virtual bool isFormControlElement() const { return true; }
+
+ virtual bool supportsFocus() const;
+
+ virtual short tabIndex() const;
+
+ virtual HTMLFormElement* virtualForm() const;
+ virtual bool isDefaultButtonForForm() const;
+ virtual bool isValidFormControlElement();
+ String visibleValidationMessage() const;
+
+ OwnPtr<ValidationMessage> m_validationMessage;
+ bool m_disabled : 1;
+ bool m_readOnly : 1;
+ bool m_required : 1;
+ bool m_valueMatchesRenderer : 1;
+
+ // The initial value of m_willValidate depends on the derived class. We can't
+ // initialize it with a virtual function in the constructor. m_willValidate
+ // is not deterministic as long as m_willValidateInitialized is false.
+ mutable bool m_willValidateInitialized: 1;
+ mutable bool m_willValidate : 1;
+
+ // Cache of validity()->valid().
+ // But "candidate for constraint validation" doesn't affect m_isValid.
+ bool m_isValid : 1;
+};
+
+// FIXME: Give this class its own header file.
+class HTMLFormControlElementWithState : public HTMLFormControlElement {
+public:
+ virtual ~HTMLFormControlElementWithState();
+
+protected:
+ HTMLFormControlElementWithState(const QualifiedName& tagName, Document*, HTMLFormElement*);
+
+ virtual bool autoComplete() const;
+
+ virtual void willMoveToNewOwnerDocument();
+ virtual void didMoveToNewOwnerDocument();
+ virtual void defaultEventHandler(Event*);
+
+private:
+ virtual bool shouldSaveAndRestoreFormControlState() const;
+ virtual void finishParsingChildren();
+};
+
+// FIXME: Give this class its own header file.
+class HTMLTextFormControlElement : public HTMLFormControlElementWithState {
+public:
+ // Common flag for HTMLInputElement::tooLong() and HTMLTextAreaElement::tooLong().
+ enum NeedsToCheckDirtyFlag {CheckDirtyFlag, IgnoreDirtyFlag};
+
+ virtual ~HTMLTextFormControlElement();
+
+ // The derived class should return true if placeholder processing is needed.
+ virtual bool supportsPlaceholder() const = 0;
+ String strippedPlaceholder() const;
+ bool placeholderShouldBeVisible() const;
+
+ int selectionStart() const;
+ int selectionEnd() const;
+ void setSelectionStart(int);
+ void setSelectionEnd(int);
+ void select();
+ void setSelectionRange(int start, int end);
+ PassRefPtr<Range> selection() const;
+
+ virtual int maxLength() const = 0;
+ virtual String value() const = 0;
+
+protected:
+ HTMLTextFormControlElement(const QualifiedName&, Document*, HTMLFormElement*);
+
+ void updatePlaceholderVisibility(bool);
+
+ virtual void parseMappedAttribute(Attribute*);
+
+private:
+ virtual void dispatchFocusEvent();
+ virtual void dispatchBlurEvent();
+
+ bool isPlaceholderEmpty() const;
+
+ virtual int cachedSelectionStart() const = 0;
+ virtual int cachedSelectionEnd() const = 0;
+
+ // Returns true if user-editable value is empty. Used to check placeholder visibility.
+ virtual bool isEmptyValue() const = 0;
+ // Called in dispatchFocusEvent(), after placeholder process, before calling parent's dispatchFocusEvent().
+ virtual void handleFocusEvent() { }
+ // Called in dispatchBlurEvent(), after placeholder process, before calling parent's dispatchBlurEvent().
+ virtual void handleBlurEvent() { }
+
+ RenderTextControl* textRendererAfterUpdateLayout();
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLFormElement.cpp b/Source/WebCore/html/HTMLFormElement.cpp
new file mode 100644
index 0000000..c896bbf
--- /dev/null
+++ b/Source/WebCore/html/HTMLFormElement.cpp
@@ -0,0 +1,669 @@
+/*
+ * 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 Apple Inc. All rights reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLFormElement.h"
+
+#include "Attribute.h"
+#include "DOMFormData.h"
+#include "DOMWindow.h"
+#include "Document.h"
+#include "Event.h"
+#include "EventNames.h"
+#include "FileList.h"
+#include "FileSystem.h"
+#include "FormData.h"
+#include "FormDataList.h"
+#include "FormState.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
+#include "HTMLDocument.h"
+#include "HTMLFormCollection.h"
+#include "HTMLImageElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "MIMETypeRegistry.h"
+#include "Page.h"
+#include "RenderTextControl.h"
+#include "ScriptEventListener.h"
+#include "Settings.h"
+#include "ValidityState.h"
+#include <limits>
+
+#if PLATFORM(WX)
+#include <wx/defs.h>
+#include <wx/filename.h>
+#endif
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLFormElement::HTMLFormElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , m_associatedElementsBeforeIndex(0)
+ , m_associatedElementsAfterIndex(0)
+ , m_wasUserSubmitted(false)
+ , m_isSubmittingOrPreparingForSubmission(false)
+ , m_shouldSubmit(false)
+ , m_isInResetFunction(false)
+ , m_wasMalformed(false)
+ , m_wasDemoted(false)
+{
+ ASSERT(hasTagName(formTag));
+}
+
+PassRefPtr<HTMLFormElement> HTMLFormElement::create(Document* document)
+{
+ return adoptRef(new HTMLFormElement(formTag, document));
+}
+
+PassRefPtr<HTMLFormElement> HTMLFormElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLFormElement(tagName, document));
+}
+
+HTMLFormElement::~HTMLFormElement()
+{
+ if (!autoComplete())
+ document()->unregisterForDocumentActivationCallbacks(this);
+
+ for (unsigned i = 0; i < m_associatedElements.size(); ++i)
+ m_associatedElements[i]->formDestroyed();
+ for (unsigned i = 0; i < m_imageElements.size(); ++i)
+ m_imageElements[i]->m_form = 0;
+}
+
+bool HTMLFormElement::formWouldHaveSecureSubmission(const String& url)
+{
+ return document()->completeURL(url).protocolIs("https");
+}
+
+bool HTMLFormElement::rendererIsNeeded(RenderStyle* style)
+{
+ if (!m_wasDemoted)
+ return HTMLElement::rendererIsNeeded(style);
+
+ ContainerNode* node = parentNode();
+ RenderObject* parentRenderer = node->renderer();
+ bool parentIsTableElementPart = (parentRenderer->isTable() && node->hasTagName(tableTag))
+ || (parentRenderer->isTableRow() && node->hasTagName(trTag))
+ || (parentRenderer->isTableSection() && node->hasTagName(tbodyTag))
+ || (parentRenderer->isTableCol() && node->hasTagName(colTag))
+ || (parentRenderer->isTableCell() && node->hasTagName(trTag));
+
+ if (!parentIsTableElementPart)
+ return true;
+
+ EDisplay display = style->display();
+ bool formIsTablePart = display == TABLE || display == INLINE_TABLE || display == TABLE_ROW_GROUP
+ || display == TABLE_HEADER_GROUP || display == TABLE_FOOTER_GROUP || display == TABLE_ROW
+ || display == TABLE_COLUMN_GROUP || display == TABLE_COLUMN || display == TABLE_CELL
+ || display == TABLE_CAPTION;
+
+ return formIsTablePart;
+}
+
+void HTMLFormElement::insertedIntoDocument()
+{
+ if (document()->isHTMLDocument())
+ static_cast<HTMLDocument*>(document())->addNamedItem(m_name);
+
+ HTMLElement::insertedIntoDocument();
+
+ if (hasID())
+ document()->resetFormElementsOwner(this);
+}
+
+void HTMLFormElement::removedFromDocument()
+{
+ if (document()->isHTMLDocument())
+ static_cast<HTMLDocument*>(document())->removeNamedItem(m_name);
+
+ HTMLElement::removedFromDocument();
+
+ if (hasID())
+ document()->resetFormElementsOwner(0);
+}
+
+void HTMLFormElement::handleLocalEvents(Event* event)
+{
+ Node* targetNode = event->target()->toNode();
+ if (event->eventPhase() != Event::CAPTURING_PHASE && targetNode && targetNode != this && (event->type() == eventNames().submitEvent || event->type() == eventNames().resetEvent)) {
+ event->stopPropagation();
+ return;
+ }
+ HTMLElement::handleLocalEvents(event);
+}
+
+unsigned HTMLFormElement::length() const
+{
+ unsigned len = 0;
+ for (unsigned i = 0; i < m_associatedElements.size(); ++i)
+ if (m_associatedElements[i]->isEnumeratable())
+ ++len;
+ return len;
+}
+
+Node* HTMLFormElement::item(unsigned index)
+{
+ return elements()->item(index);
+}
+
+void HTMLFormElement::submitImplicitly(Event* event, bool fromImplicitSubmissionTrigger)
+{
+ int submissionTriggerCount = 0;
+ for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
+ FormAssociatedElement* formAssociatedElement = m_associatedElements[i];
+ if (!formAssociatedElement->isFormControlElement())
+ continue;
+ HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(formAssociatedElement);
+ if (formElement->isSuccessfulSubmitButton()) {
+ if (formElement->renderer()) {
+ formElement->dispatchSimulatedClick(event);
+ return;
+ }
+ } else if (formElement->canTriggerImplicitSubmission())
+ ++submissionTriggerCount;
+ }
+ if (fromImplicitSubmissionTrigger && submissionTriggerCount == 1)
+ prepareForSubmission(event);
+}
+
+static inline HTMLFormControlElement* submitElementFromEvent(const Event* event)
+{
+ Node* targetNode = event->target()->toNode();
+ if (!targetNode || !targetNode->isElementNode())
+ return 0;
+ Element* targetElement = static_cast<Element*>(targetNode);
+ if (!targetElement->isFormControlElement())
+ return 0;
+ return static_cast<HTMLFormControlElement*>(targetElement);
+}
+
+bool HTMLFormElement::validateInteractively(Event* event)
+{
+ ASSERT(event);
+ if (!document()->page() || !document()->page()->settings()->interactiveFormValidationEnabled() || noValidate())
+ return true;
+
+ HTMLFormControlElement* submitElement = submitElementFromEvent(event);
+ if (submitElement && submitElement->formNoValidate())
+ return true;
+
+ for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
+ if (m_associatedElements[i]->isFormControlElement())
+ static_cast<HTMLFormControlElement*>(m_associatedElements[i])->hideVisibleValidationMessage();
+ }
+
+ Vector<RefPtr<FormAssociatedElement> > unhandledInvalidControls;
+ collectUnhandledInvalidControls(unhandledInvalidControls);
+ if (unhandledInvalidControls.isEmpty())
+ return true;
+ // If the form has invalid controls, abort submission.
+
+ RefPtr<HTMLFormElement> protector(this);
+ // Focus on the first focusable control and show a validation message.
+ for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) {
+ FormAssociatedElement* unhandledAssociatedElement = unhandledInvalidControls[i].get();
+ HTMLElement* unhandled = toHTMLElement(unhandledAssociatedElement);
+ if (unhandled->isFocusable() && unhandled->inDocument()) {
+ RefPtr<Document> originalDocument(unhandled->document());
+ unhandled->scrollIntoViewIfNeeded(false);
+ // scrollIntoViewIfNeeded() dispatches events, so the state
+ // of 'unhandled' might be changed so it's no longer focusable or
+ // moved to another document.
+ if (unhandled->isFocusable() && unhandled->inDocument() && originalDocument == unhandled->document()) {
+ unhandled->focus();
+ if (unhandled->isFormControlElement())
+ static_cast<HTMLFormControlElement*>(unhandled)->updateVisibleValidationMessage();
+ break;
+ }
+ }
+ }
+ // Warn about all of unfocusable controls.
+ if (Frame* frame = document()->frame()) {
+ for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) {
+ FormAssociatedElement* unhandledAssociatedElement = unhandledInvalidControls[i].get();
+ HTMLElement* unhandled = toHTMLElement(unhandledAssociatedElement);
+ if (unhandled->isFocusable() && unhandled->inDocument())
+ continue;
+ String message("An invalid form control with name='%name' is not focusable.");
+ message.replace("%name", unhandledAssociatedElement->name());
+ frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, ErrorMessageLevel, message, 0, document()->url().string());
+ }
+ }
+ return false;
+}
+
+bool HTMLFormElement::prepareForSubmission(Event* event)
+{
+ Frame* frame = document()->frame();
+ if (m_isSubmittingOrPreparingForSubmission || !frame)
+ return m_isSubmittingOrPreparingForSubmission;
+
+ m_isSubmittingOrPreparingForSubmission = true;
+ m_shouldSubmit = false;
+
+ // Interactive validation must be done before dispatching the submit event.
+ if (!validateInteractively(event)) {
+ m_isSubmittingOrPreparingForSubmission = false;
+ return false;
+ }
+
+ frame->loader()->client()->dispatchWillSendSubmitEvent(this);
+
+ if (dispatchEvent(Event::create(eventNames().submitEvent, true, true)))
+ m_shouldSubmit = true;
+
+ m_isSubmittingOrPreparingForSubmission = false;
+
+ if (m_shouldSubmit)
+ submit(event, true, true, NotSubmittedByJavaScript);
+
+ return m_shouldSubmit;
+}
+
+void HTMLFormElement::submit()
+{
+ submit(0, false, true, NotSubmittedByJavaScript);
+}
+
+void HTMLFormElement::submitFromJavaScript()
+{
+ Frame* frame = document()->frame();
+ if (!frame)
+ return;
+ submit(0, false, frame->script()->anyPageIsProcessingUserGesture(), SubmittedByJavaScript);
+}
+
+void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger formSubmissionTrigger)
+{
+ FrameView* view = document()->view();
+ Frame* frame = document()->frame();
+ if (!view || !frame)
+ return;
+
+ if (m_isSubmittingOrPreparingForSubmission) {
+ m_shouldSubmit = true;
+ return;
+ }
+
+ m_isSubmittingOrPreparingForSubmission = true;
+ m_wasUserSubmitted = processingUserGesture;
+
+ HTMLFormControlElement* firstSuccessfulSubmitButton = 0;
+ bool needButtonActivation = activateSubmitButton; // do we need to activate a submit button?
+
+ for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
+ FormAssociatedElement* associatedElement = m_associatedElements[i];
+ if (!associatedElement->isFormControlElement())
+ continue;
+ if (needButtonActivation) {
+ HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(associatedElement);
+ if (control->isActivatedSubmit())
+ needButtonActivation = false;
+ else if (firstSuccessfulSubmitButton == 0 && control->isSuccessfulSubmitButton())
+ firstSuccessfulSubmitButton = control;
+ }
+ }
+
+ if (needButtonActivation && firstSuccessfulSubmitButton)
+ firstSuccessfulSubmitButton->setActivatedSubmit(true);
+
+ frame->loader()->submitForm(FormSubmission::create(this, m_attributes, event, !processingUserGesture, formSubmissionTrigger));
+
+ if (needButtonActivation && firstSuccessfulSubmitButton)
+ firstSuccessfulSubmitButton->setActivatedSubmit(false);
+
+ m_shouldSubmit = false;
+ m_isSubmittingOrPreparingForSubmission = false;
+}
+
+void HTMLFormElement::reset()
+{
+ Frame* frame = document()->frame();
+ if (m_isInResetFunction || !frame)
+ return;
+
+ m_isInResetFunction = true;
+
+ if (!dispatchEvent(Event::create(eventNames().resetEvent, true, true))) {
+ m_isInResetFunction = false;
+ return;
+ }
+
+ for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
+ if (m_associatedElements[i]->isFormControlElement())
+ static_cast<HTMLFormControlElement*>(m_associatedElements[i])->reset();
+ }
+
+ m_isInResetFunction = false;
+}
+
+void HTMLFormElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == actionAttr)
+ m_attributes.parseAction(attr->value());
+ else if (attr->name() == targetAttr)
+ m_attributes.setTarget(attr->value());
+ else if (attr->name() == methodAttr)
+ m_attributes.parseMethodType(attr->value());
+ else if (attr->name() == enctypeAttr)
+ m_attributes.parseEncodingType(attr->value());
+ else if (attr->name() == accept_charsetAttr)
+ m_attributes.setAcceptCharset(attr->value());
+ else if (attr->name() == autocompleteAttr) {
+ if (!autoComplete())
+ document()->registerForDocumentActivationCallbacks(this);
+ else
+ document()->unregisterForDocumentActivationCallbacks(this);
+ } else if (attr->name() == onsubmitAttr)
+ setAttributeEventListener(eventNames().submitEvent, createAttributeEventListener(this, attr));
+ else if (attr->name() == onresetAttr)
+ setAttributeEventListener(eventNames().resetEvent, createAttributeEventListener(this, attr));
+ else if (attr->name() == nameAttr) {
+ const AtomicString& newName = attr->value();
+ if (inDocument() && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->addNamedItem(newName);
+ }
+ m_name = newName;
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+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)
+{
+ // Compares the position of the form element and the inserted element.
+ // Updates the indeces in order to the relation of the position:
+ unsigned short position = compareDocumentPosition(element);
+ if (position & DOCUMENT_POSITION_CONTAINS)
+ ++m_associatedElementsAfterIndex;
+ else if (position & DOCUMENT_POSITION_PRECEDING) {
+ ++m_associatedElementsBeforeIndex;
+ ++m_associatedElementsAfterIndex;
+ }
+
+ if (m_associatedElements.isEmpty())
+ return 0;
+
+ // Does binary search on m_associatedElements in order to find the index
+ // to be inserted.
+ unsigned left = 0, right = m_associatedElements.size() - 1;
+ while (left != right) {
+ unsigned middle = left + ((right - left) / 2);
+ position = element->compareDocumentPosition(toHTMLElement(m_associatedElements[middle]));
+ if (position & DOCUMENT_POSITION_FOLLOWING)
+ right = middle;
+ else
+ left = middle + 1;
+ }
+
+ position = element->compareDocumentPosition(toHTMLElement(m_associatedElements[left]));
+ if (position & DOCUMENT_POSITION_FOLLOWING)
+ return left;
+ return left + 1;
+}
+
+unsigned HTMLFormElement::formElementIndex(FormAssociatedElement* associatedElement)
+{
+ HTMLElement* element = toHTMLElement(associatedElement);
+ // Treats separately the case where this element has the form attribute
+ // for performance consideration.
+ if (element->fastHasAttribute(formAttr))
+ return formElementIndexWithFormAttribute(element);
+
+ // Check for the special case where this element is the very last thing in
+ // the form's tree of children; we don't want to walk the entire tree in that
+ // common case that occurs during parsing; instead we'll just return a value
+ // that says "add this form element to the end of the array".
+ if (element->traverseNextNode(this)) {
+ unsigned i = m_associatedElementsBeforeIndex;
+ for (Node* node = this; node; node = node->traverseNextNode(this)) {
+ if (node == element) {
+ ++m_associatedElementsAfterIndex;
+ return i;
+ }
+ if (node->isHTMLElement()
+ && (static_cast<Element*>(node)->isFormControlElement()
+ || node->hasTagName(objectTag))
+ && static_cast<HTMLElement*>(node)->form() == this)
+ ++i;
+ }
+ }
+ return m_associatedElementsAfterIndex++;
+}
+
+void HTMLFormElement::registerFormElement(FormAssociatedElement* e)
+{
+ if (e->isFormControlElement()) {
+ HTMLFormControlElement* element = static_cast<HTMLFormControlElement*>(e);
+ document()->checkedRadioButtons().removeButton(element);
+ m_checkedRadioButtons.addButton(element);
+ }
+ m_associatedElements.insert(formElementIndex(e), e);
+}
+
+void HTMLFormElement::removeFormElement(FormAssociatedElement* e)
+{
+ if (e->isFormControlElement())
+ m_checkedRadioButtons.removeButton(static_cast<HTMLFormControlElement*>(e));
+ HTMLElement* element = toHTMLElement(e);
+ if (element->fastHasAttribute(formAttr)) {
+ unsigned index;
+ for (index = 0; index < m_associatedElements.size(); ++index)
+ if (m_associatedElements[index] == e)
+ break;
+ ASSERT(index < m_associatedElements.size());
+ if (index < m_associatedElementsBeforeIndex)
+ --m_associatedElementsBeforeIndex;
+ if (index < m_associatedElementsAfterIndex)
+ --m_associatedElementsAfterIndex;
+ } else
+ --m_associatedElementsAfterIndex;
+ removeFromVector(m_associatedElements, e);
+}
+
+bool HTMLFormElement::isURLAttribute(Attribute* attr) const
+{
+ return attr->name() == actionAttr;
+}
+
+void HTMLFormElement::registerImgElement(HTMLImageElement* e)
+{
+ ASSERT(m_imageElements.find(e) == notFound);
+ m_imageElements.append(e);
+}
+
+void HTMLFormElement::removeImgElement(HTMLImageElement* e)
+{
+ ASSERT(m_imageElements.find(e) != notFound);
+ removeFromVector(m_imageElements, e);
+}
+
+PassRefPtr<HTMLCollection> HTMLFormElement::elements()
+{
+ return HTMLFormCollection::create(this);
+}
+
+String HTMLFormElement::name() const
+{
+ return getAttribute(nameAttr);
+}
+
+bool HTMLFormElement::noValidate() const
+{
+ return fastHasAttribute(novalidateAttr);
+}
+
+// FIXME: This function should be removed because it does not do the same thing as the
+// JavaScript binding for action, which treats action as a URL attribute. Last time I
+// (Darin Adler) removed this, someone added it back, so I am leaving it in for now.
+String HTMLFormElement::action() const
+{
+ return getAttribute(actionAttr);
+}
+
+void HTMLFormElement::setAction(const String &value)
+{
+ setAttribute(actionAttr, value);
+}
+
+void HTMLFormElement::setEnctype(const String &value)
+{
+ setAttribute(enctypeAttr, value);
+}
+
+String HTMLFormElement::method() const
+{
+ return getAttribute(methodAttr);
+}
+
+void HTMLFormElement::setMethod(const String &value)
+{
+ setAttribute(methodAttr, value);
+}
+
+String HTMLFormElement::target() const
+{
+ return getAttribute(targetAttr);
+}
+
+bool HTMLFormElement::wasUserSubmitted() const
+{
+ return m_wasUserSubmitted;
+}
+
+HTMLFormControlElement* HTMLFormElement::defaultButton() const
+{
+ for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
+ if (!m_associatedElements[i]->isFormControlElement())
+ continue;
+ HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(m_associatedElements[i]);
+ if (control->isSuccessfulSubmitButton())
+ return control;
+ }
+
+ return 0;
+}
+
+bool HTMLFormElement::checkValidity()
+{
+ Vector<RefPtr<FormAssociatedElement> > controls;
+ collectUnhandledInvalidControls(controls);
+ return controls.isEmpty();
+}
+
+void HTMLFormElement::collectUnhandledInvalidControls(Vector<RefPtr<FormAssociatedElement> >& unhandledInvalidControls)
+{
+ RefPtr<HTMLFormElement> protector(this);
+ // Copy m_associatedElements because event handlers called from
+ // HTMLFormControlElement::checkValidity() might change m_associatedElements.
+ Vector<RefPtr<FormAssociatedElement> > elements;
+ elements.reserveCapacity(m_associatedElements.size());
+ for (unsigned i = 0; i < m_associatedElements.size(); ++i)
+ elements.append(m_associatedElements[i]);
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ if (elements[i]->form() == this && elements[i]->isFormControlElement())
+ static_cast<HTMLFormControlElement*>(elements[i].get())->checkValidity(&unhandledInvalidControls);
+ }
+}
+
+HTMLFormControlElement* HTMLFormElement::elementForAlias(const AtomicString& alias)
+{
+ if (alias.isEmpty() || !m_elementAliases)
+ return 0;
+ return m_elementAliases->get(alias.impl()).get();
+}
+
+void HTMLFormElement::addElementAlias(HTMLFormControlElement* element, const AtomicString& alias)
+{
+ if (alias.isEmpty())
+ return;
+ if (!m_elementAliases)
+ m_elementAliases = adoptPtr(new AliasMap);
+ m_elementAliases->set(alias.impl(), element);
+}
+
+void HTMLFormElement::getNamedElements(const AtomicString& name, Vector<RefPtr<Node> >& namedItems)
+{
+ elements()->namedItems(name, namedItems);
+
+ HTMLFormControlElement* aliasElement = elementForAlias(name);
+ if (aliasElement) {
+ if (namedItems.find(aliasElement) == notFound) {
+ // We have seen it before but it is gone now. Still, we need to return it.
+ // FIXME: The above comment is not clear enough; it does not say why we need to do this.
+ namedItems.append(aliasElement);
+ }
+ }
+ if (namedItems.size() && namedItems.first() != aliasElement)
+ addElementAlias(static_cast<HTMLFormControlElement*>(namedItems.first().get()), name);
+}
+
+void HTMLFormElement::documentDidBecomeActive()
+{
+ ASSERT(!autoComplete());
+
+ for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
+ if (m_associatedElements[i]->isFormControlElement())
+ static_cast<HTMLFormControlElement*>(m_associatedElements[i])->reset();
+ }
+}
+
+void HTMLFormElement::willMoveToNewOwnerDocument()
+{
+ if (!autoComplete())
+ document()->unregisterForDocumentActivationCallbacks(this);
+ HTMLElement::willMoveToNewOwnerDocument();
+}
+
+void HTMLFormElement::didMoveToNewOwnerDocument()
+{
+ if (!autoComplete())
+ document()->registerForDocumentActivationCallbacks(this);
+ HTMLElement::didMoveToNewOwnerDocument();
+}
+
+bool HTMLFormElement::autoComplete() const
+{
+ return !equalIgnoringCase(fastGetAttribute(autocompleteAttr), "off");
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLFormElement.h b/Source/WebCore/html/HTMLFormElement.h
new file mode 100644
index 0000000..bd087b8
--- /dev/null
+++ b/Source/WebCore/html/HTMLFormElement.h
@@ -0,0 +1,176 @@
+/*
+ * 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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLFormElement_h
+#define HTMLFormElement_h
+
+#include "CheckedRadioButtons.h"
+#include "FormState.h"
+#include "FormSubmission.h"
+#include "HTMLElement.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class Event;
+class FormAssociatedElement;
+class FormData;
+class HTMLFormControlElement;
+class HTMLImageElement;
+class HTMLInputElement;
+class HTMLFormCollection;
+class TextEncoding;
+
+struct CollectionCache;
+
+class HTMLFormElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLFormElement> create(Document*);
+ static PassRefPtr<HTMLFormElement> create(const QualifiedName&, Document*);
+ virtual ~HTMLFormElement();
+
+ PassRefPtr<HTMLCollection> elements();
+ void getNamedElements(const AtomicString&, Vector<RefPtr<Node> >&);
+
+ unsigned length() const;
+ Node* item(unsigned index);
+
+ String enctype() const { return m_attributes.encodingType(); }
+ void setEnctype(const String&);
+
+ String encoding() const { return m_attributes.encodingType(); }
+ void setEncoding(const String& value) { setEnctype(value); }
+
+ // FIXME: Rename this function to shouldAutocomplete.
+ bool autoComplete() const;
+
+ // FIXME: Should rename these two functions to say "form control" or "form-associated element" instead of "form element".
+ void registerFormElement(FormAssociatedElement*);
+ void removeFormElement(FormAssociatedElement*);
+
+ void registerImgElement(HTMLImageElement*);
+ void removeImgElement(HTMLImageElement*);
+
+ bool prepareForSubmission(Event*);
+ void submit();
+ void submitFromJavaScript();
+ void reset();
+
+ // Used to indicate a malformed state to keep from applying the bottom margin of the form.
+ // FIXME: Would probably be better to call this wasUnclosed; that's more specific.
+ void setMalformed(bool malformed) { m_wasMalformed = malformed; }
+ bool isMalformed() const { return m_wasMalformed; }
+
+ void setDemoted(bool demoted) { m_wasDemoted = demoted; }
+
+ void submitImplicitly(Event*, bool fromImplicitSubmissionTrigger);
+ bool formWouldHaveSecureSubmission(const String& url);
+
+ String name() const;
+
+ bool noValidate() const;
+
+ String acceptCharset() const { return m_attributes.acceptCharset(); }
+ void setAcceptCharset(const String&);
+
+ String action() const;
+ void setAction(const String&);
+
+ String method() const;
+ void setMethod(const String&);
+
+ virtual String target() const;
+
+ bool wasUserSubmitted() const;
+
+ HTMLFormControlElement* defaultButton() const;
+
+ bool checkValidity();
+
+ HTMLFormControlElement* elementForAlias(const AtomicString&);
+ void addElementAlias(HTMLFormControlElement*, const AtomicString& alias);
+
+ CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
+
+ const Vector<FormAssociatedElement*>& associatedElements() const { return m_associatedElements; }
+
+private:
+ HTMLFormElement(const QualifiedName&, Document*);
+
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
+ virtual void handleLocalEvents(Event*);
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual bool isURLAttribute(Attribute*) const;
+
+ virtual void documentDidBecomeActive();
+
+ virtual void willMoveToNewOwnerDocument();
+ virtual void didMoveToNewOwnerDocument();
+
+ void submit(Event*, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger);
+
+ unsigned formElementIndexWithFormAttribute(Element*);
+ unsigned formElementIndex(FormAssociatedElement*);
+
+ // Returns true if the submission should proceed.
+ bool validateInteractively(Event*);
+
+ // Validates each of the controls, and stores controls of which 'invalid'
+ // event was not canceled to the specified vector.
+ void collectUnhandledInvalidControls(Vector<RefPtr<FormAssociatedElement> >&);
+
+ friend class HTMLFormCollection;
+
+ typedef HashMap<RefPtr<AtomicStringImpl>, RefPtr<HTMLFormControlElement> > AliasMap;
+
+ FormSubmission::Attributes m_attributes;
+ OwnPtr<AliasMap> m_elementAliases;
+ OwnPtr<CollectionCache> m_collectionCache;
+
+ CheckedRadioButtons m_checkedRadioButtons;
+
+ unsigned m_associatedElementsBeforeIndex;
+ unsigned m_associatedElementsAfterIndex;
+ Vector<FormAssociatedElement*> m_associatedElements;
+ Vector<HTMLImageElement*> m_imageElements;
+
+ bool m_wasUserSubmitted;
+ bool m_isSubmittingOrPreparingForSubmission;
+ bool m_shouldSubmit;
+
+ bool m_isInResetFunction;
+
+ bool m_wasMalformed;
+ bool m_wasDemoted;
+
+ AtomicString m_name;
+};
+
+} // namespace WebCore
+
+#endif // HTMLFormElement_h
diff --git a/Source/WebCore/html/HTMLFormElement.idl b/Source/WebCore/html/HTMLFormElement.idl
new file mode 100644
index 0000000..e9759e2
--- /dev/null
+++ b/Source/WebCore/html/HTMLFormElement.idl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ HasIndexGetter,
+ HasOverridingNameGetter
+ ] HTMLFormElement : HTMLElement {
+ readonly attribute HTMLCollection elements;
+ readonly attribute long length;
+
+ attribute [Reflect] DOMString name;
+ attribute [Reflect] boolean noValidate;
+ attribute [Reflect=accept_charset] DOMString acceptCharset;
+ attribute [Reflect, URL] DOMString action;
+ attribute [ConvertNullToNullString] DOMString encoding;
+ attribute [ConvertNullToNullString] DOMString enctype;
+ attribute [Reflect] DOMString method;
+ attribute [Reflect] DOMString target;
+
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ [ImplementationFunction=submitFromJavaScript] void submit();
+#else
+ void submit();
+#endif
+ void reset();
+ boolean checkValidity();
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLFrameElement.cpp b/Source/WebCore/html/HTMLFrameElement.cpp
new file mode 100644
index 0000000..71c8f3f
--- /dev/null
+++ b/Source/WebCore/html/HTMLFrameElement.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLFrameElement.h"
+
+#include "Attribute.h"
+#include "Frame.h"
+#include "HTMLFrameSetElement.h"
+#include "HTMLNames.h"
+#include "RenderFrame.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLFrameElement::HTMLFrameElement(const QualifiedName& tagName, Document* document)
+ : HTMLFrameElementBase(tagName, document)
+ , m_frameBorder(true)
+ , m_frameBorderSet(false)
+ , m_noResize(false)
+{
+ ASSERT(hasTagName(frameTag));
+}
+
+PassRefPtr<HTMLFrameElement> HTMLFrameElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLFrameElement(tagName, document));
+}
+
+bool HTMLFrameElement::rendererIsNeeded(RenderStyle*)
+{
+ // For compatibility, frames render even when display: none is set.
+ return isURLAllowed();
+}
+
+RenderObject* HTMLFrameElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderFrame(this);
+}
+
+static inline HTMLFrameSetElement* containingFrameSetElement(Node* node)
+{
+ while ((node = node->parentNode())) {
+ if (node->hasTagName(framesetTag))
+ return static_cast<HTMLFrameSetElement*>(node);
+ }
+ return 0;
+}
+
+void HTMLFrameElement::attach()
+{
+ HTMLFrameElementBase::attach();
+
+ if (HTMLFrameSetElement* frameSetElement = containingFrameSetElement(this)) {
+ if (!m_frameBorderSet)
+ m_frameBorder = frameSetElement->hasFrameBorder();
+ if (!m_noResize)
+ m_noResize = frameSetElement->noResize();
+ }
+}
+
+void HTMLFrameElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == frameborderAttr) {
+ m_frameBorder = attr->value().toInt();
+ m_frameBorderSet = !attr->isNull();
+ // FIXME: If we are already attached, this has no effect.
+ } else if (attr->name() == noresizeAttr) {
+ m_noResize = true;
+ // FIXME: If we are already attached, this has no effect.
+ // FIXME: Since this does not check attr->isNull(), it can
+ // never reset m_noResize to false if the attribute is removed.
+ } else
+ HTMLFrameElementBase::parseMappedAttribute(attr);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLFrameElement.h b/Source/WebCore/html/HTMLFrameElement.h
new file mode 100644
index 0000000..d8cf509
--- /dev/null
+++ b/Source/WebCore/html/HTMLFrameElement.h
@@ -0,0 +1,57 @@
+/*
+ * 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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLFrameElement_h
+#define HTMLFrameElement_h
+
+#include "HTMLFrameElementBase.h"
+
+namespace WebCore {
+
+class HTMLFrameElement : public HTMLFrameElementBase {
+public:
+ static PassRefPtr<HTMLFrameElement> create(const QualifiedName&, Document*);
+
+ bool hasFrameBorder() const { return m_frameBorder; }
+
+ bool noResize() const { return m_noResize; }
+
+private:
+ HTMLFrameElement(const QualifiedName&, Document*);
+
+ virtual void attach();
+
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ bool m_frameBorder;
+ bool m_frameBorderSet;
+
+ bool m_noResize;
+};
+
+} // namespace WebCore
+
+#endif // HTMLFrameElement_h
diff --git a/Source/WebCore/html/HTMLFrameElement.idl b/Source/WebCore/html/HTMLFrameElement.idl
new file mode 100644
index 0000000..dfe4ef8
--- /dev/null
+++ b/Source/WebCore/html/HTMLFrameElement.idl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLFrameElement : HTMLElement {
+
+ attribute [Reflect] DOMString frameBorder;
+ attribute [Reflect] DOMString longDesc;
+ attribute [Reflect] DOMString marginHeight;
+ attribute [Reflect] DOMString marginWidth;
+ attribute [Reflect] DOMString name;
+ attribute [Reflect] boolean noResize;
+ attribute [Reflect] DOMString scrolling;
+ attribute [Reflect, URL] DOMString src;
+
+ // Introduced in DOM Level 2:
+ readonly attribute [CheckFrameSecurity] Document contentDocument;
+
+ // Extensions
+ readonly attribute DOMWindow contentWindow;
+
+#if defined(ENABLE_SVG) && ENABLE_SVG
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS
+ [SVGCheckSecurityDocument] SVGDocument getSVGDocument()
+ raises(DOMException);
+#endif
+#endif
+
+ attribute [ConvertNullToNullString, CustomSetter] DOMString location;
+
+ readonly attribute long width;
+ readonly attribute long height;
+
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLFrameElementBase.cpp b/Source/WebCore/html/HTMLFrameElementBase.cpp
new file mode 100644
index 0000000..47465c6
--- /dev/null
+++ b/Source/WebCore/html/HTMLFrameElementBase.cpp
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (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, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLFrameElementBase.h"
+
+#include "Attribute.h"
+#include "Document.h"
+#include "EventNames.h"
+#include "FocusController.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameTree.h"
+#include "FrameView.h"
+#include "HTMLFrameSetElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "KURL.h"
+#include "Page.h"
+#include "RenderEmbeddedObject.h"
+#include "RenderFrame.h"
+#include "ScriptController.h"
+#include "ScriptEventListener.h"
+#include "Settings.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tagName, Document* document)
+ : HTMLFrameOwnerElement(tagName, document)
+ , m_scrolling(ScrollbarAuto)
+ , m_marginWidth(-1)
+ , m_marginHeight(-1)
+ , m_checkInDocumentTimer(this, &HTMLFrameElementBase::checkInDocumentTimerFired)
+ , m_viewSource(false)
+ , m_remainsAliveOnRemovalFromTree(false)
+{
+}
+
+bool HTMLFrameElementBase::isURLAllowed() const
+{
+ if (m_URL.isEmpty())
+ return true;
+
+ const KURL& completeURL = document()->completeURL(m_URL);
+
+ if (protocolIsJavaScript(completeURL)) {
+ Document* contentDoc = this->contentDocument();
+ if (contentDoc && !ScriptController::canAccessFromCurrentOrigin(contentDoc->frame()))
+ return false;
+ }
+
+ if (Frame* parentFrame = document()->frame()) {
+ if (parentFrame->page()->frameCount() >= Page::maxNumberOfFrames)
+ return false;
+ }
+
+ // We allow one level of self-reference because some sites depend on that.
+ // But we don't allow more than one.
+ bool foundSelfReference = false;
+ for (Frame* frame = document()->frame(); frame; frame = frame->tree()->parent()) {
+ if (equalIgnoringFragmentIdentifier(frame->loader()->url(), completeURL)) {
+ if (foundSelfReference)
+ return false;
+ foundSelfReference = true;
+ }
+ }
+
+ return true;
+}
+
+void HTMLFrameElementBase::openURL(bool lockHistory, bool lockBackForwardList)
+{
+ if (!isURLAllowed())
+ return;
+
+ if (m_URL.isEmpty())
+ m_URL = blankURL().string();
+
+ Frame* parentFrame = document()->frame();
+ if (!parentFrame)
+ return;
+
+ parentFrame->loader()->subframeLoader()->requestFrame(this, m_URL, m_frameName, lockHistory, lockBackForwardList);
+ if (contentFrame())
+ contentFrame()->setInViewSourceMode(viewSourceMode());
+}
+
+void HTMLFrameElementBase::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == srcAttr)
+ setLocation(stripLeadingAndTrailingHTMLSpaces(attr->value()));
+ else if (isIdAttributeName(attr->name())) {
+ // Important to call through to base for the id attribute so the hasID bit gets set.
+ HTMLFrameOwnerElement::parseMappedAttribute(attr);
+ m_frameName = attr->value();
+ } else if (attr->name() == nameAttr) {
+ m_frameName = attr->value();
+ // FIXME: If we are already attached, this doesn't actually change the frame's name.
+ // FIXME: If we are already attached, this doesn't check for frame name
+ // conflicts and generate a unique frame name.
+ } else if (attr->name() == marginwidthAttr) {
+ m_marginWidth = attr->value().toInt();
+ // FIXME: If we are already attached, this has no effect.
+ } else if (attr->name() == marginheightAttr) {
+ m_marginHeight = attr->value().toInt();
+ // FIXME: If we are already attached, this has no effect.
+ } else if (attr->name() == scrollingAttr) {
+ // Auto and yes both simply mean "allow scrolling." No means "don't allow scrolling."
+ if (equalIgnoringCase(attr->value(), "auto") || equalIgnoringCase(attr->value(), "yes"))
+ m_scrolling = document()->frameElementsShouldIgnoreScrolling() ? ScrollbarAlwaysOff : ScrollbarAuto;
+ else if (equalIgnoringCase(attr->value(), "no"))
+ m_scrolling = ScrollbarAlwaysOff;
+ // FIXME: If we are already attached, this has no effect.
+ } else if (attr->name() == viewsourceAttr) {
+ m_viewSource = !attr->isNull();
+ if (contentFrame())
+ contentFrame()->setInViewSourceMode(viewSourceMode());
+ } else if (attr->name() == onloadAttr)
+ setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
+ else if (attr->name() == onbeforeloadAttr)
+ setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, attr));
+ else if (attr->name() == onbeforeunloadAttr) {
+ // FIXME: should <frame> elements have beforeunload handlers?
+ setAttributeEventListener(eventNames().beforeunloadEvent, createAttributeEventListener(this, attr));
+ } else
+ HTMLFrameOwnerElement::parseMappedAttribute(attr);
+}
+
+void HTMLFrameElementBase::setNameAndOpenURL()
+{
+ m_frameName = getAttribute(nameAttr);
+ if (m_frameName.isNull())
+ m_frameName = getIdAttribute();
+ openURL();
+}
+
+void HTMLFrameElementBase::updateOnReparenting()
+{
+ ASSERT(m_remainsAliveOnRemovalFromTree);
+
+ if (Frame* frame = contentFrame())
+ frame->transferChildFrameToNewDocument();
+}
+
+void HTMLFrameElementBase::insertedIntoDocument()
+{
+ HTMLFrameOwnerElement::insertedIntoDocument();
+
+ if (m_remainsAliveOnRemovalFromTree) {
+ updateOnReparenting();
+ setRemainsAliveOnRemovalFromTree(false);
+ return;
+ }
+ // DocumentFragments don't kick of any loads.
+ if (!document()->frame())
+ return;
+
+ // Loads may cause synchronous javascript execution (e.g. beforeload or
+ // src=javascript), which could try to access the renderer before the normal
+ // parser machinery would call lazyAttach() and set us as needing style
+ // resolve. Any code which expects this to be attached will resolve style
+ // before using renderer(), so this will make sure we attach in time.
+ // FIXME: Normally lazyAttach marks the renderer as attached(), but we don't
+ // want to do that here, as as callers expect to call attach() right after
+ // this and attach() will ASSERT(!attached())
+ ASSERT(!renderer()); // This recalc is unecessary if we already have a renderer.
+ lazyAttach(DoNotSetAttached);
+ setNameAndOpenURL();
+}
+
+void HTMLFrameElementBase::attach()
+{
+ HTMLFrameOwnerElement::attach();
+
+ if (RenderPart* part = renderPart()) {
+ if (Frame* frame = contentFrame())
+ part->setWidget(frame->view());
+ }
+}
+
+KURL HTMLFrameElementBase::location() const
+{
+ return document()->completeURL(getAttribute(srcAttr));
+}
+
+void HTMLFrameElementBase::setLocation(const String& str)
+{
+ Settings* settings = document()->settings();
+ if (settings && settings->needsAcrobatFrameReloadingQuirk() && m_URL == str)
+ return;
+
+ m_URL = AtomicString(str);
+
+ if (inDocument())
+ openURL(false, false);
+}
+
+bool HTMLFrameElementBase::supportsFocus() const
+{
+ return true;
+}
+
+void HTMLFrameElementBase::setFocus(bool received)
+{
+ HTMLFrameOwnerElement::setFocus(received);
+ if (Page* page = document()->page()) {
+ if (received)
+ page->focusController()->setFocusedFrame(contentFrame());
+ else if (page->focusController()->focusedFrame() == contentFrame()) // Focus may have already been given to another frame, don't take it away.
+ page->focusController()->setFocusedFrame(0);
+ }
+}
+
+bool HTMLFrameElementBase::isURLAttribute(Attribute *attr) const
+{
+ return attr->name() == srcAttr;
+}
+
+int HTMLFrameElementBase::width() const
+{
+ document()->updateLayoutIgnorePendingStylesheets();
+ if (!renderBox())
+ return 0;
+ return renderBox()->width();
+}
+
+int HTMLFrameElementBase::height() const
+{
+ document()->updateLayoutIgnorePendingStylesheets();
+ if (!renderBox())
+ return 0;
+ return renderBox()->height();
+}
+
+void HTMLFrameElementBase::setRemainsAliveOnRemovalFromTree(bool value)
+{
+ m_remainsAliveOnRemovalFromTree = value;
+
+ // There is a possibility that JS will do document.adoptNode() on this element but will not insert it into the tree.
+ // Start the async timer that is normally stopped by attach(). If it's not stopped and fires, it'll unload the frame.
+ if (value)
+ m_checkInDocumentTimer.startOneShot(0);
+ else
+ m_checkInDocumentTimer.stop();
+}
+
+void HTMLFrameElementBase::checkInDocumentTimerFired(Timer<HTMLFrameElementBase>*)
+{
+ ASSERT(!attached());
+ ASSERT(m_remainsAliveOnRemovalFromTree);
+
+ m_remainsAliveOnRemovalFromTree = false;
+ willRemove();
+}
+
+void HTMLFrameElementBase::willRemove()
+{
+ if (m_remainsAliveOnRemovalFromTree)
+ return;
+
+ HTMLFrameOwnerElement::willRemove();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLFrameElementBase.h b/Source/WebCore/html/HTMLFrameElementBase.h
new file mode 100644
index 0000000..e5f9c46
--- /dev/null
+++ b/Source/WebCore/html/HTMLFrameElementBase.h
@@ -0,0 +1,97 @@
+/*
+ * 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, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLFrameElementBase_h
+#define HTMLFrameElementBase_h
+
+#include "HTMLFrameOwnerElement.h"
+#include "ScrollTypes.h"
+
+namespace WebCore {
+
+class HTMLFrameElementBase : public HTMLFrameOwnerElement {
+public:
+ KURL location() const;
+ void setLocation(const String&);
+
+ virtual ScrollbarMode scrollingMode() const { return m_scrolling; }
+
+ int marginWidth() const { return m_marginWidth; }
+ int marginHeight() const { return m_marginHeight; }
+
+ int width() const;
+ int height() const;
+
+ void setRemainsAliveOnRemovalFromTree(bool);
+
+protected:
+ HTMLFrameElementBase(const QualifiedName&, Document*);
+
+ bool isURLAllowed() const;
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoDocument();
+ virtual void attach();
+
+private:
+ virtual bool supportsFocus() const;
+ virtual void setFocus(bool);
+
+ virtual bool isURLAttribute(Attribute*) const;
+
+ virtual void willRemove();
+ void checkInDocumentTimerFired(Timer<HTMLFrameElementBase>*);
+ void updateOnReparenting();
+
+ bool viewSourceMode() const { return m_viewSource; }
+
+ void setNameAndOpenURL();
+ void openURL(bool lockHistory = true, bool lockBackForwardList = true);
+
+ AtomicString m_URL;
+ AtomicString m_frameName;
+
+ ScrollbarMode m_scrolling;
+
+ int m_marginWidth;
+ int m_marginHeight;
+
+ // This is a performance optimization some call "magic iframe" which avoids
+ // tearing down the frame hierarchy when a web page calls adoptNode on a
+ // frame owning element but does not immediately insert it into the new
+ // document before JavaScript yields to WebCore. If the element is not yet
+ // in a document by the time this timer fires, the frame hierarchy teardown
+ // will continue. This can also be seen as implementation of:
+ // "Removing an iframe from a Document does not cause its browsing context
+ // to be discarded. Indeed, an iframe's browsing context can survive its
+ // original parent Document if its iframe is moved to another Document."
+ // From HTML5: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#the-iframe-element
+ Timer<HTMLFrameElementBase> m_checkInDocumentTimer;
+
+ bool m_viewSource;
+ bool m_remainsAliveOnRemovalFromTree;
+};
+
+} // namespace WebCore
+
+#endif // HTMLFrameElementBase_h
diff --git a/Source/WebCore/html/HTMLFrameOwnerElement.cpp b/Source/WebCore/html/HTMLFrameOwnerElement.cpp
new file mode 100644
index 0000000..2a7b610
--- /dev/null
+++ b/Source/WebCore/html/HTMLFrameOwnerElement.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLFrameOwnerElement.h"
+
+#include "DOMWindow.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "RenderPart.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(0)
+ , m_sandboxFlags(SandboxNone)
+{
+}
+
+RenderPart* HTMLFrameOwnerElement::renderPart() const
+{
+ // HTMLObjectElement and HTMLEmbedElement may return arbitrary renderers
+ // when using fallback content.
+ if (!renderer() || !renderer()->isRenderPart())
+ return 0;
+ return toRenderPart(renderer());
+}
+
+void HTMLFrameOwnerElement::willRemove()
+{
+ // FIXME: It is unclear why this can't be moved to removedFromDocument()
+ // this is the only implementation of willRemove in WebCore!
+ if (Frame* frame = contentFrame()) {
+ RefPtr<Frame> protect(frame);
+ frame->loader()->frameDetached();
+ frame->disconnectOwnerElement();
+ }
+
+ HTMLElement::willRemove();
+}
+
+HTMLFrameOwnerElement::~HTMLFrameOwnerElement()
+{
+ if (m_contentFrame)
+ m_contentFrame->disconnectOwnerElement();
+}
+
+Document* HTMLFrameOwnerElement::contentDocument() const
+{
+ return m_contentFrame ? m_contentFrame->document() : 0;
+}
+
+DOMWindow* HTMLFrameOwnerElement::contentWindow() const
+{
+ return m_contentFrame ? m_contentFrame->domWindow() : 0;
+}
+
+void HTMLFrameOwnerElement::setSandboxFlags(SandboxFlags flags)
+{
+ if (m_sandboxFlags == flags)
+ return;
+
+ m_sandboxFlags = flags;
+
+ if (Frame* frame = contentFrame())
+ frame->loader()->ownerElementSandboxFlagsChanged();
+}
+
+#if ENABLE(SVG)
+SVGDocument* HTMLFrameOwnerElement::getSVGDocument(ExceptionCode& ec) const
+{
+ Document* doc = contentDocument();
+ if (doc && doc->isSVGDocument())
+ return static_cast<SVGDocument*>(doc);
+ // Spec: http://www.w3.org/TR/SVG/struct.html#InterfaceGetSVGDocument
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+}
+#endif
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLFrameOwnerElement.h b/Source/WebCore/html/HTMLFrameOwnerElement.h
new file mode 100644
index 0000000..f784f4f
--- /dev/null
+++ b/Source/WebCore/html/HTMLFrameOwnerElement.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLFrameOwnerElement_h
+#define HTMLFrameOwnerElement_h
+
+#include "FrameLoaderTypes.h"
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class DOMWindow;
+class Frame;
+class RenderPart;
+
+#if ENABLE(SVG)
+class SVGDocument;
+#endif
+
+class HTMLFrameOwnerElement : public HTMLElement {
+public:
+ virtual ~HTMLFrameOwnerElement();
+
+ Frame* contentFrame() const { return m_contentFrame; }
+ DOMWindow* contentWindow() const;
+ Document* contentDocument() const;
+
+ // Most subclasses use RenderPart (either RenderEmbeddedObject or RenderIFrame)
+ // except for HTMLObjectElement and HTMLEmbedElement which may return any
+ // RenderObject when using fallback content.
+ RenderPart* renderPart() const;
+
+#if ENABLE(SVG)
+ SVGDocument* getSVGDocument(ExceptionCode&) const;
+#endif
+
+ virtual ScrollbarMode scrollingMode() const { return ScrollbarAuto; }
+
+ SandboxFlags sandboxFlags() const { return m_sandboxFlags; }
+
+protected:
+ HTMLFrameOwnerElement(const QualifiedName& tagName, Document*);
+
+ void setSandboxFlags(SandboxFlags);
+
+ virtual void willRemove();
+
+private:
+ friend class Frame;
+
+ virtual bool isFrameOwnerElement() const { return true; }
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const { return m_contentFrame; }
+
+ Frame* m_contentFrame;
+ SandboxFlags m_sandboxFlags;
+};
+
+} // namespace WebCore
+
+#endif // HTMLFrameOwnerElement_h
diff --git a/Source/WebCore/html/HTMLFrameSetElement.cpp b/Source/WebCore/html/HTMLFrameSetElement.cpp
new file mode 100644
index 0000000..0bb6c56
--- /dev/null
+++ b/Source/WebCore/html/HTMLFrameSetElement.cpp
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLFrameSetElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "Document.h"
+#include "Event.h"
+#include "EventNames.h"
+#include "Frame.h"
+#include "FrameLoaderClient.h"
+#include "HTMLNames.h"
+#include "Length.h"
+#include "MouseEvent.h"
+#include "RenderFrameSet.h"
+#include "ScriptEventListener.h"
+#include "Text.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLFrameSetElement::HTMLFrameSetElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , m_totalRows(1)
+ , m_totalCols(1)
+ , m_border(6)
+ , m_borderSet(false)
+ , m_borderColorSet(false)
+ , frameborder(true)
+ , frameBorderSet(false)
+ , noresize(false)
+{
+ ASSERT(hasTagName(framesetTag));
+}
+
+PassRefPtr<HTMLFrameSetElement> HTMLFrameSetElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLFrameSetElement(tagName, document));
+}
+
+bool HTMLFrameSetElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == bordercolorAttr) {
+ result = eUniversal;
+ return true;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLFrameSetElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == rowsAttr) {
+ if (!attr->isNull()) {
+ m_rowLengths.set(newLengthArray(attr->value().string(), m_totalRows));
+ setNeedsStyleRecalc();
+ }
+ } else if (attr->name() == colsAttr) {
+ if (!attr->isNull()) {
+ m_colLengths.set(newLengthArray(attr->value().string(), m_totalCols));
+ setNeedsStyleRecalc();
+ }
+ } else if (attr->name() == frameborderAttr) {
+ if (!attr->isNull()) {
+ // false or "no" or "0"..
+ if (attr->value().toInt() == 0) {
+ frameborder = false;
+ m_border = 0;
+ }
+ frameBorderSet = true;
+ } else {
+ frameborder = false;
+ frameBorderSet = false;
+ }
+ } else if (attr->name() == noresizeAttr) {
+ noresize = true;
+ } else if (attr->name() == borderAttr) {
+ if (!attr->isNull()) {
+ m_border = attr->value().toInt();
+ if (!m_border)
+ frameborder = false;
+ m_borderSet = true;
+ } else
+ m_borderSet = false;
+ } else if (attr->name() == bordercolorAttr) {
+ m_borderColorSet = attr->decl();
+ if (!attr->decl() && !attr->isEmpty()) {
+ addCSSColor(attr, CSSPropertyBorderColor, attr->value());
+ m_borderColorSet = true;
+ }
+ } else if (attr->name() == onloadAttr)
+ document()->setWindowAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onbeforeunloadAttr)
+ document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onunloadAttr)
+ document()->setWindowAttributeEventListener(eventNames().unloadEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onblurAttr)
+ document()->setWindowAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onfocusAttr)
+ document()->setWindowAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onfocusinAttr)
+ document()->setWindowAttributeEventListener(eventNames().focusinEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onfocusoutAttr)
+ document()->setWindowAttributeEventListener(eventNames().focusoutEvent, createAttributeEventListener(document()->frame(), attr));
+#if ENABLE(ORIENTATION_EVENTS)
+ else if (attr->name() == onorientationchangeAttr)
+ document()->setWindowAttributeEventListener(eventNames().orientationchangeEvent, createAttributeEventListener(document()->frame(), attr));
+#endif
+ else if (attr->name() == onhashchangeAttr)
+ document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onresizeAttr)
+ document()->setWindowAttributeEventListener(eventNames().resizeEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onscrollAttr)
+ document()->setWindowAttributeEventListener(eventNames().scrollEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onstorageAttr)
+ document()->setWindowAttributeEventListener(eventNames().storageEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == ononlineAttr)
+ document()->setWindowAttributeEventListener(eventNames().onlineEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onofflineAttr)
+ document()->setWindowAttributeEventListener(eventNames().offlineEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onpopstateAttr)
+ document()->setWindowAttributeEventListener(eventNames().popstateEvent, createAttributeEventListener(document()->frame(), attr));
+ else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+bool HTMLFrameSetElement::rendererIsNeeded(RenderStyle *style)
+{
+ // For compatibility, frames render even when display: none is set.
+ // However, we delay creating a renderer until stylesheets have loaded.
+ return style->isStyleAvailable();
+}
+
+RenderObject *HTMLFrameSetElement::createRenderer(RenderArena *arena, RenderStyle *style)
+{
+ if (style->contentData())
+ return RenderObject::createObject(this, style);
+
+ return new (arena) RenderFrameSet(this);
+}
+
+void HTMLFrameSetElement::attach()
+{
+ // Inherit default settings from parent frameset
+ // FIXME: This is not dynamic.
+ for (ContainerNode* node = parentNode(); node; node = node->parentNode()) {
+ if (node->hasTagName(framesetTag)) {
+ HTMLFrameSetElement* frameset = static_cast<HTMLFrameSetElement*>(node);
+ if (!frameBorderSet)
+ frameborder = frameset->hasFrameBorder();
+ if (frameborder) {
+ if (!m_borderSet)
+ m_border = frameset->border();
+ if (!m_borderColorSet)
+ m_borderColorSet = frameset->hasBorderColor();
+ }
+ if (!noresize)
+ noresize = frameset->noResize();
+ break;
+ }
+ }
+
+ HTMLElement::attach();
+}
+
+void HTMLFrameSetElement::defaultEventHandler(Event* evt)
+{
+ if (evt->isMouseEvent() && !noresize && renderer() && renderer()->isFrameSet()) {
+ if (toRenderFrameSet(renderer())->userResize(static_cast<MouseEvent*>(evt))) {
+ evt->setDefaultHandled();
+ return;
+ }
+ }
+ HTMLElement::defaultEventHandler(evt);
+}
+
+void HTMLFrameSetElement::recalcStyle(StyleChange ch)
+{
+ if (needsStyleRecalc() && renderer()) {
+ renderer()->setNeedsLayout(true);
+#ifdef ANDROID_FLATTEN_FRAMESET
+ static_cast<RenderFrameSet*>(renderer())->setGridNeedsLayout();
+#endif
+ clearNeedsStyleRecalc();
+ }
+ HTMLElement::recalcStyle(ch);
+}
+
+void HTMLFrameSetElement::insertedIntoDocument()
+{
+ HTMLElement::insertedIntoDocument();
+ if (Frame* frame = document()->frame())
+ frame->loader()->client()->dispatchDidBecomeFrameset(document()->isFrameSet());
+}
+
+void HTMLFrameSetElement::removedFromDocument()
+{
+ HTMLElement::removedFromDocument();
+ if (Frame* frame = document()->frame())
+ frame->loader()->client()->dispatchDidBecomeFrameset(document()->isFrameSet());
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLFrameSetElement.h b/Source/WebCore/html/HTMLFrameSetElement.h
new file mode 100644
index 0000000..bdbec6a
--- /dev/null
+++ b/Source/WebCore/html/HTMLFrameSetElement.h
@@ -0,0 +1,102 @@
+/*
+ * 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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLFrameSetElement_h
+#define HTMLFrameSetElement_h
+
+#include <wtf/OwnArrayPtr.h>
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLFrameSetElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLFrameSetElement> create(const QualifiedName&, Document*);
+
+ bool hasFrameBorder() const { return frameborder; }
+ bool noResize() const { return noresize; }
+
+ int totalRows() const { return m_totalRows; }
+ int totalCols() const { return m_totalCols; }
+ int border() const { return m_border; }
+
+ bool hasBorderColor() const { return m_borderColorSet; }
+
+ const Length* rowLengths() const { return m_rowLengths.get(); }
+ const Length* colLengths() const { return m_colLengths.get(); }
+
+ // 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*);
+
+ virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void attach();
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ virtual void defaultEventHandler(Event*);
+
+ virtual void recalcStyle(StyleChange);
+
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
+ OwnArrayPtr<Length> m_rowLengths;
+ OwnArrayPtr<Length> m_colLengths;
+
+ int m_totalRows;
+ int m_totalCols;
+
+ int m_border;
+ bool m_borderSet;
+
+ bool m_borderColorSet;
+
+ bool frameborder;
+ bool frameBorderSet;
+ bool noresize;
+};
+
+} // namespace WebCore
+
+#endif // HTMLFrameSetElement_h
diff --git a/Source/WebCore/html/HTMLFrameSetElement.idl b/Source/WebCore/html/HTMLFrameSetElement.idl
new file mode 100644
index 0000000..06aab6a
--- /dev/null
+++ b/Source/WebCore/html/HTMLFrameSetElement.idl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2006, 2007, 2009, 2010 Apple Inc. All rights reserve
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ HasOverridingNameGetter
+ ] HTMLFrameSetElement : HTMLElement {
+ attribute [Reflect] DOMString cols;
+ attribute [Reflect] DOMString rows;
+
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
+ // Event handler attributes
+ attribute [DontEnum, WindowEventListener] EventListener onbeforeunload;
+ attribute [DontEnum, WindowEventListener] EventListener onhashchange;
+ attribute [DontEnum, WindowEventListener] EventListener onmessage;
+ attribute [DontEnum, WindowEventListener] EventListener onoffline;
+ attribute [DontEnum, WindowEventListener] EventListener ononline;
+ attribute [DontEnum, WindowEventListener] EventListener onpopstate;
+ attribute [DontEnum, WindowEventListener] EventListener onresize;
+ attribute [DontEnum, WindowEventListener] EventListener onstorage;
+ attribute [DontEnum, WindowEventListener] EventListener onunload;
+
+#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS
+ attribute [DontEnum] EventListener onorientationchange;
+#endif
+
+ // Overrides of Element attributes (with different implementation in bindings).
+ attribute [DontEnum, WindowEventListener] EventListener onblur;
+ attribute [DontEnum, WindowEventListener] EventListener onerror;
+ attribute [DontEnum, WindowEventListener] EventListener onfocus;
+ attribute [DontEnum, WindowEventListener] EventListener onload;
+
+ // Not implemented yet.
+ // attribute [DontEnum, WindowEventListener] EventListener onafterprint;
+ // attribute [DontEnum, WindowEventListener] EventListener onbeforeprint;
+ // attribute [DontEnum, WindowEventListener] EventListener onredo;
+ // attribute [DontEnum, WindowEventListener] EventListener onundo;
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLHRElement.cpp b/Source/WebCore/html/HTMLHRElement.cpp
new file mode 100644
index 0000000..44aa052
--- /dev/null
+++ b/Source/WebCore/html/HTMLHRElement.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLHRElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLHRElement::HTMLHRElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(hrTag));
+}
+
+PassRefPtr<HTMLHRElement> HTMLHRElement::create(Document* document)
+{
+ return adoptRef(new HTMLHRElement(hrTag, document));
+}
+
+PassRefPtr<HTMLHRElement> HTMLHRElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLHRElement(tagName, document));
+}
+
+bool HTMLHRElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == alignAttr ||
+ attrName == widthAttr ||
+ attrName == colorAttr ||
+ attrName == sizeAttr ||
+ attrName == noshadeAttr) {
+ result = eHR;
+ return false;
+ }
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLHRElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == alignAttr) {
+ if (equalIgnoringCase(attr->value(), "left")) {
+ addCSSProperty(attr, CSSPropertyMarginLeft, "0");
+ addCSSProperty(attr, CSSPropertyMarginRight, CSSValueAuto);
+ } else if (equalIgnoringCase(attr->value(), "right")) {
+ addCSSProperty(attr, CSSPropertyMarginLeft, CSSValueAuto);
+ addCSSProperty(attr, CSSPropertyMarginRight, "0");
+ } else {
+ addCSSProperty(attr, CSSPropertyMarginLeft, CSSValueAuto);
+ addCSSProperty(attr, CSSPropertyMarginRight, CSSValueAuto);
+ }
+ } else if (attr->name() == widthAttr) {
+ bool ok;
+ int v = attr->value().toInt(&ok);
+ if (ok && !v)
+ addCSSLength(attr, CSSPropertyWidth, "1");
+ else
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
+ } else if (attr->name() == colorAttr) {
+ addCSSProperty(attr, CSSPropertyBorderTopStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderRightStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderBottomStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderLeftStyle, CSSValueSolid);
+ addCSSColor(attr, CSSPropertyBorderColor, attr->value());
+ addCSSColor(attr, CSSPropertyBackgroundColor, attr->value());
+ } else if (attr->name() == noshadeAttr) {
+ addCSSProperty(attr, CSSPropertyBorderTopStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderRightStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderBottomStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderLeftStyle, CSSValueSolid);
+ addCSSColor(attr, CSSPropertyBorderColor, String("grey"));
+ addCSSColor(attr, CSSPropertyBackgroundColor, String("grey"));
+ } else if (attr->name() == sizeAttr) {
+ StringImpl* si = attr->value().impl();
+ int size = si->toInt();
+ if (size <= 1)
+ addCSSProperty(attr, CSSPropertyBorderBottomWidth, String("0"));
+ else
+ addCSSLength(attr, CSSPropertyHeight, String::number(size-2));
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLHRElement.h b/Source/WebCore/html/HTMLHRElement.h
new file mode 100644
index 0000000..e86bb56
--- /dev/null
+++ b/Source/WebCore/html/HTMLHRElement.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLHRElement_h
+#define HTMLHRElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLHRElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLHRElement> create(Document*);
+ static PassRefPtr<HTMLHRElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLHRElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+};
+
+} // namespace WebCore
+
+#endif // HTMLHRElement_h
diff --git a/Source/WebCore/html/HTMLHRElement.idl b/Source/WebCore/html/HTMLHRElement.idl
new file mode 100644
index 0000000..23a57da
--- /dev/null
+++ b/Source/WebCore/html/HTMLHRElement.idl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLHRElement : HTMLElement {
+ attribute [Reflect] DOMString align;
+ attribute [Reflect] boolean noShade;
+ attribute [Reflect] DOMString size;
+ attribute [Reflect] DOMString width;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLHeadElement.cpp b/Source/WebCore/html/HTMLHeadElement.cpp
new file mode 100644
index 0000000..8218311
--- /dev/null
+++ b/Source/WebCore/html/HTMLHeadElement.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLHeadElement.h"
+
+#include "HTMLNames.h"
+#include "Text.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLHeadElement::HTMLHeadElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(headTag));
+}
+
+PassRefPtr<HTMLHeadElement> HTMLHeadElement::create(Document* document)
+{
+ return adoptRef(new HTMLHeadElement(headTag, document));
+}
+
+PassRefPtr<HTMLHeadElement> HTMLHeadElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLHeadElement(tagName, document));
+}
+
+}
diff --git a/Source/WebCore/html/HTMLHeadElement.h b/Source/WebCore/html/HTMLHeadElement.h
new file mode 100644
index 0000000..1a5df86
--- /dev/null
+++ b/Source/WebCore/html/HTMLHeadElement.h
@@ -0,0 +1,42 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLHeadElement_h
+#define HTMLHeadElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLHeadElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLHeadElement> create(Document*);
+ static PassRefPtr<HTMLHeadElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLHeadElement(const QualifiedName&, Document*);
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLHeadElement.idl b/Source/WebCore/html/HTMLHeadElement.idl
new file mode 100644
index 0000000..59bdbf0
--- /dev/null
+++ b/Source/WebCore/html/HTMLHeadElement.idl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLHeadElement : HTMLElement {
+ attribute [Reflect] DOMString profile;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLHeadingElement.cpp b/Source/WebCore/html/HTMLHeadingElement.cpp
new file mode 100644
index 0000000..47a9ea3
--- /dev/null
+++ b/Source/WebCore/html/HTMLHeadingElement.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLHeadingElement.h"
+
+namespace WebCore {
+
+inline HTMLHeadingElement::HTMLHeadingElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+}
+
+PassRefPtr<HTMLHeadingElement> HTMLHeadingElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLHeadingElement(tagName, document));
+}
+
+}
diff --git a/Source/WebCore/html/HTMLHeadingElement.h b/Source/WebCore/html/HTMLHeadingElement.h
new file mode 100644
index 0000000..f09cfe3
--- /dev/null
+++ b/Source/WebCore/html/HTMLHeadingElement.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLHeadingElement_h
+#define HTMLHeadingElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLHeadingElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLHeadingElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLHeadingElement(const QualifiedName&, Document*);
+};
+
+} // namespace WebCore
+
+#endif // HTMLHeadingElement_h
diff --git a/Source/WebCore/html/HTMLHeadingElement.idl b/Source/WebCore/html/HTMLHeadingElement.idl
new file mode 100644
index 0000000..e419c1c
--- /dev/null
+++ b/Source/WebCore/html/HTMLHeadingElement.idl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLHeadingElement : HTMLElement {
+ attribute [Reflect] DOMString align;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLHtmlElement.cpp b/Source/WebCore/html/HTMLHtmlElement.cpp
new file mode 100644
index 0000000..59c0d3e
--- /dev/null
+++ b/Source/WebCore/html/HTMLHtmlElement.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLHtmlElement.h"
+
+#include "ApplicationCacheHost.h"
+#include "Document.h"
+#include "DocumentLoader.h"
+#include "DocumentParser.h"
+#include "Frame.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLHtmlElement::HTMLHtmlElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(htmlTag));
+}
+
+PassRefPtr<HTMLHtmlElement> HTMLHtmlElement::create(Document* document)
+{
+ return adoptRef(new HTMLHtmlElement(htmlTag, document));
+}
+
+PassRefPtr<HTMLHtmlElement> HTMLHtmlElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLHtmlElement(tagName, document));
+}
+
+bool HTMLHtmlElement::isURLAttribute(Attribute* attribute) const
+{
+ return attribute->name() == manifestAttr;
+}
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+void HTMLHtmlElement::insertedByParser()
+{
+ // When parsing a fragment, its dummy document has a null parser.
+ if (!document()->parser() || !document()->parser()->documentWasLoadedAsPartOfNavigation())
+ return;
+
+ if (!document()->frame())
+ return;
+
+ DocumentLoader* documentLoader = document()->frame()->loader()->documentLoader();
+ if (!documentLoader)
+ return;
+
+ const AtomicString& manifest = getAttribute(manifestAttr);
+ if (manifest.isEmpty())
+ documentLoader->applicationCacheHost()->selectCacheWithoutManifest();
+ else
+ documentLoader->applicationCacheHost()->selectCacheWithManifest(document()->completeURL(manifest));
+}
+#endif
+
+}
diff --git a/Source/WebCore/html/HTMLHtmlElement.h b/Source/WebCore/html/HTMLHtmlElement.h
new file mode 100644
index 0000000..9cad44e
--- /dev/null
+++ b/Source/WebCore/html/HTMLHtmlElement.h
@@ -0,0 +1,48 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLHtmlElement_h
+#define HTMLHtmlElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLHtmlElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLHtmlElement> create(Document*);
+ static PassRefPtr<HTMLHtmlElement> create(const QualifiedName&, Document*);
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ void insertedByParser();
+#endif
+
+private:
+ HTMLHtmlElement(const QualifiedName&, Document*);
+
+ virtual bool isURLAttribute(Attribute*) const;
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLHtmlElement.idl b/Source/WebCore/html/HTMLHtmlElement.idl
new file mode 100644
index 0000000..03c661c
--- /dev/null
+++ b/Source/WebCore/html/HTMLHtmlElement.idl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLHtmlElement : HTMLElement {
+ attribute [Reflect] DOMString version;
+ attribute [Reflect, URL] DOMString manifest;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLIFrameElement.cpp b/Source/WebCore/html/HTMLIFrameElement.cpp
new file mode 100644
index 0000000..06af093
--- /dev/null
+++ b/Source/WebCore/html/HTMLIFrameElement.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (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, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Ericsson AB. 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLIFrameElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "Frame.h"
+#include "HTMLDocument.h"
+#include "HTMLNames.h"
+#include "RenderIFrame.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLIFrameElement::HTMLIFrameElement(const QualifiedName& tagName, Document* document)
+ : HTMLFrameElementBase(tagName, document)
+{
+ ASSERT(hasTagName(iframeTag));
+}
+
+PassRefPtr<HTMLIFrameElement> HTMLIFrameElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLIFrameElement(tagName, document));
+}
+
+bool HTMLIFrameElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == widthAttr || attrName == heightAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ if (attrName == alignAttr) {
+ result = eReplaced; // Share with <img> since the alignment behavior is the same.
+ return false;
+ }
+
+ if (attrName == frameborderAttr) {
+ result = eReplaced;
+ return false;
+ }
+
+ return HTMLFrameElementBase::mapToEntry(attrName, result);
+}
+
+static SandboxFlags parseSandboxAttribute(Attribute* attribute)
+{
+ if (attribute->isNull())
+ return SandboxNone;
+
+ // Parse the unordered set of unique space-separated tokens.
+ SandboxFlags flags = SandboxAll;
+ const UChar* characters = attribute->value().characters();
+ unsigned length = attribute->value().length();
+ unsigned start = 0;
+ while (true) {
+ while (start < length && isASCIISpace(characters[start]))
+ ++start;
+ if (start >= length)
+ break;
+ unsigned end = start + 1;
+ while (end < length && !isASCIISpace(characters[end]))
+ ++end;
+
+ // Turn off the corresponding sandbox flag if it's set as "allowed".
+ String sandboxToken = String(characters + start, end - start);
+ if (equalIgnoringCase(sandboxToken, "allow-same-origin"))
+ flags &= ~SandboxOrigin;
+ else if (equalIgnoringCase(sandboxToken, "allow-forms"))
+ flags &= ~SandboxForms;
+ else if (equalIgnoringCase(sandboxToken, "allow-scripts"))
+ flags &= ~SandboxScripts;
+ else if (equalIgnoringCase(sandboxToken, "allow-top-navigation"))
+ flags &= ~SandboxTopNavigation;
+
+ start = end + 1;
+ }
+
+ return flags;
+}
+
+void HTMLIFrameElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == widthAttr)
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
+ else if (attr->name() == heightAttr)
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
+ else if (attr->name() == alignAttr)
+ addHTMLAlignment(attr);
+ else if (attr->name() == nameAttr) {
+ const AtomicString& newName = attr->value();
+ if (inDocument() && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeExtraNamedItem(m_name);
+ document->addExtraNamedItem(newName);
+ }
+ m_name = newName;
+ } else if (attr->name() == frameborderAttr) {
+ // Frame border doesn't really match the HTML4 spec definition for iframes. It simply adds
+ // a presentational hint that the border should be off if set to zero.
+ if (!attr->isNull() && !attr->value().toInt())
+ // Add a rule that nulls out our border width.
+ addCSSLength(attr, CSSPropertyBorderWidth, "0");
+ } else if (attr->name() == sandboxAttr)
+ setSandboxFlags(parseSandboxAttribute(attr));
+ else
+ HTMLFrameElementBase::parseMappedAttribute(attr);
+}
+
+bool HTMLIFrameElement::rendererIsNeeded(RenderStyle* style)
+{
+ return isURLAllowed() && style->display() != NONE;
+}
+
+RenderObject* HTMLIFrameElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderIFrame(this);
+}
+
+void HTMLIFrameElement::insertedIntoDocument()
+{
+ if (document()->isHTMLDocument())
+ static_cast<HTMLDocument*>(document())->addExtraNamedItem(m_name);
+
+ HTMLFrameElementBase::insertedIntoDocument();
+}
+
+void HTMLIFrameElement::removedFromDocument()
+{
+ if (document()->isHTMLDocument())
+ static_cast<HTMLDocument*>(document())->removeExtraNamedItem(m_name);
+
+ HTMLFrameElementBase::removedFromDocument();
+}
+
+bool HTMLIFrameElement::isURLAttribute(Attribute* attr) const
+{
+ return attr->name() == srcAttr;
+}
+
+}
diff --git a/Source/WebCore/html/HTMLIFrameElement.h b/Source/WebCore/html/HTMLIFrameElement.h
new file mode 100644
index 0000000..61cd6b6
--- /dev/null
+++ b/Source/WebCore/html/HTMLIFrameElement.h
@@ -0,0 +1,54 @@
+/*
+ * 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, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLIFrameElement_h
+#define HTMLIFrameElement_h
+
+#include "HTMLFrameElementBase.h"
+
+namespace WebCore {
+
+class HTMLIFrameElement : public HTMLFrameElementBase {
+public:
+ static PassRefPtr<HTMLIFrameElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLIFrameElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ virtual bool isURLAttribute(Attribute*) const;
+
+ AtomicString m_name;
+};
+
+} // namespace WebCore
+
+#endif // HTMLIFrameElement_h
diff --git a/Source/WebCore/html/HTMLIFrameElement.idl b/Source/WebCore/html/HTMLIFrameElement.idl
new file mode 100644
index 0000000..7f9e25a
--- /dev/null
+++ b/Source/WebCore/html/HTMLIFrameElement.idl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLIFrameElement : HTMLElement {
+ attribute [Reflect] DOMString align;
+ attribute [Reflect] DOMString frameBorder;
+ attribute [Reflect] DOMString height;
+ attribute [Reflect] DOMString longDesc;
+ attribute [Reflect] DOMString marginHeight;
+ attribute [Reflect] DOMString marginWidth;
+ attribute [Reflect] DOMString name;
+ attribute [Reflect] DOMString sandbox;
+ attribute [Reflect] DOMString scrolling;
+ attribute [Reflect, URL] DOMString src;
+ attribute [Reflect] DOMString width;
+
+ // Introduced in DOM Level 2:
+ readonly attribute [CheckFrameSecurity] Document contentDocument;
+
+ // Extensions
+ readonly attribute DOMWindow contentWindow;
+
+#if defined(ENABLE_SVG) && ENABLE_SVG
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS
+ [SVGCheckSecurityDocument] SVGDocument getSVGDocument()
+ raises(DOMException);
+#endif
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLImageElement.cpp b/Source/WebCore/html/HTMLImageElement.cpp
new file mode 100644
index 0000000..d66075e
--- /dev/null
+++ b/Source/WebCore/html/HTMLImageElement.cpp
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLImageElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "EventNames.h"
+#include "FrameView.h"
+#include "HTMLDocument.h"
+#include "HTMLFormElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "RenderImage.h"
+#include "ScriptEventListener.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLElement(tagName, document)
+ , m_imageLoader(this)
+ , ismap(false)
+ , m_form(form)
+ , m_compositeOperator(CompositeSourceOver)
+{
+ ASSERT(hasTagName(imgTag));
+ if (form)
+ form->registerImgElement(this);
+}
+
+PassRefPtr<HTMLImageElement> HTMLImageElement::create(Document* document)
+{
+ return adoptRef(new HTMLImageElement(imgTag, document));
+}
+
+PassRefPtr<HTMLImageElement> HTMLImageElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLImageElement(tagName, document, form));
+}
+
+HTMLImageElement::~HTMLImageElement()
+{
+ if (m_form)
+ m_form->removeImgElement(this);
+}
+
+PassRefPtr<HTMLImageElement> HTMLImageElement::createForJSConstructor(Document* document, const int* optionalWidth, const int* optionalHeight)
+{
+ RefPtr<HTMLImageElement> image = adoptRef(new HTMLImageElement(imgTag, document));
+ if (optionalWidth)
+ image->setWidth(*optionalWidth);
+ if (optionalHeight > 0)
+ image->setHeight(*optionalHeight);
+ return image.release();
+}
+
+bool HTMLImageElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == widthAttr ||
+ attrName == heightAttr ||
+ attrName == vspaceAttr ||
+ attrName == hspaceAttr ||
+ attrName == valignAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ if (attrName == borderAttr || attrName == alignAttr) {
+ result = eReplaced; // Shared with embed and iframe elements.
+ return false;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLImageElement::parseMappedAttribute(Attribute* attr)
+{
+ const QualifiedName& attrName = attr->name();
+ if (attrName == altAttr) {
+ if (renderer() && renderer()->isImage())
+ toRenderImage(renderer())->updateAltText();
+ } else if (attrName == srcAttr)
+ m_imageLoader.updateFromElementIgnoringPreviousError();
+ else if (attrName == widthAttr)
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
+ else if (attrName == heightAttr)
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
+ else if (attrName == borderAttr) {
+ // border="noborder" -> border="0"
+ addCSSLength(attr, CSSPropertyBorderWidth, attr->value().toInt() ? attr->value() : "0");
+ addCSSProperty(attr, CSSPropertyBorderTopStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderRightStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderBottomStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderLeftStyle, CSSValueSolid);
+ } else if (attrName == vspaceAttr) {
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
+ } else if (attrName == hspaceAttr) {
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
+ } else if (attrName == alignAttr)
+ addHTMLAlignment(attr);
+ else if (attrName == valignAttr)
+ addCSSProperty(attr, CSSPropertyVerticalAlign, attr->value());
+ else if (attrName == usemapAttr) {
+ if (attr->value().string()[0] == '#')
+ usemap = attr->value();
+ else
+ usemap = document()->completeURL(stripLeadingAndTrailingHTMLSpaces(attr->value())).string();
+ setIsLink(!attr->isNull());
+ } else if (attrName == ismapAttr)
+ ismap = true;
+ else if (attrName == onabortAttr)
+ setAttributeEventListener(eventNames().abortEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onloadAttr)
+ setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onbeforeloadAttr)
+ setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, attr));
+ else if (attrName == compositeAttr) {
+ if (!parseCompositeOperator(attr->value(), m_compositeOperator))
+ m_compositeOperator = CompositeSourceOver;
+ } else if (attrName == nameAttr) {
+ const AtomicString& newName = attr->value();
+ if (inDocument() && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->addNamedItem(newName);
+ }
+ m_name = newName;
+ } else if (isIdAttributeName(attr->name())) {
+ const AtomicString& newId = attr->value();
+ if (inDocument() && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeExtraNamedItem(m_id);
+ document->addExtraNamedItem(newId);
+ }
+ m_id = newId;
+ // also call superclass
+ HTMLElement::parseMappedAttribute(attr);
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+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
+ String alt = getAttribute(altAttr);
+ // fall back to title attribute
+ if (alt.isNull())
+ alt = getAttribute(titleAttr);
+ return alt;
+}
+
+RenderObject* HTMLImageElement::createRenderer(RenderArena* arena, RenderStyle* style)
+{
+ if (style->contentData())
+ return RenderObject::createObject(this, style);
+
+ RenderImage* image = new (arena) RenderImage(this);
+ image->setImageResource(RenderImageResource::create());
+ return image;
+}
+
+void HTMLImageElement::attach()
+{
+ HTMLElement::attach();
+
+ if (renderer() && renderer()->isImage() && m_imageLoader.haveFiredBeforeLoadEvent()) {
+ RenderImage* renderImage = toRenderImage(renderer());
+ RenderImageResource* renderImageResource = renderImage->imageResource();
+ if (renderImageResource->hasImage())
+ return;
+ renderImageResource->setCachedImage(m_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 (!m_imageLoader.image() && !renderImageResource->cachedImage())
+ renderImage->setImageSizeForAltText();
+ }
+}
+
+void HTMLImageElement::insertedIntoDocument()
+{
+ if (document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->addNamedItem(m_name);
+ document->addExtraNamedItem(m_id);
+ }
+
+ // If we have been inserted from a renderer-less document,
+ // our loader may have not fetched the image, so do it now.
+ if (!m_imageLoader.image())
+ m_imageLoader.updateFromElement();
+
+ HTMLElement::insertedIntoDocument();
+}
+
+void HTMLImageElement::removedFromDocument()
+{
+ if (document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->removeExtraNamedItem(m_id);
+ }
+
+ HTMLElement::removedFromDocument();
+}
+
+void HTMLImageElement::insertedIntoTree(bool deep)
+{
+ if (!m_form) {
+ // m_form can be non-null if it was set in constructor.
+ for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
+ if (ancestor->hasTagName(formTag)) {
+ m_form = static_cast<HTMLFormElement*>(ancestor);
+ m_form->registerImgElement(this);
+ break;
+ }
+ }
+ }
+
+ HTMLElement::insertedIntoTree(deep);
+}
+
+void HTMLImageElement::removedFromTree(bool deep)
+{
+ if (m_form)
+ m_form->removeImgElement(this);
+ m_form = 0;
+ HTMLElement::removedFromTree(deep);
+}
+
+int HTMLImageElement::width(bool ignorePendingStylesheets) const
+{
+ if (!renderer()) {
+ // check the attribute first for an explicit pixel value
+ bool ok;
+ int width = getAttribute(widthAttr).toInt(&ok);
+ if (ok)
+ return width;
+
+ // if the image is available, use its width
+ if (m_imageLoader.image())
+ return m_imageLoader.image()->imageSize(1.0f).width();
+ }
+
+ if (ignorePendingStylesheets)
+ document()->updateLayoutIgnorePendingStylesheets();
+ else
+ document()->updateLayout();
+
+ RenderBox* box = renderBox();
+ return box ? adjustForAbsoluteZoom(box->contentWidth(), box) : 0;
+}
+
+int HTMLImageElement::height(bool ignorePendingStylesheets) const
+{
+ if (!renderer()) {
+ // check the attribute first for an explicit pixel value
+ bool ok;
+ int height = getAttribute(heightAttr).toInt(&ok);
+ if (ok)
+ return height;
+
+ // if the image is available, use its height
+ if (m_imageLoader.image())
+ return m_imageLoader.image()->imageSize(1.0f).height();
+ }
+
+ if (ignorePendingStylesheets)
+ document()->updateLayoutIgnorePendingStylesheets();
+ else
+ document()->updateLayout();
+
+ RenderBox* box = renderBox();
+ return box ? adjustForAbsoluteZoom(box->contentHeight(), box) : 0;
+}
+
+int HTMLImageElement::naturalWidth() const
+{
+ if (!m_imageLoader.image())
+ return 0;
+
+ return m_imageLoader.image()->imageSize(1.0f).width();
+}
+
+int HTMLImageElement::naturalHeight() const
+{
+ if (!m_imageLoader.image())
+ return 0;
+
+ return m_imageLoader.image()->imageSize(1.0f).height();
+}
+
+bool HTMLImageElement::isURLAttribute(Attribute* attr) const
+{
+ return attr->name() == srcAttr
+ || attr->name() == lowsrcAttr
+ || attr->name() == longdescAttr
+ || (attr->name() == usemapAttr && attr->value().string()[0] != '#');
+}
+
+const AtomicString& HTMLImageElement::alt() const
+{
+ return getAttribute(altAttr);
+}
+
+bool HTMLImageElement::draggable() const
+{
+ // Image elements are draggable by default.
+ return !equalIgnoringCase(getAttribute(draggableAttr), "false");
+}
+
+void HTMLImageElement::setHeight(int value)
+{
+ setAttribute(heightAttr, String::number(value));
+}
+
+KURL HTMLImageElement::src() const
+{
+ return document()->completeURL(getAttribute(srcAttr));
+}
+
+void HTMLImageElement::setSrc(const String& value)
+{
+ setAttribute(srcAttr, value);
+}
+
+void HTMLImageElement::setWidth(int value)
+{
+ setAttribute(widthAttr, String::number(value));
+}
+
+int HTMLImageElement::x() const
+{
+ RenderObject* r = renderer();
+ if (!r)
+ return 0;
+
+ // FIXME: This doesn't work correctly with transforms.
+ FloatPoint absPos = r->localToAbsolute();
+ return absPos.x();
+}
+
+int HTMLImageElement::y() const
+{
+ RenderObject* r = renderer();
+ if (!r)
+ return 0;
+
+ // FIXME: This doesn't work correctly with transforms.
+ FloatPoint absPos = r->localToAbsolute();
+ return absPos.y();
+}
+
+bool HTMLImageElement::complete() const
+{
+ return m_imageLoader.imageComplete();
+}
+
+void HTMLImageElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+{
+ HTMLElement::addSubresourceAttributeURLs(urls);
+
+ addSubresourceURL(urls, src());
+ // FIXME: What about when the usemap attribute begins with "#"?
+ addSubresourceURL(urls, document()->completeURL(getAttribute(usemapAttr)));
+}
+
+void HTMLImageElement::willMoveToNewOwnerDocument()
+{
+ m_imageLoader.elementWillMoveToNewOwnerDocument();
+ HTMLElement::willMoveToNewOwnerDocument();
+}
+
+}
diff --git a/Source/WebCore/html/HTMLImageElement.h b/Source/WebCore/html/HTMLImageElement.h
new file mode 100644
index 0000000..7f38216
--- /dev/null
+++ b/Source/WebCore/html/HTMLImageElement.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2004, 2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLImageElement_h
+#define HTMLImageElement_h
+
+#include "GraphicsTypes.h"
+#include "HTMLElement.h"
+#include "HTMLImageLoader.h"
+
+namespace WebCore {
+
+class HTMLFormElement;
+
+class HTMLImageElement : public HTMLElement {
+ friend class HTMLFormElement;
+public:
+ 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();
+
+ int width(bool ignorePendingStylesheets = false) const;
+ int height(bool ignorePendingStylesheets = false) const;
+
+ int naturalWidth() const;
+ int naturalHeight() const;
+
+ bool isServerMap() const { return ismap && usemap.isEmpty(); }
+
+ 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); }
+
+ const AtomicString& alt() const;
+
+ void setHeight(int);
+
+ KURL src() const;
+ void setSrc(const String&);
+
+ void setWidth(int);
+
+ int x() const;
+ int y() const;
+
+ bool complete() const;
+
+ bool haveFiredLoadEvent() const { return m_imageLoader.haveFiredLoadEvent(); }
+
+protected:
+ HTMLImageElement(const QualifiedName&, Document*, HTMLFormElement* = 0);
+
+ virtual void willMoveToNewOwnerDocument();
+
+private:
+ virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void attach();
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ virtual bool canStartSelection() const { return false; }
+
+ virtual bool isURLAttribute(Attribute*) const;
+
+ virtual bool draggable() const;
+
+ virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+ virtual void insertedIntoTree(bool deep);
+ virtual void removedFromTree(bool deep);
+
+ HTMLImageLoader m_imageLoader;
+ String usemap;
+ bool ismap;
+ HTMLFormElement* m_form;
+ AtomicString m_name;
+ AtomicString m_id;
+ CompositeOperator m_compositeOperator;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLImageElement.idl b/Source/WebCore/html/HTMLImageElement.idl
new file mode 100644
index 0000000..935b721
--- /dev/null
+++ b/Source/WebCore/html/HTMLImageElement.idl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2006, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ GenerateNativeConverter
+ ] HTMLImageElement : HTMLElement {
+ attribute [Reflect] DOMString name;
+ attribute [Reflect] DOMString align;
+ attribute [Reflect] DOMString alt;
+ attribute [Reflect] DOMString border;
+ attribute long height;
+ attribute [Reflect] long hspace;
+ attribute [Reflect] boolean isMap;
+ attribute [Reflect, URL] DOMString longDesc;
+ attribute [Reflect, URL] DOMString src;
+ attribute [Reflect] DOMString useMap;
+ attribute [Reflect] long vspace;
+ attribute long width;
+
+ // Extensions
+ readonly attribute boolean complete;
+ attribute [Reflect,URL] DOMString lowsrc;
+ readonly attribute long naturalHeight;
+ readonly attribute long naturalWidth;
+ readonly attribute long x;
+ readonly attribute long y;
+
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+ // Objective-C extension:
+ readonly attribute DOMString altDisplayString;
+ readonly attribute URL absoluteImageURL;
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLImageLoader.cpp b/Source/WebCore/html/HTMLImageLoader.cpp
new file mode 100644
index 0000000..710c177
--- /dev/null
+++ b/Source/WebCore/html/HTMLImageLoader.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLImageLoader.h"
+
+#include "CachedImage.h"
+#include "Element.h"
+#include "Event.h"
+#include "EventNames.h"
+#include "HTMLNames.h"
+#include "HTMLObjectElement.h"
+#include "HTMLParserIdioms.h"
+#include "Settings.h"
+
+#if USE(JSC)
+#include "JSDOMWindowBase.h"
+#endif
+
+namespace WebCore {
+
+HTMLImageLoader::HTMLImageLoader(Element* node)
+ : ImageLoader(node)
+{
+}
+
+HTMLImageLoader::~HTMLImageLoader()
+{
+}
+
+void HTMLImageLoader::dispatchLoadEvent()
+{
+ bool errorOccurred = image()->errorOccurred();
+ if (!errorOccurred && image()->response().httpStatusCode() >= 400)
+ errorOccurred = element()->hasTagName(HTMLNames::objectTag); // 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();
+ if (settings && settings->usesDashboardBackwardCompatibilityMode() && attr.length() > 7 && attr.startsWith("url(\"") && attr.endsWith("\")"))
+ return attr.string().substring(5, attr.length() - 7);
+#endif
+
+ return stripLeadingAndTrailingHTMLSpaces(attr);
+}
+
+void HTMLImageLoader::notifyFinished(CachedResource*)
+{
+ CachedImage* cachedImage = image();
+
+ Element* elem = element();
+ ImageLoader::notifyFinished(cachedImage);
+
+ bool loadError = cachedImage->errorOccurred() || cachedImage->response().httpStatusCode() >= 400;
+#if USE(JSC)
+ if (!loadError) {
+ if (!elem->inDocument()) {
+ JSC::JSGlobalData* globalData = JSDOMWindowBase::commonJSGlobalData();
+ globalData->heap.reportExtraMemoryCost(cachedImage->encodedSize());
+ }
+ }
+#endif
+
+ if (loadError && elem->hasTagName(HTMLNames::objectTag))
+ static_cast<HTMLObjectElement*>(elem)->renderFallbackContent();
+}
+
+}
diff --git a/Source/WebCore/html/HTMLImageLoader.h b/Source/WebCore/html/HTMLImageLoader.h
new file mode 100644
index 0000000..d3b6068
--- /dev/null
+++ b/Source/WebCore/html/HTMLImageLoader.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLImageLoader_h
+#define HTMLImageLoader_h
+
+#include "ImageLoader.h"
+
+namespace WebCore {
+
+class HTMLImageLoader : public ImageLoader {
+public:
+ HTMLImageLoader(Element*);
+ virtual ~HTMLImageLoader();
+
+ virtual void dispatchLoadEvent();
+ virtual String sourceURI(const AtomicString&) const;
+
+ virtual void notifyFinished(CachedResource*);
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp
new file mode 100644
index 0000000..5ebd640
--- /dev/null
+++ b/Source/WebCore/html/HTMLInputElement.cpp
@@ -0,0 +1,1572 @@
+/*
+ * 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 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLInputElement.h"
+
+#include "AXObjectCache.h"
+#include "Attribute.h"
+#include "BeforeTextInsertedEvent.h"
+#include "CSSPropertyNames.h"
+#include "Document.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
+#include "FileList.h"
+#include "HTMLCollection.h"
+#include "HTMLDataListElement.h"
+#include "HTMLFormElement.h"
+#include "HTMLNames.h"
+#include "HTMLOptionElement.h"
+#include "HTMLParserIdioms.h"
+#include "InputType.h"
+#include "KeyboardEvent.h"
+#include "LocalizedStrings.h"
+#include "MouseEvent.h"
+#include "RenderTextControlSingleLine.h"
+#include "RenderTheme.h"
+#include "RuntimeEnabledFeatures.h"
+#include "ScriptEventListener.h"
+<<<<<<< HEAD:WebCore/html/HTMLInputElement.cpp
+#include "Settings.h"
+#include "StepRange.h"
+#include "TextEvent.h"
+#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
+#include "PlatformBridge.h"
+#endif
+=======
+>>>>>>> webkit.org at r75315:Source/WebCore/html/HTMLInputElement.cpp
+#include "WheelEvent.h"
+#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+const int maxSavedResults = 256;
+
+HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLTextFormControlElement(tagName, document, form)
+ , m_maxResults(-1)
+ , m_isChecked(false)
+ , m_reflectsCheckedAttribute(true)
+ , m_isIndeterminate(false)
+ , m_hasType(false)
+ , m_isActivatedSubmit(false)
+ , m_autocomplete(Uninitialized)
+ , m_isAutofilled(false)
+ , m_inputType(InputType::createText(this))
+{
+ ASSERT(hasTagName(inputTag) || hasTagName(isindexTag));
+}
+
+PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLInputElement(tagName, document, form));
+}
+
+HTMLInputElement::~HTMLInputElement()
+{
+ if (needsActivationCallback())
+ document()->unregisterForDocumentActivationCallbacks(this);
+
+ document()->checkedRadioButtons().removeButton(this);
+
+ // Need to remove this from the form while it is still an HTMLInputElement,
+ // so can't wait for the base class's destructor to do it.
+ removeFromForm();
+}
+
+const AtomicString& HTMLInputElement::formControlName() const
+{
+ return m_data.name();
+}
+
+bool HTMLInputElement::autoComplete() const
+{
+ if (m_autocomplete != Uninitialized)
+ return m_autocomplete == On;
+ return HTMLTextFormControlElement::autoComplete();
+}
+
+void HTMLInputElement::updateCheckedRadioButtons()
+{
+ if (attached() && checked())
+ checkedRadioButtons().addButton(this);
+
+ if (form()) {
+ const Vector<FormAssociatedElement*>& controls = form()->associatedElements();
+ for (unsigned i = 0; i < controls.size(); ++i) {
+ if (!controls[i]->isFormControlElement())
+ continue;
+ HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(controls[i]);
+ if (control->name() != name())
+ continue;
+ if (control->type() != type())
+ continue;
+ control->setNeedsValidityCheck();
+ }
+ } else {
+ // FIXME: Traversing the document is inefficient.
+ for (Node* node = document()->body(); node; node = node->traverseNextNode()) {
+ if (!node->isElementNode())
+ continue;
+ Element* element = static_cast<Element*>(node);
+ if (element->formControlName() != name())
+ continue;
+ if (element->formControlType() != type())
+ continue;
+ HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(element);
+ if (control->form())
+ continue;
+ control->setNeedsValidityCheck();
+ }
+ }
+
+ if (renderer() && renderer()->style()->hasAppearance())
+ renderer()->theme()->stateChanged(renderer(), CheckedState);
+}
+
+bool HTMLInputElement::isValidValue(const String& value) const
+{
+ if (!m_inputType->canSetStringValue()) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ return !m_inputType->typeMismatchFor(value)
+ && !stepMismatch(value)
+ && !rangeUnderflow(value)
+ && !rangeOverflow(value)
+ && !tooLong(value, IgnoreDirtyFlag)
+ && !patternMismatch(value)
+ && !valueMissing(value);
+}
+
+bool HTMLInputElement::typeMismatch() const
+{
+ return m_inputType->typeMismatch();
+}
+
+bool HTMLInputElement::valueMissing(const String& value) const
+{
+ if (!isRequiredFormControl() || readOnly() || disabled())
+ return false;
+ return m_inputType->valueMissing(value);
+}
+
+bool HTMLInputElement::patternMismatch(const String& value) const
+{
+ return m_inputType->patternMismatch(value);
+}
+
+bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
+{
+ // We use isTextType() instead of supportsMaxLength() because of the
+ // 'virtual' overhead.
+ if (!isTextType())
+ return false;
+ int max = maxLength();
+ if (max < 0)
+ return false;
+ if (check == CheckDirtyFlag) {
+ // Return false for the default value even if it is longer than maxLength.
+ bool userEdited = !m_data.value().isNull();
+ if (!userEdited)
+ return false;
+ }
+ return numGraphemeClusters(value) > static_cast<unsigned>(max);
+}
+
+bool HTMLInputElement::rangeUnderflow(const String& value) const
+{
+ return m_inputType->rangeUnderflow(value);
+}
+
+bool HTMLInputElement::rangeOverflow(const String& value) const
+{
+ return m_inputType->rangeOverflow(value);
+}
+
+double HTMLInputElement::minimum() const
+{
+ return m_inputType->minimum();
+}
+
+double HTMLInputElement::maximum() const
+{
+ return m_inputType->maximum();
+}
+
+bool HTMLInputElement::stepMismatch(const String& value) const
+{
+ double step;
+ if (!getAllowedValueStep(&step))
+ return false;
+ return m_inputType->stepMismatch(value, step);
+}
+
+String HTMLInputElement::minimumString() const
+{
+ return m_inputType->serialize(minimum());
+}
+
+String HTMLInputElement::maximumString() const
+{
+ return m_inputType->serialize(maximum());
+}
+
+String HTMLInputElement::stepBaseString() const
+{
+ return m_inputType->serialize(m_inputType->stepBase());
+}
+
+String HTMLInputElement::stepString() const
+{
+ double step;
+ if (!getAllowedValueStep(&step)) {
+ // stepString() should be called only if stepMismatch() can be true.
+ ASSERT_NOT_REACHED();
+ return String();
+ }
+ return serializeForNumberType(step / m_inputType->stepScaleFactor());
+}
+
+String HTMLInputElement::typeMismatchText() const
+{
+ return m_inputType->typeMismatchText();
+}
+
+String HTMLInputElement::valueMissingText() const
+{
+ return m_inputType->valueMissingText();
+}
+
+bool HTMLInputElement::getAllowedValueStep(double* step) const
+{
+ return getAllowedValueStepWithDecimalPlaces(step, 0);
+}
+
+bool HTMLInputElement::getAllowedValueStepWithDecimalPlaces(double* step, unsigned* decimalPlaces) const
+{
+ ASSERT(step);
+ double defaultStep = m_inputType->defaultStep();
+ double stepScaleFactor = m_inputType->stepScaleFactor();
+ if (!isfinite(defaultStep) || !isfinite(stepScaleFactor))
+ return false;
+ const AtomicString& stepString = fastGetAttribute(stepAttr);
+ if (stepString.isEmpty()) {
+ *step = defaultStep * stepScaleFactor;
+ if (decimalPlaces)
+ *decimalPlaces = 0;
+ return true;
+ }
+ if (equalIgnoringCase(stepString, "any"))
+ return false;
+ double parsed;
+ if (!decimalPlaces) {
+ if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
+ *step = defaultStep * stepScaleFactor;
+ return true;
+ }
+ } else {
+ if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) {
+ *step = defaultStep * stepScaleFactor;
+ *decimalPlaces = 0;
+ return true;
+ }
+ }
+ // For date, month, week, the parsed value should be an integer for some types.
+ if (m_inputType->parsedStepValueShouldBeInteger())
+ parsed = max(round(parsed), 1.0);
+ double result = parsed * stepScaleFactor;
+ // For datetime, datetime-local, time, the result should be an integer.
+ if (m_inputType->scaledStepValueShouldBeInteger())
+ result = max(round(result), 1.0);
+ ASSERT(result > 0);
+ *step = result;
+ return true;
+}
+
+void HTMLInputElement::applyStep(double count, ExceptionCode& ec)
+{
+ double step;
+ unsigned stepDecimalPlaces, currentDecimalPlaces;
+ if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces)) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+ const double nan = numeric_limits<double>::quiet_NaN();
+ double current = m_inputType->parseToDoubleWithDecimalPlaces(value(), nan, &currentDecimalPlaces);
+ if (!isfinite(current)) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+ double newValue = current + step * count;
+ if (isinf(newValue)) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+ double acceptableError = m_inputType->acceptableError(step);
+ if (newValue - m_inputType->minimum() < -acceptableError) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+ if (newValue < m_inputType->minimum())
+ newValue = m_inputType->minimum();
+ unsigned baseDecimalPlaces;
+ double base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
+ baseDecimalPlaces = min(baseDecimalPlaces, 16u);
+ if (newValue < pow(10.0, 21.0)) {
+ if (stepMismatch(value())) {
+ double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, currentDecimalPlaces)));
+ newValue = round(newValue * scale) / scale;
+ } else {
+ double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
+ newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
+ }
+ }
+ if (newValue - m_inputType->maximum() > acceptableError) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+ if (newValue > m_inputType->maximum())
+ newValue = m_inputType->maximum();
+ setValueAsNumber(newValue, ec);
+
+ if (AXObjectCache::accessibilityEnabled())
+ document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
+}
+
+void HTMLInputElement::stepUp(int n, ExceptionCode& ec)
+{
+ applyStep(n, ec);
+}
+
+void HTMLInputElement::stepDown(int n, ExceptionCode& ec)
+{
+ applyStep(-n, ec);
+}
+
+bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const
+{
+ if (isTextField())
+ return HTMLFormControlElementWithState::isFocusable();
+ return HTMLFormControlElementWithState::isKeyboardFocusable(event) && m_inputType->isKeyboardFocusable();
+}
+
+bool HTMLInputElement::isMouseFocusable() const
+{
+ if (isTextField())
+ return HTMLFormControlElementWithState::isFocusable();
+ return HTMLFormControlElementWithState::isMouseFocusable();
+}
+
+void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
+{
+ if (isTextField())
+ InputElement::updateFocusAppearance(m_data, this, this, restorePreviousSelection);
+ else
+ HTMLFormControlElementWithState::updateFocusAppearance(restorePreviousSelection);
+}
+
+void HTMLInputElement::aboutToUnload()
+{
+ InputElement::aboutToUnload(this, this);
+}
+
+bool HTMLInputElement::shouldUseInputMethod() const
+{
+ return m_inputType->shouldUseInputMethod();
+}
+
+void HTMLInputElement::handleFocusEvent()
+{
+ InputElement::dispatchFocusEvent(this, this);
+}
+
+void HTMLInputElement::handleBlurEvent()
+{
+ m_inputType->handleBlurEvent();
+ InputElement::dispatchBlurEvent(this, this);
+}
+
+void HTMLInputElement::setType(const String& 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()) {
+ ExceptionCode ec;
+ removeAttribute(typeAttr, ec);
+ } else
+ setAttribute(typeAttr, type);
+}
+
+void HTMLInputElement::updateType()
+{
+ const AtomicString& typeString = fastGetAttribute(typeAttr);
+<<<<<<< HEAD:WebCore/html/HTMLInputElement.cpp
+ DeprecatedInputType newType = typeString.isEmpty() ? TEXT : typeMap->get(typeString);
+#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
+ if (newType == PASSWORD && document()->focusedNode() == this)
+ PlatformBridge::updateTextfield(document()->view(), this, true, String());
+#endif
+
+ // IMPORTANT: Don't allow the type to be changed to FILE after the first
+ // type change, otherwise a JavaScript programmer would be able to set a text
+ // field's value to something like /etc/passwd and then change it to a file field.
+ if (deprecatedInputType() != newType) {
+ if (newType == FILE && m_haveType)
+ // Set the attribute back to the old value.
+ // Useful in case we were called from inside parseMappedAttribute.
+ setAttribute(typeAttr, type());
+ else {
+ checkedRadioButtons().removeButton(this);
+
+ if (newType == FILE && !m_fileList)
+ m_fileList = FileList::create();
+
+ bool wasAttached = attached();
+ if (wasAttached)
+ detach();
+
+ bool didStoreValue = storesValueSeparateFromAttribute();
+ bool wasPasswordField = deprecatedInputType() == PASSWORD;
+ bool didRespectHeightAndWidth = respectHeightAndWidthAttrs();
+ m_deprecatedTypeNumber = newType;
+ m_inputType = InputType::create(this, typeString);
+ setNeedsWillValidateCheck();
+ bool willStoreValue = storesValueSeparateFromAttribute();
+ bool isPasswordField = deprecatedInputType() == PASSWORD;
+ bool willRespectHeightAndWidth = respectHeightAndWidthAttrs();
+
+ if (didStoreValue && !willStoreValue && !m_data.value().isNull()) {
+ setAttribute(valueAttr, m_data.value());
+ m_data.setValue(String());
+ }
+ if (!didStoreValue && willStoreValue)
+ m_data.setValue(sanitizeValue(getAttribute(valueAttr)));
+ else
+ InputElement::updateValueIfNeeded(m_data, this);
+=======
+>>>>>>> webkit.org at r75315:Source/WebCore/html/HTMLInputElement.cpp
+
+ OwnPtr<InputType> newType = InputType::create(this, typeString);
+
+ if (m_hasType && !newType->canChangeFromAnotherType()) {
+ // Set the attribute back to the old value.
+ // Useful in case we were called from inside parseMappedAttribute.
+ setAttribute(typeAttr, type());
+ return;
+ }
+
+ m_hasType = true;
+
+ if (m_inputType->formControlType() == newType->formControlType())
+ return;
+
+ checkedRadioButtons().removeButton(this);
+
+ bool wasAttached = attached();
+ if (wasAttached)
+ detach();
+
+ bool didStoreValue = m_inputType->storesValueSeparateFromAttribute();
+ bool neededActivationCallback = needsActivationCallback();
+ bool didRespectHeightAndWidth = m_inputType->shouldRespectHeightAndWidthAttributes();
+
+ m_inputType = newType.release();
+
+ setNeedsWillValidateCheck();
+
+ bool willStoreValue = m_inputType->storesValueSeparateFromAttribute();
+
+ if (didStoreValue && !willStoreValue && !m_data.value().isNull()) {
+ setAttribute(valueAttr, m_data.value());
+ m_data.setValue(String());
+ }
+ if (!didStoreValue && willStoreValue)
+ m_data.setValue(sanitizeValue(fastGetAttribute(valueAttr)));
+ else
+ InputElement::updateValueIfNeeded(m_data, this);
+
+ if (neededActivationCallback)
+ unregisterForActivationCallbackIfNeeded();
+ else
+ registerForActivationCallbackIfNeeded();
+
+ if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
+ NamedNodeMap* map = attributeMap();
+ ASSERT(map);
+ if (Attribute* height = map->getAttributeItem(heightAttr))
+ attributeChanged(height, false);
+ if (Attribute* width = map->getAttributeItem(widthAttr))
+ attributeChanged(width, false);
+ if (Attribute* align = map->getAttributeItem(alignAttr))
+ attributeChanged(align, false);
+ }
+
+ if (wasAttached) {
+ attach();
+ if (document()->focusedNode() == this)
+ updateFocusAppearance(true);
+ }
+
+ checkedRadioButtons().addButton(this);
+
+ setNeedsValidityCheck();
+ InputElement::notifyFormStateChanged(this);
+}
+
+const AtomicString& HTMLInputElement::formControlType() const
+{
+ return m_inputType->formControlType();
+}
+
+bool HTMLInputElement::saveFormControlState(String& result) const
+{
+ return m_inputType->saveFormControlState(result);
+}
+
+void HTMLInputElement::restoreFormControlState(const String& state)
+{
+ m_inputType->restoreFormControlState(state);
+}
+
+bool HTMLInputElement::canStartSelection() const
+{
+ if (!isTextField())
+ return false;
+ return HTMLFormControlElementWithState::canStartSelection();
+}
+
+bool HTMLInputElement::canHaveSelection() const
+{
+ return isTextField();
+}
+
+void HTMLInputElement::accessKeyAction(bool sendToAnyElement)
+{
+ m_inputType->accessKeyAction(sendToAnyElement);
+}
+
+bool HTMLInputElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (((attrName == heightAttr || attrName == widthAttr) && m_inputType->shouldRespectHeightAndWidthAttributes())
+ || attrName == vspaceAttr
+ || attrName == hspaceAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ if (attrName == alignAttr && m_inputType->shouldRespectAlignAttribute()) {
+ // Share with <img> since the alignment behavior is the same.
+ result = eReplaced;
+ return false;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLInputElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == nameAttr) {
+ checkedRadioButtons().removeButton(this);
+ m_data.setName(attr->value());
+ checkedRadioButtons().addButton(this);
+ HTMLFormControlElementWithState::parseMappedAttribute(attr);
+ } else if (attr->name() == autocompleteAttr) {
+ if (equalIgnoringCase(attr->value(), "off")) {
+ m_autocomplete = Off;
+ registerForActivationCallbackIfNeeded();
+ } else {
+ bool needsToUnregister = m_autocomplete == Off;
+
+ if (attr->isEmpty())
+ m_autocomplete = Uninitialized;
+ else
+ m_autocomplete = On;
+
+ if (needsToUnregister)
+ unregisterForActivationCallbackIfNeeded();
+ }
+ } else if (attr->name() == typeAttr) {
+ updateType();
+ } else if (attr->name() == valueAttr) {
+ // We only need to setChanged if the form is looking at the default value right now.
+ if (m_data.value().isNull())
+ setNeedsStyleRecalc();
+ setFormControlValueMatchesRenderer(false);
+ setNeedsValidityCheck();
+ } else if (attr->name() == checkedAttr) {
+ if (m_reflectsCheckedAttribute) {
+ setChecked(!attr->isNull());
+ m_reflectsCheckedAttribute = true;
+ }
+ setNeedsValidityCheck();
+ } else if (attr->name() == maxlengthAttr) {
+ InputElement::parseMaxLengthAttribute(m_data, this, this, attr);
+ setNeedsValidityCheck();
+ } else if (attr->name() == sizeAttr)
+ InputElement::parseSizeAttribute(m_data, this, attr);
+ else if (attr->name() == altAttr)
+ m_inputType->altAttributeChanged();
+ else if (attr->name() == srcAttr)
+ m_inputType->srcAttributeChanged();
+ else if (attr->name() == usemapAttr || attr->name() == accesskeyAttr) {
+ // FIXME: ignore for the moment
+ } else if (attr->name() == vspaceAttr) {
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
+ } else if (attr->name() == hspaceAttr) {
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
+ } else if (attr->name() == alignAttr) {
+ if (m_inputType->shouldRespectAlignAttribute())
+ addHTMLAlignment(attr);
+ } else if (attr->name() == widthAttr) {
+ if (m_inputType->shouldRespectHeightAndWidthAttributes())
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
+ } else if (attr->name() == heightAttr) {
+ if (m_inputType->shouldRespectHeightAndWidthAttributes())
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
+ } else if (attr->name() == onsearchAttr) {
+ // Search field and slider attributes all just cause updateFromElement to be called through style recalcing.
+ setAttributeEventListener(eventNames().searchEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == resultsAttr) {
+ int oldResults = m_maxResults;
+ m_maxResults = !attr->isNull() ? std::min(attr->value().toInt(), maxSavedResults) : -1;
+ // FIXME: Detaching just for maxResults change is not ideal. We should figure out the right
+ // time to relayout for this change.
+ if (m_maxResults != oldResults && (m_maxResults <= 0 || oldResults <= 0) && attached()) {
+ detach();
+ attach();
+ }
+ setNeedsStyleRecalc();
+ } else if (attr->name() == autosaveAttr || attr->name() == incrementalAttr)
+ setNeedsStyleRecalc();
+ else if (attr->name() == minAttr || attr->name() == maxAttr) {
+ m_inputType->minOrMaxAttributeChanged();
+ setNeedsValidityCheck();
+ } else if (attr->name() == multipleAttr || attr->name() == patternAttr || attr->name() == precisionAttr || attr->name() == stepAttr)
+ setNeedsValidityCheck();
+#if ENABLE(DATALIST)
+ else if (attr->name() == listAttr)
+ m_hasNonEmptyList = !attr->isEmpty();
+ // FIXME: we need to tell this change to a renderer if the attribute affects the appearance.
+#endif
+#if ENABLE(INPUT_SPEECH)
+ else if (attr->name() == webkitspeechAttr) {
+ if (renderer())
+ toRenderTextControlSingleLine(renderer())->speechAttributeChanged();
+ setNeedsStyleRecalc();
+ } else if (attr->name() == onwebkitspeechchangeAttr)
+ setAttributeEventListener(eventNames().webkitspeechchangeEvent, createAttributeEventListener(this, attr));
+#endif
+ else
+ HTMLTextFormControlElement::parseMappedAttribute(attr);
+}
+
+bool HTMLInputElement::rendererIsNeeded(RenderStyle* style)
+{
+ return m_inputType->rendererIsNeeded() && HTMLFormControlElementWithState::rendererIsNeeded(style);
+}
+
+RenderObject* HTMLInputElement::createRenderer(RenderArena* arena, RenderStyle* style)
+{
+ return m_inputType->createRenderer(arena, style);
+}
+
+void HTMLInputElement::attach()
+{
+ if (!m_hasType)
+ updateType();
+
+ HTMLFormControlElementWithState::attach();
+
+ m_inputType->attach();
+
+ if (document()->focusedNode() == this)
+ document()->updateFocusAppearanceSoon(true /* restore selection */);
+}
+
+void HTMLInputElement::detach()
+{
+ HTMLFormControlElementWithState::detach();
+ setFormControlValueMatchesRenderer(false);
+}
+
+String HTMLInputElement::altText() const
+{
+ // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
+ // also heavily discussed by Hixie on bugzilla
+ // note this is intentionally different to HTMLImageElement::altText()
+ String alt = fastGetAttribute(altAttr);
+ // fall back to title attribute
+ if (alt.isNull())
+ alt = getAttribute(titleAttr);
+ if (alt.isNull())
+ alt = getAttribute(valueAttr);
+ if (alt.isEmpty())
+ alt = inputElementAltText();
+ return alt;
+}
+
+bool HTMLInputElement::isSuccessfulSubmitButton() const
+{
+ // HTML spec says that buttons must have names to be considered successful.
+ // However, other browsers do not impose this constraint. So we do not.
+ return !disabled() && m_inputType->canBeSuccessfulSubmitButton();
+}
+
+bool HTMLInputElement::isActivatedSubmit() const
+{
+ return m_isActivatedSubmit;
+}
+
+void HTMLInputElement::setActivatedSubmit(bool flag)
+{
+ m_isActivatedSubmit = flag;
+}
+
+bool HTMLInputElement::appendFormData(FormDataList& encoding, bool multipart)
+{
+ return m_inputType->isFormDataAppendable() && m_inputType->appendFormData(encoding, multipart);
+}
+
+void HTMLInputElement::reset()
+{
+ if (m_inputType->storesValueSeparateFromAttribute())
+ setValue(String());
+
+ setChecked(hasAttribute(checkedAttr));
+ m_reflectsCheckedAttribute = true;
+}
+
+bool HTMLInputElement::isTextField() const
+{
+ return m_inputType->isTextField();
+}
+
+bool HTMLInputElement::isTextType() const
+{
+ return m_inputType->isTextType();
+}
+
+void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent)
+{
+ if (checked() == nowChecked)
+ return;
+
+ checkedRadioButtons().removeButton(this);
+
+ m_reflectsCheckedAttribute = false;
+ m_isChecked = nowChecked;
+ setNeedsStyleRecalc();
+
+ updateCheckedRadioButtons();
+
+ // Ideally we'd do this from the render tree (matching
+ // RenderTextView), but it's not possible to do it at the moment
+ // because of the way the code is structured.
+ if (renderer() && AXObjectCache::accessibilityEnabled())
+ renderer()->document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXCheckedStateChanged, true);
+
+ // Only send a change event for items in the document (avoid firing during
+ // parsing) and don't send a change event for a radio button that's getting
+ // unchecked to match other browsers. DOM is not a useful standard for this
+ // because it says only to fire change events at "lose focus" time, which is
+ // definitely wrong in practice for these types of elements.
+ if (sendChangeEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged())
+ dispatchFormControlChangeEvent();
+}
+
+void HTMLInputElement::setIndeterminate(bool newValue)
+{
+ if (!m_inputType->isCheckable() || indeterminate() == newValue)
+ return;
+
+ m_isIndeterminate = newValue;
+
+ setNeedsStyleRecalc();
+
+ if (renderer() && renderer()->style()->hasAppearance())
+ renderer()->theme()->stateChanged(renderer(), CheckedState);
+}
+
+int HTMLInputElement::size() const
+{
+ return m_data.size();
+}
+
+void HTMLInputElement::copyNonAttributeProperties(const Element* source)
+{
+ const HTMLInputElement* sourceElement = static_cast<const HTMLInputElement*>(source);
+
+ m_data.setValue(sourceElement->m_data.value());
+ setChecked(sourceElement->m_isChecked);
+ m_reflectsCheckedAttribute = sourceElement->m_reflectsCheckedAttribute;
+ m_isIndeterminate = sourceElement->m_isIndeterminate;
+
+ HTMLFormControlElementWithState::copyNonAttributeProperties(source);
+}
+
+String HTMLInputElement::value() const
+{
+ String value;
+ if (m_inputType->getTypeSpecificValue(value))
+ return value;
+
+ value = m_data.value();
+ if (!value.isNull())
+ return value;
+
+ value = sanitizeValue(fastGetAttribute(valueAttr));
+ if (!value.isNull())
+ return value;
+
+ return m_inputType->fallbackValue();
+}
+
+String HTMLInputElement::valueWithDefault() const
+{
+ String value = this->value();
+ if (!value.isNull())
+ return value;
+
+ return m_inputType->defaultValue();
+}
+
+void HTMLInputElement::setValueForUser(const String& value)
+{
+ // Call setValue and make it send a change event.
+ setValue(value, true);
+}
+
+const String& HTMLInputElement::suggestedValue() const
+{
+ return m_data.suggestedValue();
+}
+
+void HTMLInputElement::setSuggestedValue(const String& value)
+{
+ if (!m_inputType->canSetSuggestedValue())
+ return;
+ setFormControlValueMatchesRenderer(false);
+ m_data.setSuggestedValue(sanitizeValue(value));
+ updatePlaceholderVisibility(false);
+ if (renderer())
+ renderer()->updateFromElement();
+ setNeedsStyleRecalc();
+}
+
+void HTMLInputElement::setValue(const String& value, bool sendChangeEvent)
+{
+ if (!m_inputType->canSetValue(value))
+ return;
+
+ setFormControlValueMatchesRenderer(false);
+ if (m_inputType->storesValueSeparateFromAttribute()) {
+ if (files())
+ files()->clear();
+ else {
+ m_data.setValue(sanitizeValue(value));
+ if (isTextField())
+ updatePlaceholderVisibility(false);
+ }
+ setNeedsStyleRecalc();
+ } else
+ setAttribute(valueAttr, sanitizeValue(value));
+
+ setNeedsValidityCheck();
+
+ if (isTextField()) {
+ unsigned max = m_data.value().length();
+#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
+ // Make sure our UI side textfield changes to match the RenderTextControl
+ PlatformBridge::updateTextfield(document()->view(), this, false, value);
+#endif
+ if (document()->focusedNode() == this)
+ InputElement::updateSelectionRange(this, this, max, max);
+ else
+ cacheSelection(max, max);
+ m_data.setSuggestedValue(String());
+ }
+
+ // Don't dispatch the change event when focused, it will be dispatched
+ // when the control loses focus.
+ if (sendChangeEvent && document()->focusedNode() != this)
+ dispatchFormControlChangeEvent();
+
+ InputElement::notifyFormStateChanged(this);
+}
+
+double HTMLInputElement::valueAsDate() const
+{
+ return m_inputType->valueAsDate();
+}
+
+void HTMLInputElement::setValueAsDate(double value, ExceptionCode& ec)
+{
+ m_inputType->setValueAsDate(value, ec);
+}
+
+double HTMLInputElement::valueAsNumber() const
+{
+ return m_inputType->valueAsNumber();
+}
+
+void HTMLInputElement::setValueAsNumber(double newValue, ExceptionCode& ec)
+{
+ if (!isfinite(newValue)) {
+ ec = NOT_SUPPORTED_ERR;
+ return;
+ }
+ m_inputType->setValueAsNumber(newValue, ec);
+}
+
+String HTMLInputElement::placeholder() const
+{
+ return fastGetAttribute(placeholderAttr).string();
+}
+
+void HTMLInputElement::setPlaceholder(const String& value)
+{
+ setAttribute(placeholderAttr, value);
+}
+
+bool HTMLInputElement::searchEventsShouldBeDispatched() const
+{
+ return hasAttribute(incrementalAttr);
+}
+
+void HTMLInputElement::setValueFromRenderer(const String& value)
+{
+ // File upload controls will always use setFileListFromRenderer.
+ ASSERT(!isFileUpload());
+
+ m_data.setSuggestedValue(String());
+ InputElement::setValueFromRenderer(m_data, this, this, value);
+ updatePlaceholderVisibility(false);
+ setNeedsValidityCheck();
+
+ // Clear autofill flag (and yellow background) on user edit.
+ setAutofilled(false);
+}
+
+void HTMLInputElement::setFileListFromRenderer(const Vector<String>& paths)
+{
+ m_inputType->setFileList(paths);
+
+ setFormControlValueMatchesRenderer(true);
+ InputElement::notifyFormStateChanged(this);
+ setNeedsValidityCheck();
+}
+
+void* HTMLInputElement::preDispatchEventHandler(Event* event)
+{
+ if (event->type() != eventNames().clickEvent)
+ return 0;
+ // FIXME: Check whether there are any cases where this actually ends up leaking.
+ return m_inputType->willDispatchClick().leakPtr();
+}
+
+void HTMLInputElement::postDispatchEventHandler(Event* event, void* dataFromPreDispatch)
+{
+ OwnPtr<ClickHandlingState> state = adoptPtr(static_cast<ClickHandlingState*>(dataFromPreDispatch));
+ if (event->type() != eventNames().clickEvent)
+ return;
+ if (!state)
+ return;
+ m_inputType->didDispatchClick(event, *state);
+}
+
+void HTMLInputElement::defaultEventHandler(Event* evt)
+{
+ if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent) {
+ m_inputType->handleClickEvent(static_cast<MouseEvent*>(evt));
+ if (evt->defaultHandled())
+ return;
+ }
+
+ if (evt->isKeyboardEvent() && evt->type() == eventNames().keydownEvent) {
+ m_inputType->handleKeydownEvent(static_cast<KeyboardEvent*>(evt));
+ if (evt->defaultHandled())
+ return;
+ }
+
+ // Call the base event handler before any of our own event handling for almost all events in text fields.
+ // Makes editing keyboard handling take precedence over the keydown and keypress handling in this function.
+ bool callBaseClassEarly = isTextField() && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
+ if (callBaseClassEarly) {
+ HTMLFormControlElementWithState::defaultEventHandler(evt);
+ if (evt->defaultHandled())
+ return;
+ }
+
+ // DOMActivate events cause the input to be "activated" - in the case of image and submit inputs, this means
+ // actually submitting the form. For reset inputs, the form is reset. These events are sent when the user clicks
+ // on the element, or presses enter while it is the active element. JavaScript code wishing to activate the element
+ // must dispatch a DOMActivate event - a click event will not do the job.
+ if (evt->type() == eventNames().DOMActivateEvent) {
+ m_inputType->handleDOMActivateEvent(evt);
+ if (evt->defaultHandled())
+ return;
+ }
+
+ // Use key press event here since sending simulated mouse events
+ // on key down blocks the proper sending of the key press event.
+ 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)) {
+ if (isSearchField()) {
+ addSearchResult();
+ onSearch();
+ }
+ // Fire onChange for text fields.
+ RenderObject* r = renderer();
+ if (r && r->isTextField() && toRenderTextControl(r)->wasChangedSinceLastChangeEvent()) {
+ dispatchFormControlChangeEvent();
+ // Refetch the renderer since arbitrary JS code run during onchange can do anything, including destroying it.
+ r = renderer();
+ if (r && r->isTextField())
+ toRenderTextControl(r)->setChangedSinceLastChangeEvent(false);
+ }
+
+ RefPtr<HTMLFormElement> formForSubmission = m_inputType->formForSubmission();
+ // Form may never have been present, or may have been destroyed by code responding to the change event.
+ if (formForSubmission)
+ formForSubmission->submitImplicitly(evt, canTriggerImplicitSubmission());
+
+ evt->setDefaultHandled();
+ return;
+ }
+
+ if (evt->isBeforeTextInsertedEvent())
+ m_inputType->handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(evt));
+
+ if (evt->isWheelEvent()) {
+ m_inputType->handleWheelEvent(static_cast<WheelEvent*>(evt));
+ if (evt->defaultHandled())
+ return;
+ }
+
+<<<<<<< HEAD:WebCore/html/HTMLInputElement.cpp
+ if (deprecatedInputType() == RANGE
+ && renderer()
+ && (evt->isMouseEvent()
+#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
+ || evt->isTouchEvent()
+#endif
+ || evt->isDragEvent()
+ || evt->isWheelEvent()))
+ toRenderSlider(renderer())->forwardEvent(evt);
+=======
+ m_inputType->forwardEvent(evt);
+>>>>>>> webkit.org at r75315:Source/WebCore/html/HTMLInputElement.cpp
+
+ if (!callBaseClassEarly && !evt->defaultHandled())
+ HTMLFormControlElementWithState::defaultEventHandler(evt);
+}
+
+bool HTMLInputElement::isURLAttribute(Attribute *attr) const
+{
+ return (attr->name() == srcAttr || attr->name() == formactionAttr);
+}
+
+String HTMLInputElement::defaultValue() const
+{
+ return fastGetAttribute(valueAttr);
+}
+
+void HTMLInputElement::setDefaultValue(const String &value)
+{
+ setAttribute(valueAttr, value);
+}
+
+void HTMLInputElement::setDefaultName(const AtomicString& name)
+{
+ m_data.setName(name);
+}
+
+String HTMLInputElement::accept() const
+{
+ return fastGetAttribute(acceptAttr);
+}
+
+String HTMLInputElement::alt() const
+{
+ return fastGetAttribute(altAttr);
+}
+
+int HTMLInputElement::maxLength() const
+{
+ return m_data.maxLength();
+}
+
+void HTMLInputElement::setMaxLength(int maxLength, ExceptionCode& ec)
+{
+ if (maxLength < 0)
+ ec = INDEX_SIZE_ERR;
+ else
+ setAttribute(maxlengthAttr, String::number(maxLength));
+}
+
+bool HTMLInputElement::multiple() const
+{
+ return fastHasAttribute(multipleAttr);
+}
+
+void HTMLInputElement::setSize(unsigned size)
+{
+ setAttribute(sizeAttr, String::number(size));
+}
+
+KURL HTMLInputElement::src() const
+{
+ return document()->completeURL(fastGetAttribute(srcAttr));
+}
+
+void HTMLInputElement::setAutofilled(bool autofilled)
+{
+ if (autofilled == m_isAutofilled)
+ return;
+
+ m_isAutofilled = autofilled;
+ setNeedsStyleRecalc();
+}
+
+FileList* HTMLInputElement::files()
+{
+ return m_inputType->files();
+}
+
+bool HTMLInputElement::isAcceptableValue(const String& proposedValue) const
+{
+ return m_inputType->isAcceptableValue(proposedValue);
+}
+
+String HTMLInputElement::sanitizeValue(const String& proposedValue) const
+{
+ return m_inputType->sanitizeValue(proposedValue);
+}
+
+bool HTMLInputElement::hasUnacceptableValue() const
+{
+ return m_inputType->hasUnacceptableValue();
+}
+
+bool HTMLInputElement::isInRange() const
+{
+ return m_inputType->supportsRangeLimitation() && !rangeUnderflow(value()) && !rangeOverflow(value());
+}
+
+bool HTMLInputElement::isOutOfRange() const
+{
+ return m_inputType->supportsRangeLimitation() && (rangeUnderflow(value()) || rangeOverflow(value()));
+}
+
+bool HTMLInputElement::needsActivationCallback()
+{
+ return m_autocomplete == Off || m_inputType->shouldResetOnDocumentActivation();
+}
+
+void HTMLInputElement::registerForActivationCallbackIfNeeded()
+{
+ if (needsActivationCallback())
+ document()->registerForDocumentActivationCallbacks(this);
+}
+
+void HTMLInputElement::unregisterForActivationCallbackIfNeeded()
+{
+ if (!needsActivationCallback())
+ document()->unregisterForDocumentActivationCallbacks(this);
+}
+
+bool HTMLInputElement::isRequiredFormControl() const
+{
+ return m_inputType->supportsRequired() && required();
+}
+
+void HTMLInputElement::cacheSelection(int start, int end)
+{
+ m_data.setCachedSelectionStart(start);
+ m_data.setCachedSelectionEnd(end);
+}
+
+void HTMLInputElement::addSearchResult()
+{
+ ASSERT(isSearchField());
+ if (renderer())
+ toRenderTextControlSingleLine(renderer())->addSearchResult();
+}
+
+void HTMLInputElement::onSearch()
+{
+ ASSERT(isSearchField());
+ if (renderer())
+ toRenderTextControlSingleLine(renderer())->stopSearchEventTimer();
+ dispatchEvent(Event::create(eventNames().searchEvent, true, false));
+}
+
+void HTMLInputElement::documentDidBecomeActive()
+{
+ ASSERT(needsActivationCallback());
+ reset();
+}
+
+void HTMLInputElement::willMoveToNewOwnerDocument()
+{
+ m_inputType->willMoveToNewOwnerDocument();
+
+ // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered
+ if (needsActivationCallback())
+ document()->unregisterForDocumentActivationCallbacks(this);
+
+ document()->checkedRadioButtons().removeButton(this);
+
+ HTMLFormControlElementWithState::willMoveToNewOwnerDocument();
+}
+
+void HTMLInputElement::didMoveToNewOwnerDocument()
+{
+ registerForActivationCallbackIfNeeded();
+
+ HTMLFormControlElementWithState::didMoveToNewOwnerDocument();
+}
+
+void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+{
+ HTMLFormControlElementWithState::addSubresourceAttributeURLs(urls);
+
+ addSubresourceURL(urls, src());
+}
+
+bool HTMLInputElement::recalcWillValidate() const
+{
+ return m_inputType->supportsValidation() && HTMLFormControlElementWithState::recalcWillValidate();
+}
+
+#if ENABLE(DATALIST)
+
+HTMLElement* HTMLInputElement::list() const
+{
+ return dataList();
+}
+
+HTMLDataListElement* HTMLInputElement::dataList() const
+{
+ if (!m_hasNonEmptyList)
+ return 0;
+
+ if (!m_inputType->shouldRespectListAttribute())
+ return 0;
+
+ Element* element = document()->getElementById(fastGetAttribute(listAttr));
+ if (!element)
+ return 0;
+ if (!element->hasTagName(datalistTag))
+ return 0;
+
+ return static_cast<HTMLDataListElement*>(element);
+}
+
+HTMLOptionElement* HTMLInputElement::selectedOption() const
+{
+ String value = this->value();
+
+ // The empty string never matches to a datalist option because it
+ // doesn't represent a suggestion according to the standard.
+ if (value.isEmpty())
+ return 0;
+
+ HTMLDataListElement* sourceElement = dataList();
+ if (!sourceElement)
+ return 0;
+ RefPtr<HTMLCollection> options = sourceElement->options();
+ if (!options)
+ return 0;
+ unsigned length = options->length();
+ for (unsigned i = 0; i < length; ++i) {
+ HTMLOptionElement* option = static_cast<HTMLOptionElement*>(options->item(i));
+ if (!option->disabled() && value == option->value())
+ return option;
+ }
+ return 0;
+}
+
+#endif // ENABLE(DATALIST)
+
+void HTMLInputElement::stepUpFromRenderer(int n)
+{
+ // The differences from stepUp()/stepDown():
+ //
+ // Difference 1: the current value
+ // If the current value is not a number, including empty, the current value is assumed as 0.
+ // * If 0 is in-range, and matches to step value
+ // - The value should be the +step if n > 0
+ // - The value should be the -step if n < 0
+ // If -step or +step is out of range, new value should be 0.
+ // * If 0 is smaller than the minimum value
+ // - The value should be the minimum value for any n
+ // * If 0 is larger than the maximum value
+ // - The value should be the maximum value for any n
+ // * If 0 is in-range, but not matched to step value
+ // - The value should be the larger matched value nearest to 0 if n > 0
+ // e.g. <input type=number min=-100 step=3> -> 2
+ // - The value should be the smaler matched value nearest to 0 if n < 0
+ // e.g. <input type=number min=-100 step=3> -> -1
+ // As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
+ // As for datetime type, the current value is assumed as "the current date/time in UTC".
+ // If the current value is smaller than the minimum value:
+ // - The value should be the minimum value if n > 0
+ // - Nothing should happen if n < 0
+ // If the current value is larger than the maximum value:
+ // - The value should be the maximum value if n < 0
+ // - Nothing should happen if n > 0
+ //
+ // Difference 2: clamping steps
+ // If the current value is not matched to step value:
+ // - The value should be the larger matched value nearest to 0 if n > 0
+ // e.g. <input type=number value=3 min=-100 step=3> -> 5
+ // - The value should be the smaler matched value nearest to 0 if n < 0
+ // e.g. <input type=number value=3 min=-100 step=3> -> 2
+ //
+ // n is assumed as -n if step < 0.
+
+ ASSERT(hasSpinButton() || m_inputType->isRangeControl());
+ if (!hasSpinButton() && !m_inputType->isRangeControl())
+ return;
+ ASSERT(n);
+ if (!n)
+ return;
+
+ unsigned stepDecimalPlaces, baseDecimalPlaces;
+ double step, base;
+ // The value will be the default value after stepping for <input value=(empty/invalid) step="any" />
+ // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
+ // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
+ if (equalIgnoringCase(fastGetAttribute(stepAttr), "any"))
+ step = 0;
+ else if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces))
+ return;
+ base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
+ baseDecimalPlaces = min(baseDecimalPlaces, 16u);
+
+ int sign;
+ if (step > 0)
+ sign = n;
+ else if (step < 0)
+ sign = -n;
+ else
+ sign = 0;
+
+ const double nan = numeric_limits<double>::quiet_NaN();
+ String currentStringValue = value();
+ double current = m_inputType->parseToDouble(currentStringValue, nan);
+ if (!isfinite(current)) {
+ ExceptionCode ec;
+ current = m_inputType->defaultValueForStepUp();
+ setValueAsNumber(current, ec);
+ }
+ if ((sign > 0 && current < m_inputType->minimum()) || (sign < 0 && current > m_inputType->maximum()))
+ setValue(m_inputType->serialize(sign > 0 ? m_inputType->minimum() : m_inputType->maximum()));
+ else {
+ ExceptionCode ec;
+ if (stepMismatch(currentStringValue)) {
+ ASSERT(step);
+ double newValue;
+ double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
+
+ if (sign < 0)
+ newValue = round((base + floor((current - base) / step) * step) * scale) / scale;
+ else if (sign > 0)
+ newValue = round((base + ceil((current - base) / step) * step) * scale) / scale;
+ else
+ newValue = current;
+
+ if (newValue < m_inputType->minimum())
+ newValue = m_inputType->minimum();
+ if (newValue > m_inputType->maximum())
+ newValue = m_inputType->maximum();
+
+ setValueAsNumber(newValue, ec);
+ current = newValue;
+ if (n > 1)
+ applyStep(n - 1, ec);
+ else if (n < -1)
+ applyStep(n + 1, ec);
+ } else
+ applyStep(n, ec);
+ }
+
+ if (currentStringValue != value()) {
+ if (renderer() && renderer()->isTextField())
+ toRenderTextControl(renderer())->setChangedSinceLastChangeEvent(true);
+ if (m_inputType->isRangeControl())
+ dispatchFormControlChangeEvent();
+ else
+ dispatchEvent(Event::create(eventNames().inputEvent, true, false));
+ }
+}
+
+#if ENABLE(WCSS)
+
+void HTMLInputElement::setWapInputFormat(String& mask)
+{
+ String validateMask = validateInputMask(m_data, mask);
+ if (!validateMask.isEmpty())
+ m_data.setInputFormatMask(validateMask);
+}
+
+#endif
+
+#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::speechInputEnabled() && hasAttribute(webkitspeechAttr);
+}
+
+#endif
+
+bool HTMLInputElement::isTextButton() const
+{
+ return m_inputType->isTextButton();
+}
+
+bool HTMLInputElement::isRadioButton() const
+{
+ return m_inputType->isRadioButton();
+}
+
+bool HTMLInputElement::isSearchField() const
+{
+ return m_inputType->isSearchField();
+}
+
+bool HTMLInputElement::isInputTypeHidden() const
+{
+ return m_inputType->isHiddenType();
+}
+
+bool HTMLInputElement::isPasswordField() const
+{
+ return m_inputType->isPasswordField();
+}
+
+bool HTMLInputElement::isCheckbox() const
+{
+ return m_inputType->isCheckbox();
+}
+
+bool HTMLInputElement::isText() const
+{
+ return m_inputType->isTextType();
+}
+
+bool HTMLInputElement::isEmailField() const
+{
+ return m_inputType->isEmailField();
+}
+
+bool HTMLInputElement::isFileUpload() const
+{
+ return m_inputType->isFileUpload();
+}
+
+bool HTMLInputElement::isImageButton() const
+{
+ return m_inputType->isImageButton();
+}
+
+bool HTMLInputElement::isNumberField() const
+{
+ return m_inputType->isNumberField();
+}
+
+bool HTMLInputElement::isSubmitButton() const
+{
+ return m_inputType->isSubmitButton();
+}
+
+bool HTMLInputElement::isTelephoneField() const
+{
+ return m_inputType->isTelephoneField();
+}
+
+bool HTMLInputElement::isURLField() const
+{
+ return m_inputType->isURLField();
+}
+
+bool HTMLInputElement::isEnumeratable() const
+{
+ return m_inputType->isEnumeratable();
+}
+
+bool HTMLInputElement::isChecked() const
+{
+ return checked() && m_inputType->isCheckable();
+}
+
+bool HTMLInputElement::hasSpinButton() const
+{
+ return m_inputType->hasSpinButton();
+}
+
+bool HTMLInputElement::supportsPlaceholder() const
+{
+ return isTextType();
+}
+
+CheckedRadioButtons& HTMLInputElement::checkedRadioButtons() const
+{
+ if (HTMLFormElement* formElement = form())
+ return formElement->checkedRadioButtons();
+ return document()->checkedRadioButtons();
+}
+
+void HTMLInputElement::handleBeforeTextInsertedEvent(Event* event)
+{
+ InputElement::handleBeforeTextInsertedEvent(m_data, this, this, event);
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h
new file mode 100644
index 0000000..eb30de0
--- /dev/null
+++ b/Source/WebCore/html/HTMLInputElement.h
@@ -0,0 +1,319 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLInputElement_h
+#define HTMLInputElement_h
+
+#include "HTMLFormControlElement.h"
+#include "InputElement.h"
+
+namespace WebCore {
+
+class FileList;
+class HTMLDataListElement;
+class HTMLOptionElement;
+class InputType;
+class KURL;
+
+class HTMLInputElement : public HTMLTextFormControlElement, public InputElement {
+public:
+ static PassRefPtr<HTMLInputElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+ virtual ~HTMLInputElement();
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitspeechchange);
+
+ bool autoComplete() const;
+
+ // For ValidityState
+ bool typeMismatch() const;
+ // valueMissing() ignores the specified string value for CHECKBOX and RADIO.
+ bool valueMissing(const String&) const;
+ bool patternMismatch(const String&) const;
+ bool tooLong(const String&, NeedsToCheckDirtyFlag) const;
+ bool rangeUnderflow(const String&) const;
+ bool rangeOverflow(const String&) const;
+ // Returns the minimum value for type=date, number, or range. Don't call this for other types.
+ double minimum() const;
+ // Returns the maximum value for type=date, number, or range. Don't call this for other types.
+ // This always returns a value which is >= minimum().
+ double maximum() const;
+ // Sets the "allowed value step" defined in the HTML spec to the specified double pointer.
+ // Returns false if there is no "allowed value step."
+ bool getAllowedValueStep(double*) const;
+ bool getAllowedValueStepWithDecimalPlaces(double*, unsigned*) const;
+ // For ValidityState.
+ bool stepMismatch(const String&) const;
+ String minimumString() const;
+ String maximumString() const;
+ String stepBaseString() const;
+ String stepString() const;
+ String typeMismatchText() const;
+ String valueMissingText() const;
+
+ // Implementations of HTMLInputElement::stepUp() and stepDown().
+ void stepUp(int, ExceptionCode&);
+ void stepDown(int, ExceptionCode&);
+ void stepUp(ExceptionCode& ec) { stepUp(1, ec); }
+ void stepDown(ExceptionCode& ec) { stepDown(1, ec); }
+ // stepUp()/stepDown() for user-interaction.
+ void stepUpFromRenderer(int);
+
+ bool isTextButton() const;
+
+ virtual bool isRadioButton() const;
+ virtual bool isTextField() const;
+ virtual bool isSearchField() const;
+ virtual bool isInputTypeHidden() const;
+ virtual bool isPasswordField() const;
+ virtual bool isCheckbox() const;
+
+ // FIXME: It's highly likely that any call site calling this function should instead
+ // 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.
+ bool isText() const;
+
+ bool isEmailField() const;
+ bool isFileUpload() const;
+ bool isImageButton() const;
+ bool isNumberField() const;
+ bool isSubmitButton() const;
+ bool isTelephoneField() const;
+ bool isURLField() const;
+
+#if ENABLE(INPUT_SPEECH)
+ virtual bool isSpeechEnabled() const;
+#endif
+
+ bool checked() const { return m_isChecked; }
+ void setChecked(bool, bool sendChangeEvent = false);
+
+ // 'indeterminate' is a state independent of the checked state that causes the control to draw in a way that hides the actual state.
+ bool indeterminate() const { return m_isIndeterminate; }
+ void setIndeterminate(bool);
+
+ virtual int size() const;
+
+ void setType(const String&);
+
+ virtual String value() const;
+ virtual void setValue(const String&, bool sendChangeEvent = false);
+ virtual 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;
+
+ virtual const String& suggestedValue() const;
+ void setSuggestedValue(const String&);
+
+ double valueAsDate() const;
+ void setValueAsDate(double, ExceptionCode&);
+
+ double valueAsNumber() const;
+ void setValueAsNumber(double, ExceptionCode&);
+
+ virtual String placeholder() const;
+ virtual void setPlaceholder(const String&);
+
+ String valueWithDefault() const;
+
+ virtual void setValueFromRenderer(const String&);
+ void setFileListFromRenderer(const Vector<String>&);
+
+ bool canHaveSelection() const;
+ virtual void select() { HTMLTextFormControlElement::select(); }
+
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+ virtual void detach();
+
+ // 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;
+ virtual void setActivatedSubmit(bool flag);
+
+ String altText() const;
+
+ int maxResults() const { return m_maxResults; }
+
+ String defaultValue() const;
+ void setDefaultValue(const String&);
+
+ void setDefaultName(const AtomicString&);
+
+ String accept() const;
+ String alt() const;
+
+ void setSize(unsigned);
+
+ KURL src() const;
+
+ virtual int maxLength() const;
+ void setMaxLength(int, ExceptionCode&);
+
+ bool multiple() const;
+
+ virtual bool isAutofilled() const { return m_isAutofilled; }
+ void setAutofilled(bool = true);
+
+ FileList* files();
+
+ void addSearchResult();
+ void onSearch();
+
+#if ENABLE(DATALIST)
+ HTMLElement* list() const;
+ HTMLOptionElement* selectedOption() const;
+#endif
+
+#if ENABLE(WCSS)
+ void setWapInputFormat(String& mask);
+#endif
+
+ // These functions are public so they can be used in InputType classes.
+ // Otherwise, they would be private.
+ CheckedRadioButtons& checkedRadioButtons() const;
+ void handleBeforeTextInsertedEvent(Event*);
+ void updateCheckedRadioButtons();
+
+protected:
+ HTMLInputElement(const QualifiedName&, Document*, HTMLFormElement* = 0);
+
+ virtual void defaultEventHandler(Event*);
+
+private:
+ enum AutoCompleteSetting { Uninitialized, On, Off };
+
+ virtual void willMoveToNewOwnerDocument();
+ virtual void didMoveToNewOwnerDocument();
+
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const;
+ virtual bool isMouseFocusable() const;
+ virtual bool isEnumeratable() const;
+ virtual void updateFocusAppearance(bool restorePreviousSelection);
+ virtual void aboutToUnload();
+ virtual bool shouldUseInputMethod() const;
+
+ virtual const AtomicString& formControlName() const;
+
+ // isChecked is used by the rendering tree/CSS while checked() is used by JS to determine checked state
+ virtual bool isChecked() const;
+ virtual bool isIndeterminate() const { return indeterminate(); }
+
+ virtual bool isTextFormControl() const { return isTextField(); }
+
+ virtual bool hasSpinButton() const;
+ virtual bool canTriggerImplicitSubmission() const { return isTextField(); }
+
+ virtual const AtomicString& formControlType() const;
+
+ virtual bool searchEventsShouldBeDispatched() const;
+
+ virtual bool saveFormControlState(String& value) const;
+ virtual void restoreFormControlState(const String&);
+
+ virtual bool canStartSelection() const;
+
+ virtual void accessKeyAction(bool sendToAnyElement);
+
+ virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void copyNonAttributeProperties(const Element* source);
+
+ virtual void attach();
+
+ virtual bool appendFormData(FormDataList&, bool);
+
+ virtual bool isSuccessfulSubmitButton() const;
+
+ virtual void reset();
+
+ virtual void* preDispatchEventHandler(Event*);
+ virtual void postDispatchEventHandler(Event*, void* dataFromPreDispatch);
+
+ virtual bool isURLAttribute(Attribute*) const;
+
+ virtual void cacheSelection(int start, int end);
+
+ virtual bool isAcceptableValue(const String&) const;
+ virtual String sanitizeValue(const String&) const;
+ virtual bool hasUnacceptableValue() const;
+
+ virtual bool isInRange() const;
+ virtual bool isOutOfRange() const;
+
+ virtual void documentDidBecomeActive();
+
+ virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+
+ bool needsActivationCallback();
+ void registerForActivationCallbackIfNeeded();
+ void unregisterForActivationCallbackIfNeeded();
+
+ virtual bool supportsMaxLength() const { return isTextType(); }
+ bool isTextType() const;
+
+ virtual bool supportsPlaceholder() const;
+ virtual bool isEmptyValue() const { return value().isEmpty(); }
+ virtual void handleFocusEvent();
+ virtual void handleBlurEvent();
+ virtual int cachedSelectionStart() const { return m_data.cachedSelectionStart(); }
+ virtual int cachedSelectionEnd() const { return m_data.cachedSelectionEnd(); }
+
+ virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
+ virtual bool isRequiredFormControl() const;
+ virtual bool recalcWillValidate() const;
+
+ void updateType();
+
+ // Helper for stepUp()/stepDown(). Adds step value * count to the current value.
+ void applyStep(double count, ExceptionCode&);
+
+#if ENABLE(DATALIST)
+ HTMLDataListElement* dataList() const;
+#endif
+
+#if ENABLE(WCSS)
+ virtual InputElementData data() const { return m_data; }
+#endif
+
+ InputElementData m_data;
+ short m_maxResults;
+ bool m_isChecked : 1;
+ bool m_reflectsCheckedAttribute : 1;
+ bool m_isIndeterminate : 1;
+ bool m_hasType : 1;
+ bool m_isActivatedSubmit : 1;
+ unsigned m_autocomplete : 2; // AutoCompleteSetting
+ bool m_isAutofilled : 1;
+#if ENABLE(DATALIST)
+ bool m_hasNonEmptyList : 1;
+#endif
+ OwnPtr<InputType> m_inputType;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLInputElement.idl b/Source/WebCore/html/HTMLInputElement.idl
new file mode 100644
index 0000000..f346e10
--- /dev/null
+++ b/Source/WebCore/html/HTMLInputElement.idl
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLInputElement : HTMLElement {
+ attribute [ConvertNullToNullString] DOMString defaultValue;
+ attribute [Reflect=checked] boolean defaultChecked;
+ readonly attribute HTMLFormElement form;
+ attribute [Reflect, URL] DOMString formAction;
+ attribute [Reflect] DOMString formEnctype;
+ attribute [Reflect] DOMString formMethod;
+ attribute [Reflect] boolean formNoValidate;
+ attribute [Reflect] DOMString formTarget;
+ readonly attribute ValidityState validity;
+ attribute [Reflect] DOMString accept;
+ attribute [Reflect] DOMString accessKey;
+ attribute [Reflect] DOMString align;
+ attribute [Reflect] DOMString alt;
+ attribute boolean checked;
+ attribute [Reflect] boolean disabled;
+ attribute [Reflect] boolean autofocus;
+#if defined(ENABLE_DATALIST) && ENABLE_DATALIST
+ readonly attribute HTMLElement list;
+#endif
+ attribute [Reflect] DOMString max;
+ attribute long maxLength setter raises(DOMException);
+ attribute [Reflect] DOMString min;
+ attribute [Reflect] boolean multiple;
+#if defined(ENABLE_DIRECTORY_UPLOAD) && ENABLE_DIRECTORY_UPLOAD
+ attribute [Reflect] boolean webkitdirectory;
+#endif
+ attribute [Reflect] DOMString name;
+ attribute [Reflect] DOMString pattern;
+ attribute [Reflect] DOMString placeholder;
+ attribute [Reflect] boolean readOnly;
+ attribute [Reflect] boolean required;
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+ attribute [ConvertToString] DOMString size; // DOM level 2 changed this to a long, but our existing API is a string
+#else
+ // FIXME: The spec says this should be a long, not an unsigned long.
+ attribute unsigned long size; // Changed string -> long as part of DOM level 2
+#endif
+ attribute [Reflect, URL] DOMString src;
+ attribute [Reflect] DOMString step;
+ attribute [ConvertNullToNullString] DOMString type; // readonly dropped as part of DOM level 2
+ attribute [Reflect] DOMString useMap;
+ attribute [ConvertNullToNullString] DOMString value;
+#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
+ attribute Date valueAsDate setter raises(DOMException);
+#endif
+ attribute double valueAsNumber setter raises(DOMException);
+#if defined(ENABLE_DATALIST) && ENABLE_DATALIST
+ readonly attribute HTMLOptionElement selectedOption;
+#endif
+ attribute [Reflect] boolean incremental;
+
+ void stepUp(in [Optional] long n) raises(DOMException);
+ void stepDown(in [Optional] long n) raises(DOMException);
+
+ readonly attribute boolean willValidate;
+ readonly attribute DOMString validationMessage;
+ boolean checkValidity();
+ void setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error);
+ void select();
+ void click();
+
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
+ void setValueForUser(in [ConvertNullToNullString] DOMString value);
+#endif
+
+ // WinIE extension:
+ attribute boolean indeterminate;
+
+ attribute [Custom] long selectionStart;
+ attribute [Custom] long selectionEnd;
+ [Custom] void setSelectionRange(in long start, in long end);
+
+#if defined(LANGUAGE_OBJECTIVE_C)
+ // Objective-C extension:
+ readonly attribute DOMString altDisplayString;
+ readonly attribute URL absoluteImageURL;
+#endif
+
+ readonly attribute FileList files;
+ readonly attribute NodeList labels;
+
+#if defined(ENABLE_INPUT_SPEECH) && ENABLE_INPUT_SPEECH
+ attribute [Reflect, EnabledAtRuntime] boolean webkitSpeech;
+ attribute [Reflect, EnabledAtRuntime] boolean webkitGrammar;
+ attribute [DontEnum] EventListener onwebkitspeechchange;
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLIsIndexElement.cpp b/Source/WebCore/html/HTMLIsIndexElement.cpp
new file mode 100644
index 0000000..a23a353
--- /dev/null
+++ b/Source/WebCore/html/HTMLIsIndexElement.cpp
@@ -0,0 +1,64 @@
+/*
+ * 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, 2010 Apple Inc. All rights reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLIsIndexElement.h"
+
+#include "Attribute.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLIsIndexElement::HTMLIsIndexElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLInputElement(tagName, document, form)
+{
+ ASSERT(hasTagName(isindexTag));
+ setDefaultName(isindexTag.localName());
+}
+
+PassRefPtr<HTMLIsIndexElement> HTMLIsIndexElement::create(Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLIsIndexElement(isindexTag, document, form));
+}
+
+PassRefPtr<HTMLIsIndexElement> HTMLIsIndexElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLIsIndexElement(tagName, document, form));
+}
+
+void HTMLIsIndexElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == promptAttr)
+ setValue(attr->value());
+ else if (attr->name() == placeholderAttr)
+ updatePlaceholderVisibility(true);
+ else
+ // don't call HTMLInputElement::parseMappedAttribute here, as it would
+ // accept attributes this element does not support
+ HTMLFormControlElement::parseMappedAttribute(attr);
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLIsIndexElement.h b/Source/WebCore/html/HTMLIsIndexElement.h
new file mode 100644
index 0000000..857ef75
--- /dev/null
+++ b/Source/WebCore/html/HTMLIsIndexElement.h
@@ -0,0 +1,46 @@
+/*
+ * 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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLIsIndexElement_h
+#define HTMLIsIndexElement_h
+
+#include "HTMLInputElement.h"
+
+namespace WebCore {
+
+class HTMLIsIndexElement : public HTMLInputElement {
+public:
+ static PassRefPtr<HTMLIsIndexElement> create(Document*, HTMLFormElement*);
+ static PassRefPtr<HTMLIsIndexElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+
+private:
+ HTMLIsIndexElement(const QualifiedName&, Document*, HTMLFormElement*);
+
+ virtual bool canTriggerImplicitSubmission() const { return true; }
+
+ virtual void parseMappedAttribute(Attribute*);
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLIsIndexElement.idl b/Source/WebCore/html/HTMLIsIndexElement.idl
new file mode 100644
index 0000000..028a180
--- /dev/null
+++ b/Source/WebCore/html/HTMLIsIndexElement.idl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLIsIndexElement : HTMLInputElement {
+ readonly attribute HTMLFormElement form;
+ attribute [Reflect] DOMString prompt;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLKeygenElement.cpp b/Source/WebCore/html/HTMLKeygenElement.cpp
new file mode 100644
index 0000000..881a0a8
--- /dev/null
+++ b/Source/WebCore/html/HTMLKeygenElement.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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, 2010 Apple Inc. All rights reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLKeygenElement.h"
+
+#include "Attribute.h"
+#include "Document.h"
+#include "FormDataList.h"
+#include "HTMLNames.h"
+#include "HTMLOptionElement.h"
+#include "SSLKeyGenerator.h"
+#include "Text.h"
+#include <wtf/StdLibExtras.h>
+
+using namespace WebCore;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLKeygenElement::HTMLKeygenElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLSelectElement(tagName, document, form)
+{
+ ASSERT(hasTagName(keygenTag));
+
+ // FIXME: This markup should go in the shadow tree.
+ // Add one option element for each key size.
+ Vector<String> keys;
+ getSupportedKeySizes(keys);
+ for (size_t i = 0; i < keys.size(); ++i) {
+ RefPtr<HTMLOptionElement> option = HTMLOptionElement::create(document, this->form());
+ parserAddChild(option);
+ option->parserAddChild(Text::create(document, keys[i]));
+ }
+}
+
+PassRefPtr<HTMLKeygenElement> HTMLKeygenElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLKeygenElement(tagName, document, form));
+}
+
+const AtomicString& HTMLKeygenElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keygen, ("keygen"));
+ return keygen;
+}
+
+void HTMLKeygenElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == challengeAttr)
+ m_challenge = attr->value();
+ else if (attr->name() == keytypeAttr)
+ m_keyType = attr->value();
+ else {
+ // Skip HTMLSelectElement parsing.
+ HTMLFormControlElement::parseMappedAttribute(attr);
+ }
+}
+
+bool HTMLKeygenElement::appendFormData(FormDataList& encoded_values, bool)
+{
+ // Only RSA is supported at this time.
+ if (!m_keyType.isNull() && !equalIgnoringCase(m_keyType, "rsa"))
+ return false;
+ String value = signedPublicKeyAndChallengeString(selectedIndex(), m_challenge, document()->baseURL());
+ if (value.isNull())
+ return false;
+ encoded_values.appendData(name(), value.utf8());
+ return true;
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLKeygenElement.h b/Source/WebCore/html/HTMLKeygenElement.h
new file mode 100644
index 0000000..80f94b5
--- /dev/null
+++ b/Source/WebCore/html/HTMLKeygenElement.h
@@ -0,0 +1,51 @@
+/*
+ * 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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLKeygenElement_h
+#define HTMLKeygenElement_h
+
+#include "HTMLSelectElement.h"
+
+namespace WebCore {
+
+class HTMLKeygenElement : public HTMLSelectElement {
+public:
+ static PassRefPtr<HTMLKeygenElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+
+private:
+ HTMLKeygenElement(const QualifiedName&, Document*, HTMLFormElement*);
+
+ virtual const AtomicString& formControlType() const;
+ virtual void parseMappedAttribute(Attribute*);
+ virtual bool appendFormData(FormDataList&, bool);
+
+ virtual bool willValidate() const { return false; }
+ virtual bool isOptionalFormControl() const { return false; }
+
+ AtomicString m_challenge;
+ AtomicString m_keyType;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLLIElement.cpp b/Source/WebCore/html/HTMLLIElement.cpp
new file mode 100644
index 0000000..9abea9f
--- /dev/null
+++ b/Source/WebCore/html/HTMLLIElement.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLLIElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "HTMLNames.h"
+#include "RenderListItem.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLLIElement::HTMLLIElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , m_requestedValue(0)
+{
+ ASSERT(hasTagName(liTag));
+}
+
+PassRefPtr<HTMLLIElement> HTMLLIElement::create(Document* document)
+{
+ return adoptRef(new HTMLLIElement(liTag, document));
+}
+
+PassRefPtr<HTMLLIElement> HTMLLIElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLLIElement(tagName, document));
+}
+
+bool HTMLLIElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == typeAttr) {
+ result = eListItem; // Share with <ol> since all the values are the same
+ return false;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLLIElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == valueAttr) {
+ m_requestedValue = attr->value().toInt();
+ if (renderer() && renderer()->isListItem()) {
+ if (m_requestedValue > 0)
+ toRenderListItem(renderer())->setExplicitValue(m_requestedValue);
+ else
+ toRenderListItem(renderer())->clearExplicitValue();
+ }
+ } else if (attr->name() == typeAttr) {
+ if (attr->value() == "a")
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueLowerAlpha);
+ else if (attr->value() == "A")
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueUpperAlpha);
+ else if (attr->value() == "i")
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueLowerRoman);
+ else if (attr->value() == "I")
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueUpperRoman);
+ else if (attr->value() == "1")
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueDecimal);
+ else
+ addCSSProperty(attr, CSSPropertyListStyleType, attr->value());
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+void HTMLLIElement::attach()
+{
+ ASSERT(!attached());
+
+ HTMLElement::attach();
+
+ if (renderer() && renderer()->isListItem()) {
+ RenderListItem* render = toRenderListItem(renderer());
+
+ // Find the enclosing list node.
+ Node* listNode = 0;
+ Node* n = this;
+ while (!listNode && (n = n->parentNode())) {
+ if (n->hasTagName(ulTag) || n->hasTagName(olTag))
+ listNode = n;
+ }
+
+ // 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 (!listNode)
+ render->setNotInList(true);
+
+ if (m_requestedValue > 0)
+ render->setExplicitValue(m_requestedValue);
+ else
+ render->clearExplicitValue();
+ }
+}
+
+}
diff --git a/Source/WebCore/html/HTMLLIElement.h b/Source/WebCore/html/HTMLLIElement.h
new file mode 100644
index 0000000..ad12b67
--- /dev/null
+++ b/Source/WebCore/html/HTMLLIElement.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLLIElement_h
+#define HTMLLIElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLLIElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLLIElement> create(Document*);
+ static PassRefPtr<HTMLLIElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLLIElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void attach();
+
+ int m_requestedValue;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLLIElement.idl b/Source/WebCore/html/HTMLLIElement.idl
new file mode 100644
index 0000000..2dc541b
--- /dev/null
+++ b/Source/WebCore/html/HTMLLIElement.idl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLLIElement : HTMLElement {
+ attribute [Reflect] DOMString type;
+ attribute [Reflect] long value;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLLabelElement.cpp b/Source/WebCore/html/HTMLLabelElement.cpp
new file mode 100644
index 0000000..97a0c65
--- /dev/null
+++ b/Source/WebCore/html/HTMLLabelElement.cpp
@@ -0,0 +1,168 @@
+/*
+ * 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, 2010 Apple Inc. All rights reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLLabelElement.h"
+
+#include "Document.h"
+#include "Event.h"
+#include "EventNames.h"
+#include "HTMLFormControlElement.h"
+#include "HTMLFormElement.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static HTMLFormControlElement* nodeAsLabelableFormControl(Node* node)
+{
+ if (!node || !node->isElementNode() || !static_cast<Element*>(node)->isFormControlElement())
+ return 0;
+
+ HTMLFormControlElement* formControlElement = static_cast<HTMLFormControlElement*>(node);
+ if (!formControlElement->isLabelable())
+ return 0;
+
+ return formControlElement;
+}
+
+inline HTMLLabelElement::HTMLLabelElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(labelTag));
+}
+
+PassRefPtr<HTMLLabelElement> HTMLLabelElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLLabelElement(tagName, document));
+}
+
+bool HTMLLabelElement::isFocusable() const
+{
+ return false;
+}
+
+HTMLFormControlElement* HTMLLabelElement::control()
+{
+ 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
+ // the form element must be "labelable form-associated element".
+ Node* node = this;
+ while ((node = node->traverseNextNode(this))) {
+ if (HTMLFormControlElement* formControlElement = nodeAsLabelableFormControl(node))
+ return formControlElement;
+ }
+ return 0;
+ }
+
+ // Find the first element whose id is controlId. If it is found and it is a labelable form control,
+ // return it, otherwise return 0.
+ return nodeAsLabelableFormControl(document()->getElementById(controlId));
+}
+
+void HTMLLabelElement::setActive(bool down, bool pause)
+{
+ if (down == active())
+ return;
+
+ // Update our status first.
+ HTMLElement::setActive(down, pause);
+
+ // Also update our corresponding control.
+ if (HTMLElement* element = control())
+ element->setActive(down, pause);
+}
+
+void HTMLLabelElement::setHovered(bool over)
+{
+ if (over == hovered())
+ return;
+
+ // Update our status first.
+ HTMLElement::setHovered(over);
+
+ // Also update our corresponding control.
+ if (HTMLElement* element = control())
+ element->setHovered(over);
+}
+
+void HTMLLabelElement::defaultEventHandler(Event* evt)
+{
+ static bool processingClick = false;
+
+ if (evt->type() == eventNames().clickEvent && !processingClick) {
+ RefPtr<HTMLElement> element = control();
+
+ // If we can't find a control or if the control received the click
+ // event, then there's no need for us to do anything.
+ if (!element || (evt->target() && element->containsIncludingShadowDOM(evt->target()->toNode())))
+ return;
+
+ processingClick = true;
+
+ // Click the corresponding control.
+ element->dispatchSimulatedClick(evt);
+
+ // If the control can be focused via the mouse, then do that too.
+ if (element->isMouseFocusable())
+ element->focus();
+
+ processingClick = false;
+
+ evt->setDefaultHandled();
+ }
+
+ HTMLElement::defaultEventHandler(evt);
+}
+
+void HTMLLabelElement::focus(bool)
+{
+ // to match other browsers, always restore previous selection
+ if (HTMLElement* element = control())
+ element->focus();
+}
+
+void HTMLLabelElement::accessKeyAction(bool sendToAnyElement)
+{
+ if (HTMLElement* element = control())
+ element->accessKeyAction(sendToAnyElement);
+ else
+ HTMLElement::accessKeyAction(sendToAnyElement);
+}
+
+void HTMLLabelElement::parseMappedAttribute(Attribute* attribute)
+{
+ if (attribute->name() == forAttr) {
+ // htmlFor attribute change affects other nodes than this.
+ // Clear the caches to ensure that the labels caches are cleared.
+ if (document())
+ document()->notifyLocalNodeListsLabelChanged();
+ } else
+ HTMLElement::parseMappedAttribute(attribute);
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLLabelElement.h b/Source/WebCore/html/HTMLLabelElement.h
new file mode 100644
index 0000000..2b09e17
--- /dev/null
+++ b/Source/WebCore/html/HTMLLabelElement.h
@@ -0,0 +1,59 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLLabelElement_h
+#define HTMLLabelElement_h
+
+#include "HTMLElement.h"
+#include "HTMLFormControlElement.h"
+
+namespace WebCore {
+
+class HTMLLabelElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLLabelElement> create(const QualifiedName&, Document*);
+
+ HTMLFormControlElement* control();
+
+private:
+ HTMLLabelElement(const QualifiedName&, Document*);
+
+ virtual bool isFocusable() const;
+
+ virtual void accessKeyAction(bool sendToAnyElement);
+
+ // Overridden to update the hover/active state of the corresponding control.
+ virtual void setActive(bool = true, bool pause = false);
+ virtual void setHovered(bool = true);
+
+ // Overridden to either click() or focus() the corresponding control.
+ virtual void defaultEventHandler(Event*);
+
+ void focus(bool restorePreviousSelection = true);
+
+ virtual void parseMappedAttribute(Attribute*);
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLLabelElement.idl b/Source/WebCore/html/HTMLLabelElement.idl
new file mode 100644
index 0000000..c946bc4
--- /dev/null
+++ b/Source/WebCore/html/HTMLLabelElement.idl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLLabelElement : HTMLElement {
+ readonly attribute HTMLFormElement form;
+ attribute [Reflect] DOMString accessKey;
+ attribute [Reflect=for] DOMString htmlFor;
+ readonly attribute HTMLElement control;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLLegendElement.cpp b/Source/WebCore/html/HTMLLegendElement.cpp
new file mode 100644
index 0000000..f998118
--- /dev/null
+++ b/Source/WebCore/html/HTMLLegendElement.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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, 2010 Apple Inc. All rights reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLLegendElement.h"
+
+#include "HTMLNames.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLLegendElement::HTMLLegendElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLFormControlElement(tagName, document, form)
+{
+ ASSERT(hasTagName(legendTag));
+}
+
+PassRefPtr<HTMLLegendElement> HTMLLegendElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLLegendElement(tagName, document, form));
+}
+
+bool HTMLLegendElement::supportsFocus() const
+{
+ return HTMLElement::supportsFocus();
+}
+
+const AtomicString& HTMLLegendElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, legend, ("legend"));
+ return legend;
+}
+
+HTMLFormControlElement* HTMLLegendElement::associatedControl()
+{
+ // Check if there's a fieldset belonging to this legend.
+ ContainerNode* fieldset = parentNode();
+ while (fieldset && !fieldset->hasTagName(fieldsetTag))
+ fieldset = fieldset->parentNode();
+ if (!fieldset)
+ return 0;
+
+ // Find first form element inside the fieldset that is not a legend element.
+ // FIXME: Should we consider tabindex?
+ Node* node = fieldset;
+ while ((node = node->traverseNextNode(fieldset))) {
+ if (node->isElementNode()) {
+ Element* element = static_cast<Element*>(node);
+ if (!element->hasLocalName(legendTag) && element->isFormControlElement())
+ return static_cast<HTMLFormControlElement*>(element);
+ }
+ }
+
+ return 0;
+}
+
+void HTMLLegendElement::focus(bool)
+{
+ if (isFocusable())
+ Element::focus();
+
+ // To match other browsers' behavior, never restore previous selection.
+ if (HTMLFormControlElement* control = associatedControl())
+ control->focus(false);
+}
+
+void HTMLLegendElement::accessKeyAction(bool sendToAnyElement)
+{
+ if (HTMLFormControlElement* control = associatedControl())
+ control->accessKeyAction(sendToAnyElement);
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLLegendElement.h b/Source/WebCore/html/HTMLLegendElement.h
new file mode 100644
index 0000000..732ef33
--- /dev/null
+++ b/Source/WebCore/html/HTMLLegendElement.h
@@ -0,0 +1,49 @@
+/*
+ * 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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLLegendElement_h
+#define HTMLLegendElement_h
+
+#include "HTMLFormControlElement.h"
+
+namespace WebCore {
+
+class HTMLLegendElement : public HTMLFormControlElement {
+public:
+ static PassRefPtr<HTMLLegendElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+
+private:
+ HTMLLegendElement(const QualifiedName&, Document*, HTMLFormElement*);
+
+ // Control in the legend's fieldset that gets focus and access key.
+ HTMLFormControlElement* associatedControl();
+
+ virtual bool supportsFocus() const;
+ virtual const AtomicString& formControlType() const;
+ virtual void accessKeyAction(bool sendToAnyElement);
+ virtual void focus(bool restorePreviousSelection = true);
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLLegendElement.idl b/Source/WebCore/html/HTMLLegendElement.idl
new file mode 100644
index 0000000..750f32a
--- /dev/null
+++ b/Source/WebCore/html/HTMLLegendElement.idl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLLegendElement : HTMLElement {
+ readonly attribute HTMLFormElement form;
+ attribute [Reflect] DOMString accessKey;
+ attribute [Reflect] DOMString align;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp
new file mode 100644
index 0000000..8b2ae08
--- /dev/null
+++ b/Source/WebCore/html/HTMLLinkElement.cpp
@@ -0,0 +1,520 @@
+/*
+ * 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 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Rob Buis (rwlbuis@gmail.com)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLLinkElement.h"
+
+#include "Attribute.h"
+#include "CachedCSSStyleSheet.h"
+#include "CachedResourceLoader.h"
+#include "CSSStyleSelector.h"
+#include "Document.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
+#include "FrameTree.h"
+#include "FrameView.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "MediaList.h"
+#include "MediaQueryEvaluator.h"
+#include "Page.h"
+#include "ResourceHandle.h"
+#include "ScriptEventListener.h"
+#include "Settings.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLLinkElement::HTMLLinkElement(const QualifiedName& tagName, Document* document, bool createdByParser)
+ : HTMLElement(tagName, document)
+#if ENABLE(LINK_PREFETCH)
+ , m_onloadTimer(this, &HTMLLinkElement::onloadTimerFired)
+#endif
+ , m_disabledState(Unset)
+ , m_loading(false)
+ , m_createdByParser(createdByParser)
+ , m_pendingSheetType(None)
+{
+ ASSERT(hasTagName(linkTag));
+}
+
+PassRefPtr<HTMLLinkElement> HTMLLinkElement::create(const QualifiedName& tagName, Document* document, bool createdByParser)
+{
+ return adoptRef(new HTMLLinkElement(tagName, document, createdByParser));
+}
+
+HTMLLinkElement::~HTMLLinkElement()
+{
+ if (m_sheet)
+ m_sheet->clearOwnerNode();
+
+ if (m_cachedSheet) {
+ m_cachedSheet->removeClient(this);
+ removePendingSheet();
+ }
+
+#if ENABLE(LINK_PREFETCH)
+ if (m_cachedLinkPrefetch)
+ m_cachedLinkPrefetch->removeClient(this);
+#endif
+}
+
+void HTMLLinkElement::setDisabledState(bool _disabled)
+{
+ DisabledState oldDisabledState = m_disabledState;
+ m_disabledState = _disabled ? Disabled : EnabledViaScript;
+ if (oldDisabledState != m_disabledState) {
+ // If we change the disabled state while the sheet is still loading, then we have to
+ // perform three checks:
+ if (isLoading()) {
+ // Check #1: The sheet becomes disabled while loading.
+ if (m_disabledState == Disabled)
+ removePendingSheet();
+
+ // Check #2: An alternate sheet becomes enabled while it is still loading.
+ if (m_relAttribute.m_isAlternate && m_disabledState == EnabledViaScript)
+ addPendingSheet(Blocking);
+
+ // Check #3: A main sheet becomes enabled while it was still loading and
+ // after it was disabled via script. It takes really terrible code to make this
+ // 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.m_isAlternate && m_disabledState == EnabledViaScript && oldDisabledState == Disabled)
+ addPendingSheet(Blocking);
+
+ // If the sheet is already loading just bail.
+ return;
+ }
+
+ // Load the sheet, since it's never been loaded before.
+ if (!m_sheet && m_disabledState == EnabledViaScript)
+ process();
+ else
+ document()->styleSelectorChanged(DeferRecalcStyle); // Update the style selector.
+ }
+}
+
+StyleSheet* HTMLLinkElement::sheet() const
+{
+ return m_sheet.get();
+}
+
+void HTMLLinkElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == relAttr) {
+ tokenizeRelAttribute(attr->value(), m_relAttribute);
+ process();
+ } else if (attr->name() == hrefAttr) {
+ m_url = document()->completeURL(stripLeadingAndTrailingHTMLSpaces(attr->value()));
+ process();
+ } else if (attr->name() == typeAttr) {
+ m_type = attr->value();
+ process();
+ } else if (attr->name() == mediaAttr) {
+ m_media = attr->value().string().lower();
+ process();
+ } else if (attr->name() == disabledAttr)
+ setDisabledState(!attr->isNull());
+ else if (attr->name() == onbeforeloadAttr)
+ setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, attr));
+#if ENABLE(LINK_PREFETCH)
+ else if (attr->name() == onloadAttr)
+ setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
+#endif
+ else {
+ if (attr->name() == titleAttr && m_sheet)
+ m_sheet->setTitle(attr->value());
+ HTMLElement::parseMappedAttribute(attr);
+ }
+}
+
+void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, RelAttribute& relAttribute)
+{
+ relAttribute.m_isStyleSheet = false;
+ relAttribute.m_isIcon = false;
+ relAttribute.m_isAlternate = false;
+ relAttribute.m_isDNSPrefetch = false;
+#if ENABLE(LINK_PREFETCH)
+ relAttribute.m_isLinkPrefetch = false;
+#endif
+#ifdef ANDROID_APPLE_TOUCH_ICON
+ relAttribute.m_isTouchIcon = false;
+ relAttribute.m_isPrecomposedTouchIcon = false;
+#endif
+ if (equalIgnoringCase(rel, "stylesheet"))
+ relAttribute.m_isStyleSheet = true;
+ else if (equalIgnoringCase(rel, "icon") || equalIgnoringCase(rel, "shortcut icon"))
+ relAttribute.m_isIcon = true;
+#ifdef ANDROID_APPLE_TOUCH_ICON
+ else if (equalIgnoringCase(rel, "apple-touch-icon"))
+ relAttribute.m_isTouchIcon = true;
+ else if (equalIgnoringCase(rel, "apple-touch-icon-precomposed"))
+ relAttribute.m_isPrecomposedTouchIcon = true;
+#endif
+ else if (equalIgnoringCase(rel, "dns-prefetch"))
+ relAttribute.m_isDNSPrefetch = true;
+#if ENABLE(LINK_PREFETCH)
+ else if (equalIgnoringCase(rel, "prefetch"))
+ relAttribute.m_isLinkPrefetch = true;
+#endif
+ else if (equalIgnoringCase(rel, "alternate stylesheet") || equalIgnoringCase(rel, "stylesheet alternate")) {
+ relAttribute.m_isStyleSheet = true;
+ relAttribute.m_isAlternate = true;
+ } else {
+ // Tokenize the rel attribute and set bits based on specific keywords that we find.
+ String relString = rel.string();
+ relString.replace('\n', ' ');
+ Vector<String> list;
+ relString.split(' ', list);
+ Vector<String>::const_iterator end = list.end();
+ for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
+ if (equalIgnoringCase(*it, "stylesheet"))
+ relAttribute.m_isStyleSheet = true;
+ else if (equalIgnoringCase(*it, "alternate"))
+ relAttribute.m_isAlternate = true;
+ else if (equalIgnoringCase(*it, "icon"))
+ relAttribute.m_isIcon = true;
+ }
+ }
+}
+
+void HTMLLinkElement::process()
+{
+ if (!inDocument()) {
+ ASSERT(!m_sheet);
+ return;
+ }
+
+ String type = m_type.lower();
+
+ // IE extension: location of small icon for locationbar / bookmarks
+ // We'll record this URL per document, even if we later only use it in top level frames
+ if (m_relAttribute.m_isIcon && m_url.isValid() && !m_url.isEmpty())
+ document()->setIconURL(m_url.string(), type);
+
+#ifdef ANDROID_APPLE_TOUCH_ICON
+ if ((m_relAttribute.m_isTouchIcon || m_relAttribute.m_isPrecomposedTouchIcon) && m_url.isValid()
+ && !m_url.isEmpty() && document()->frame())
+ document()->frame()->loader()->client()
+ ->dispatchDidReceiveTouchIconURL(m_url.string(),
+ m_relAttribute.m_isPrecomposedTouchIcon);
+#endif
+
+ if (m_relAttribute.m_isDNSPrefetch) {
+ Settings* settings = document()->settings();
+ // FIXME: The href attribute of the link element can be in "//hostname" form, and we shouldn't attempt
+ // to complete that as URL <https://bugs.webkit.org/show_bug.cgi?id=48857>.
+ if (settings && settings->dnsPrefetchingEnabled() && m_url.isValid() && !m_url.isEmpty())
+ ResourceHandle::prepareForURL(m_url);
+ }
+
+#if ENABLE(LINK_PREFETCH)
+ if (m_relAttribute.m_isLinkPrefetch && m_url.isValid() && document()->frame()) {
+ m_cachedLinkPrefetch = document()->cachedResourceLoader()->requestLinkPrefetch(m_url);
+ if (m_cachedLinkPrefetch)
+ m_cachedLinkPrefetch->addClient(this);
+ }
+#endif
+
+ bool acceptIfTypeContainsTextCSS = document()->page() && document()->page()->settings() && document()->page()->settings()->treatsAnyTextCSSLinkAsStylesheet();
+
+ if (m_disabledState != Disabled && (m_relAttribute.m_isStyleSheet || (acceptIfTypeContainsTextCSS && type.contains("text/css")))
+ && document()->frame() && m_url.isValid()) {
+
+ String charset = getAttribute(charsetAttr);
+ if (charset.isEmpty() && document()->frame())
+ charset = document()->frame()->loader()->writer()->encoding();
+
+ if (m_cachedSheet) {
+ removePendingSheet();
+ m_cachedSheet->removeClient(this);
+ m_cachedSheet = 0;
+ }
+
+ RefPtr<Document> originalDocument = document();
+ if (!dispatchBeforeLoadEvent(m_url))
+ return;
+ // A beforeload handler might have removed us from the document or changed the document.
+ if (!inDocument() || document() != originalDocument)
+ return;
+
+ m_loading = true;
+
+ bool mediaQueryMatches = true;
+ if (!m_media.isEmpty()) {
+ RefPtr<RenderStyle> documentStyle = CSSStyleSelector::styleForDocument(document());
+ RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(m_media);
+ MediaQueryEvaluator evaluator(document()->frame()->view()->mediaType(), document()->frame(), documentStyle.get());
+ mediaQueryMatches = evaluator.eval(media.get());
+ }
+
+ // Don't hold up render tree construction and script execution on stylesheets
+ // that are not needed for the rendering at the moment.
+ bool blocking = mediaQueryMatches && !isAlternate();
+ addPendingSheet(blocking ? Blocking : NonBlocking);
+
+ // Load stylesheets that are not needed for the rendering immediately with low priority.
+ ResourceLoadPriority priority = blocking ? ResourceLoadPriorityUnresolved : ResourceLoadPriorityVeryLow;
+ m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(m_url, charset, priority);
+
+ if (m_cachedSheet)
+ m_cachedSheet->addClient(this);
+ else {
+ // The request may have been denied if (for example) the stylesheet is local and the document is remote.
+ m_loading = false;
+ removePendingSheet();
+ }
+ } else if (m_sheet) {
+ // we no longer contain a stylesheet, e.g. perhaps rel or type was changed
+ m_sheet = 0;
+ document()->styleSelectorChanged(DeferRecalcStyle);
+ }
+}
+
+void HTMLLinkElement::insertedIntoDocument()
+{
+ HTMLElement::insertedIntoDocument();
+ document()->addStyleSheetCandidateNode(this, m_createdByParser);
+
+ process();
+}
+
+void HTMLLinkElement::removedFromDocument()
+{
+ HTMLElement::removedFromDocument();
+
+ document()->removeStyleSheetCandidateNode(this);
+
+ if (m_sheet) {
+ ASSERT(m_sheet->ownerNode() == this);
+ m_sheet->clearOwnerNode();
+ m_sheet = 0;
+ }
+
+ if (document()->renderer())
+ document()->styleSelectorChanged(DeferRecalcStyle);
+}
+
+void HTMLLinkElement::finishParsingChildren()
+{
+ m_createdByParser = false;
+ HTMLElement::finishParsingChildren();
+}
+
+void HTMLLinkElement::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* sheet)
+{
+ if (!inDocument()) {
+ ASSERT(!m_sheet);
+ return;
+ }
+
+ m_sheet = CSSStyleSheet::create(this, href, baseURL, charset);
+
+ bool strictParsing = !document()->inQuirksMode();
+ bool enforceMIMEType = strictParsing;
+ bool crossOriginCSS = false;
+ bool validMIMEType = false;
+ bool needsSiteSpecificQuirks = document()->page() && document()->page()->settings()->needsSiteSpecificQuirks();
+
+ // Check to see if we should enforce the MIME type of the CSS resource in strict mode.
+ // Running in iWeb 2 is one example of where we don't want to - <rdar://problem/6099748>
+ if (enforceMIMEType && document()->page() && !document()->page()->settings()->enforceCSSMIMETypeInNoQuirksMode())
+ enforceMIMEType = false;
+
+#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD)
+ if (enforceMIMEType && needsSiteSpecificQuirks) {
+ // Covers both http and https, with or without "www."
+ if (baseURL.string().contains("mcafee.com/japan/", false))
+ enforceMIMEType = false;
+ }
+#endif
+
+ String sheetText = sheet->sheetText(enforceMIMEType, &validMIMEType);
+ m_sheet->parseString(sheetText, strictParsing);
+
+ // If we're loading a stylesheet cross-origin, and the MIME type is not
+ // standard, require the CSS to at least start with a syntactically
+ // valid CSS rule.
+ // This prevents an attacker playing games by injecting CSS strings into
+ // HTML, XML, JSON, etc. etc.
+ if (!document()->securityOrigin()->canRequest(baseURL))
+ crossOriginCSS = true;
+
+ if (crossOriginCSS && !validMIMEType && !m_sheet->hasSyntacticallyValidCSSHeader())
+ m_sheet = CSSStyleSheet::create(this, href, baseURL, charset);
+
+ if (strictParsing && needsSiteSpecificQuirks) {
+ // Work around <https://bugs.webkit.org/show_bug.cgi?id=28350>.
+ DEFINE_STATIC_LOCAL(const String, slashKHTMLFixesDotCss, ("/KHTMLFixes.css"));
+ DEFINE_STATIC_LOCAL(const String, mediaWikiKHTMLFixesStyleSheet, ("/* KHTML fix stylesheet */\n/* work around the horizontal scrollbars */\n#column-content { margin-left: 0; }\n\n"));
+ // There are two variants of KHTMLFixes.css. One is equal to mediaWikiKHTMLFixesStyleSheet,
+ // while the other lacks the second trailing newline.
+ if (baseURL.string().endsWith(slashKHTMLFixesDotCss) && !sheetText.isNull() && mediaWikiKHTMLFixesStyleSheet.startsWith(sheetText)
+ && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1) {
+ ASSERT(m_sheet->length() == 1);
+ ExceptionCode ec;
+ m_sheet->deleteRule(0, ec);
+ }
+ }
+
+ m_sheet->setTitle(title());
+
+ RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(m_media);
+ m_sheet->setMedia(media.get());
+
+ m_loading = false;
+ m_sheet->checkLoaded();
+}
+
+bool HTMLLinkElement::isLoading() const
+{
+ if (m_loading)
+ return true;
+ if (!m_sheet)
+ return false;
+ return static_cast<CSSStyleSheet *>(m_sheet.get())->isLoading();
+}
+
+#if ENABLE(LINK_PREFETCH)
+void HTMLLinkElement::onloadTimerFired(Timer<HTMLLinkElement>* timer)
+{
+ ASSERT_UNUSED(timer, timer == &m_onloadTimer);
+ dispatchEvent(Event::create(eventNames().loadEvent, false, false));
+}
+
+void HTMLLinkElement::notifyFinished(CachedResource* resource)
+{
+ m_onloadTimer.startOneShot(0);
+ if (m_cachedLinkPrefetch.get() == resource) {
+ m_cachedLinkPrefetch->removeClient(this);
+ m_cachedLinkPrefetch = 0;
+ }
+}
+#endif
+
+bool HTMLLinkElement::sheetLoaded()
+{
+ if (!isLoading()) {
+ removePendingSheet();
+ return true;
+ }
+ return false;
+}
+
+bool HTMLLinkElement::isURLAttribute(Attribute *attr) const
+{
+ return attr->name() == hrefAttr;
+}
+
+KURL HTMLLinkElement::href() const
+{
+ return document()->completeURL(getAttribute(hrefAttr));
+}
+
+String HTMLLinkElement::rel() const
+{
+ return getAttribute(relAttr);
+}
+
+String HTMLLinkElement::target() const
+{
+ return getAttribute(targetAttr);
+}
+
+String HTMLLinkElement::type() const
+{
+ return getAttribute(typeAttr);
+}
+
+void HTMLLinkElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+{
+ HTMLElement::addSubresourceAttributeURLs(urls);
+
+ // Favicons are handled by a special case in LegacyWebArchive::create()
+ if (m_relAttribute.m_isIcon)
+ return;
+
+ if (!m_relAttribute.m_isStyleSheet)
+ return;
+
+ // Append the URL of this link element.
+ addSubresourceURL(urls, href());
+
+ // Walk the URLs linked by the linked-to stylesheet.
+ if (StyleSheet* styleSheet = const_cast<HTMLLinkElement*>(this)->sheet())
+ styleSheet->addSubresourceStyleURLs(urls);
+}
+
+#ifdef ANDROID_INSTRUMENT
+void* HTMLLinkElement::operator new(size_t size)
+{
+ return Node::operator new(size);
+}
+
+void* HTMLLinkElement::operator new[](size_t size)
+{
+ return Node::operator new[](size);
+}
+
+void HTMLLinkElement::operator delete(void* p, size_t size)
+{
+ Node::operator delete(p, size);
+}
+
+void HTMLLinkElement::operator delete[](void* p, size_t size)
+{
+ Node::operator delete[](p, size);
+}
+#endif
+
+void HTMLLinkElement::addPendingSheet(PendingSheetType type)
+{
+ if (type <= m_pendingSheetType)
+ return;
+ m_pendingSheetType = type;
+
+ if (m_pendingSheetType == NonBlocking)
+ return;
+ document()->addPendingSheet();
+}
+
+void HTMLLinkElement::removePendingSheet()
+{
+ PendingSheetType type = m_pendingSheetType;
+ m_pendingSheetType = None;
+
+ if (type == None)
+ return;
+ if (type == NonBlocking) {
+ // Document::removePendingSheet() triggers the style selector recalc for blocking sheets.
+ document()->styleSelectorChanged(RecalcStyleImmediately);
+ return;
+ }
+ document()->removePendingSheet();
+}
+
+}
diff --git a/Source/WebCore/html/HTMLLinkElement.h b/Source/WebCore/html/HTMLLinkElement.h
new file mode 100644
index 0000000..e1198b1
--- /dev/null
+++ b/Source/WebCore/html/HTMLLinkElement.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLLinkElement_h
+#define HTMLLinkElement_h
+
+#include "CSSStyleSheet.h"
+#include "CachedResourceClient.h"
+#include "CachedResourceHandle.h"
+#include "HTMLElement.h"
+#include "Timer.h"
+
+namespace WebCore {
+
+class CachedCSSStyleSheet;
+class CachedResource;
+class KURL;
+
+class HTMLLinkElement : public HTMLElement, public CachedResourceClient {
+public:
+ struct RelAttribute {
+ bool m_isStyleSheet;
+ bool m_isIcon;
+ bool m_isAlternate;
+ bool m_isDNSPrefetch;
+#ifdef ANDROID_APPLE_TOUCH_ICON
+ bool m_isTouchIcon;
+ bool m_isPrecomposedTouchIcon;
+#endif
+#if ENABLE(LINK_PREFETCH)
+ bool m_isLinkPrefetch;
+#endif
+
+ RelAttribute()
+ : m_isStyleSheet(false)
+ , m_isIcon(false)
+ , m_isAlternate(false)
+ , m_isDNSPrefetch(false)
+#if ENABLE(LINK_PREFETCH)
+ , m_isLinkPrefetch(false)
+#endif
+ {
+ }
+ };
+
+ static PassRefPtr<HTMLLinkElement> create(const QualifiedName&, Document*, bool createdByParser);
+ virtual ~HTMLLinkElement();
+
+ KURL href() const;
+ String rel() const;
+
+ virtual String target() const;
+
+ String type() const;
+
+ StyleSheet* sheet() const;
+
+ bool isLoading() const;
+
+ bool isDisabled() const { return m_disabledState == Disabled; }
+ bool isEnabledViaScript() const { return m_disabledState == EnabledViaScript; }
+ bool isIcon() const { return m_relAttribute.m_isIcon; }
+
+private:
+ virtual void parseMappedAttribute(Attribute*);
+
+#if ENABLE(LINK_PREFETCH)
+ void onloadTimerFired(Timer<HTMLLinkElement>*);
+#endif
+ void process();
+ static void processCallback(Node*);
+
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
+ // from CachedResourceClient
+ virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* sheet);
+#if ENABLE(LINK_PREFETCH)
+ virtual void notifyFinished(CachedResource*);
+#endif
+ virtual bool sheetLoaded();
+
+ bool isAlternate() const { return m_disabledState == Unset && m_relAttribute.m_isAlternate; }
+
+ void setDisabledState(bool _disabled);
+
+ virtual bool isURLAttribute(Attribute*) const;
+
+public:
+ static void tokenizeRelAttribute(const AtomicString& value, RelAttribute&);
+
+private:
+ virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+
+ virtual void finishParsingChildren();
+
+ enum PendingSheetType { None, NonBlocking, Blocking };
+ void addPendingSheet(PendingSheetType);
+ void removePendingSheet();
+
+#ifdef ANDROID_INSTRUMENT
+ // Overridden to resolve the ambiguous
+ void* operator new(size_t size);
+ void* operator new[](size_t size);
+ void operator delete(void* p, size_t size);
+ void operator delete[](void* p, size_t size);
+#endif
+
+private:
+ HTMLLinkElement(const QualifiedName&, Document*, bool createdByParser);
+
+ enum DisabledState {
+ Unset,
+ EnabledViaScript,
+ Disabled
+ };
+
+ CachedResourceHandle<CachedCSSStyleSheet> m_cachedSheet;
+ RefPtr<CSSStyleSheet> m_sheet;
+#if ENABLE(LINK_PREFETCH)
+ CachedResourceHandle<CachedResource> m_cachedLinkPrefetch;
+ Timer<HTMLLinkElement> m_onloadTimer;
+#endif
+ KURL m_url;
+ String m_type;
+ String m_media;
+ DisabledState m_disabledState;
+ RelAttribute m_relAttribute;
+ bool m_loading;
+ bool m_createdByParser;
+
+ PendingSheetType m_pendingSheetType;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLLinkElement.idl b/Source/WebCore/html/HTMLLinkElement.idl
new file mode 100644
index 0000000..9419e15
--- /dev/null
+++ b/Source/WebCore/html/HTMLLinkElement.idl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [CustomMarkFunction] HTMLLinkElement : HTMLElement {
+ attribute [Reflect] boolean disabled;
+ attribute [Reflect] DOMString charset;
+ attribute [Reflect, URL] DOMString href;
+ attribute [Reflect] DOMString hreflang;
+ attribute [Reflect] DOMString media;
+ attribute [Reflect] DOMString rel;
+ attribute [Reflect] DOMString rev;
+ attribute [Reflect] DOMString target;
+ attribute [Reflect] DOMString type;
+
+ // DOM Level 2 Style
+ readonly attribute StyleSheet sheet;
+
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+ // Objective-C extension:
+ readonly attribute URL absoluteLinkURL;
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLMapElement.cpp b/Source/WebCore/html/HTMLMapElement.cpp
new file mode 100644
index 0000000..873a9ab
--- /dev/null
+++ b/Source/WebCore/html/HTMLMapElement.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLMapElement.h"
+
+#include "Attribute.h"
+#include "Document.h"
+#include "HTMLAreaElement.h"
+#include "HTMLCollection.h"
+#include "HTMLImageElement.h"
+#include "HTMLNames.h"
+#include "HitTestResult.h"
+#include "IntSize.h"
+#include "RenderObject.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLMapElement::HTMLMapElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(mapTag));
+}
+
+PassRefPtr<HTMLMapElement> HTMLMapElement::create(Document* document)
+{
+ return adoptRef(new HTMLMapElement(mapTag, document));
+}
+
+PassRefPtr<HTMLMapElement> HTMLMapElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLMapElement(tagName, document));
+}
+
+HTMLMapElement::~HTMLMapElement()
+{
+}
+
+bool HTMLMapElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestResult& result)
+{
+ HTMLAreaElement* defaultArea = 0;
+ Node *node = this;
+ while ((node = node->traverseNextNode(this))) {
+ if (node->hasTagName(areaTag)) {
+ HTMLAreaElement* areaElt = static_cast<HTMLAreaElement*>(node);
+ if (areaElt->isDefault()) {
+ if (!defaultArea)
+ defaultArea = areaElt;
+ } else if (areaElt->mapMouseEvent(x, y, size, result))
+ return true;
+ }
+ }
+
+ if (defaultArea) {
+ result.setInnerNode(defaultArea);
+ result.setURLElement(defaultArea);
+ }
+ return defaultArea;
+}
+
+HTMLImageElement* HTMLMapElement::imageElement() const
+{
+ RefPtr<HTMLCollection> coll = document()->images();
+ for (Node* curr = coll->firstItem(); curr; curr = coll->nextItem()) {
+ if (!curr->hasTagName(imgTag))
+ continue;
+
+ // The HTMLImageElement's useMap() value includes the '#' symbol at the beginning,
+ // which has to be stripped off.
+ HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(curr);
+ String useMapName = imageElement->getAttribute(usemapAttr).string().substring(1);
+ if (equalIgnoringCase(useMapName, m_name))
+ return imageElement;
+ }
+
+ return 0;
+}
+
+void HTMLMapElement::parseMappedAttribute(Attribute* attribute)
+{
+ // FIXME: This logic seems wrong for XML documents.
+ // Either the id or name will be used depending on the order the attributes are parsed.
+
+ const QualifiedName& attrName = attribute->name();
+ if (isIdAttributeName(attrName) || attrName == nameAttr) {
+ Document* document = this->document();
+ if (isIdAttributeName(attrName)) {
+ // Call base class so that hasID bit gets set.
+ HTMLElement::parseMappedAttribute(attribute);
+ if (document->isHTMLDocument())
+ return;
+ }
+ if (inDocument())
+ document->removeImageMap(this);
+ String mapName = attribute->value();
+ if (mapName[0] == '#')
+ mapName = mapName.substring(1);
+ m_name = document->isHTMLDocument() ? mapName.lower() : mapName;
+ if (inDocument())
+ document->addImageMap(this);
+ return;
+ }
+
+ HTMLElement::parseMappedAttribute(attribute);
+}
+
+PassRefPtr<HTMLCollection> HTMLMapElement::areas()
+{
+ return HTMLCollection::create(this, MapAreas);
+}
+
+void HTMLMapElement::insertedIntoDocument()
+{
+ document()->addImageMap(this);
+ HTMLElement::insertedIntoDocument();
+}
+
+void HTMLMapElement::removedFromDocument()
+{
+ document()->removeImageMap(this);
+ HTMLElement::removedFromDocument();
+}
+
+}
diff --git a/Source/WebCore/html/HTMLMapElement.h b/Source/WebCore/html/HTMLMapElement.h
new file mode 100644
index 0000000..c0c1395
--- /dev/null
+++ b/Source/WebCore/html/HTMLMapElement.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2004, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLMapElement_h
+#define HTMLMapElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class IntSize;
+class HitTestResult;
+class HTMLImageElement;
+
+class HTMLMapElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLMapElement> create(Document*);
+ static PassRefPtr<HTMLMapElement> create(const QualifiedName&, Document*);
+ virtual ~HTMLMapElement();
+
+ const AtomicString& getName() const { return m_name; }
+
+ bool mapMouseEvent(int x, int y, const IntSize&, HitTestResult&);
+
+ HTMLImageElement* imageElement() const;
+ PassRefPtr<HTMLCollection> areas();
+
+private:
+ HTMLMapElement(const QualifiedName&, Document*);
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
+ AtomicString m_name;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLMapElement.idl b/Source/WebCore/html/HTMLMapElement.idl
new file mode 100644
index 0000000..7811c9a
--- /dev/null
+++ b/Source/WebCore/html/HTMLMapElement.idl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLMapElement : HTMLElement {
+ readonly attribute HTMLCollection areas;
+ attribute [Reflect] DOMString name;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLMarqueeElement.cpp b/Source/WebCore/html/HTMLMarqueeElement.cpp
new file mode 100644
index 0000000..053ffa8
--- /dev/null
+++ b/Source/WebCore/html/HTMLMarqueeElement.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLMarqueeElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "ExceptionCode.h"
+#include "HTMLNames.h"
+#include "RenderLayer.h"
+#include "RenderMarquee.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+// WinIE uses 60ms as the minimum delay by default.
+const int defaultMinimumDelay = 60;
+
+inline HTMLMarqueeElement::HTMLMarqueeElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , ActiveDOMObject(document, this)
+ , m_minimumDelay(defaultMinimumDelay)
+{
+ ASSERT(hasTagName(marqueeTag));
+}
+
+PassRefPtr<HTMLMarqueeElement> HTMLMarqueeElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLMarqueeElement(tagName, document));
+}
+
+bool HTMLMarqueeElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == widthAttr ||
+ attrName == heightAttr ||
+ attrName == bgcolorAttr ||
+ attrName == vspaceAttr ||
+ attrName == hspaceAttr ||
+ attrName == scrollamountAttr ||
+ attrName == scrolldelayAttr ||
+ attrName == loopAttr ||
+ attrName == behaviorAttr ||
+ attrName == directionAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLMarqueeElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == widthAttr) {
+ if (!attr->value().isEmpty())
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
+ } else if (attr->name() == heightAttr) {
+ if (!attr->value().isEmpty())
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
+ } else if (attr->name() == bgcolorAttr) {
+ if (!attr->value().isEmpty())
+ addCSSColor(attr, CSSPropertyBackgroundColor, attr->value());
+ } else if (attr->name() == vspaceAttr) {
+ if (!attr->value().isEmpty()) {
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
+ }
+ } else if (attr->name() == hspaceAttr) {
+ if (!attr->value().isEmpty()) {
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
+ }
+ } else if (attr->name() == scrollamountAttr) {
+ if (!attr->value().isEmpty())
+ addCSSLength(attr, CSSPropertyWebkitMarqueeIncrement, attr->value());
+ } else if (attr->name() == scrolldelayAttr) {
+ if (!attr->value().isEmpty())
+ addCSSLength(attr, CSSPropertyWebkitMarqueeSpeed, attr->value());
+ } else if (attr->name() == loopAttr) {
+ if (!attr->value().isEmpty()) {
+ if (attr->value() == "-1" || equalIgnoringCase(attr->value(), "infinite"))
+ addCSSProperty(attr, CSSPropertyWebkitMarqueeRepetition, CSSValueInfinite);
+ else
+ addCSSLength(attr, CSSPropertyWebkitMarqueeRepetition, attr->value());
+ }
+ } else if (attr->name() == behaviorAttr) {
+ if (!attr->value().isEmpty())
+ addCSSProperty(attr, CSSPropertyWebkitMarqueeStyle, attr->value());
+ } else if (attr->name() == directionAttr) {
+ if (!attr->value().isEmpty())
+ addCSSProperty(attr, CSSPropertyWebkitMarqueeDirection, attr->value());
+ } else if (attr->name() == truespeedAttr)
+ m_minimumDelay = !attr->isEmpty() ? 0 : defaultMinimumDelay;
+ else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+void HTMLMarqueeElement::start()
+{
+ if (RenderMarquee* marqueeRenderer = renderMarquee())
+ marqueeRenderer->start();
+}
+
+void HTMLMarqueeElement::stop()
+{
+ if (RenderMarquee* marqueeRenderer = renderMarquee())
+ marqueeRenderer->stop();
+}
+
+int HTMLMarqueeElement::scrollAmount() const
+{
+ bool ok;
+ int scrollAmount = fastGetAttribute(scrollamountAttr).toInt(&ok);
+ return ok && scrollAmount >= 0 ? scrollAmount : RenderStyle::initialMarqueeIncrement().value();
+}
+
+void HTMLMarqueeElement::setScrollAmount(int scrollAmount, ExceptionCode& ec)
+{
+ if (scrollAmount < 0)
+ ec = INDEX_SIZE_ERR;
+ else
+ setIntegralAttribute(scrollamountAttr, scrollAmount);
+}
+
+int HTMLMarqueeElement::scrollDelay() const
+{
+ bool ok;
+ int scrollDelay = fastGetAttribute(scrolldelayAttr).toInt(&ok);
+ return ok && scrollDelay >= 0 ? scrollDelay : RenderStyle::initialMarqueeSpeed();
+}
+
+void HTMLMarqueeElement::setScrollDelay(int scrollDelay, ExceptionCode& ec)
+{
+ if (scrollDelay < 0)
+ ec = INDEX_SIZE_ERR;
+ else
+ setIntegralAttribute(scrolldelayAttr, scrollDelay);
+}
+
+int HTMLMarqueeElement::loop() const
+{
+ bool ok;
+ int loopValue = fastGetAttribute(loopAttr).toInt(&ok);
+ return ok && loopValue > 0 ? loopValue : -1;
+}
+
+void HTMLMarqueeElement::setLoop(int loop, ExceptionCode& ec)
+{
+ if (loop <= 0 && loop != -1)
+ ec = INDEX_SIZE_ERR;
+ else
+ setIntegralAttribute(loopAttr, loop);
+}
+
+bool HTMLMarqueeElement::canSuspend() const
+{
+ return true;
+}
+
+void HTMLMarqueeElement::suspend(ReasonForSuspension)
+{
+ if (RenderMarquee* marqueeRenderer = renderMarquee())
+ marqueeRenderer->suspend();
+}
+
+void HTMLMarqueeElement::resume()
+{
+ if (RenderMarquee* marqueeRenderer = renderMarquee())
+ marqueeRenderer->updateMarqueePosition();
+}
+
+RenderMarquee* HTMLMarqueeElement::renderMarquee() const
+{
+ if (renderer() && renderer()->hasLayer())
+ return renderBoxModelObject()->layer()->marquee();
+ return 0;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLMarqueeElement.h b/Source/WebCore/html/HTMLMarqueeElement.h
new file mode 100644
index 0000000..586aa6f
--- /dev/null
+++ b/Source/WebCore/html/HTMLMarqueeElement.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLMarqueeElement_h
+#define HTMLMarqueeElement_h
+
+#include "ActiveDOMObject.h"
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class RenderMarquee;
+
+class HTMLMarqueeElement : public HTMLElement, private ActiveDOMObject {
+public:
+ static PassRefPtr<HTMLMarqueeElement> create(const QualifiedName&, Document*);
+
+ int minimumDelay() const { return m_minimumDelay; }
+
+ // DOM Functions
+
+ void start();
+ void stop();
+
+ int scrollAmount() const;
+ void setScrollAmount(int, ExceptionCode&);
+
+ int scrollDelay() const;
+ void setScrollDelay(int, ExceptionCode&);
+
+ int loop() const;
+ void setLoop(int, ExceptionCode&);
+
+private:
+ HTMLMarqueeElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ // ActiveDOMObject
+ virtual bool canSuspend() const;
+ virtual void suspend(ReasonForSuspension);
+ virtual void resume();
+
+ RenderMarquee* renderMarquee() const;
+
+ int m_minimumDelay;
+};
+
+} // namespace WebCore
+
+#endif // HTMLMarqueeElement_h
diff --git a/Source/WebCore/html/HTMLMarqueeElement.idl b/Source/WebCore/html/HTMLMarqueeElement.idl
new file mode 100644
index 0000000..3174fac
--- /dev/null
+++ b/Source/WebCore/html/HTMLMarqueeElement.idl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLMarqueeElement : HTMLElement {
+ void start();
+ void stop();
+
+ attribute [Reflect] DOMString behavior;
+ attribute [Reflect] DOMString bgColor;
+ attribute [Reflect] DOMString direction;
+ attribute [Reflect] DOMString height;
+ attribute [Reflect] unsigned long hspace;
+ attribute long loop setter raises(DOMException);
+ attribute long scrollAmount setter raises(DOMException);
+ attribute long scrollDelay setter raises(DOMException);
+ attribute [Reflect] boolean trueSpeed;
+ attribute [Reflect] unsigned long vspace;
+ attribute [Reflect] DOMString width;
+
+ // FIXME: Implement the following event handler attributes
+ // https://bugs.webkit.org/show_bug.cgi?id=49788
+ // attribute EventListener onbounce;
+ // attribute EventListener onfinish;
+ // attribute EventListener onstart;
+ };
+}
diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp
new file mode 100644
index 0000000..43d53f5
--- /dev/null
+++ b/Source/WebCore/html/HTMLMediaElement.cpp
@@ -0,0 +1,2521 @@
+/*
+ * Copyright (C) 2007, 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,
+ * 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 "HTMLMediaElement.h"
+
+#include "Attribute.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "ClientRect.h"
+#include "ClientRectList.h"
+#include "ContentType.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "Event.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
+#include "FrameView.h"
+#include "HTMLDocument.h"
+#include "HTMLNames.h"
+#include "HTMLSourceElement.h"
+#include "HTMLVideoElement.h"
+#include "Logging.h"
+#include "MediaDocument.h"
+#include "MediaError.h"
+#include "MediaList.h"
+#include "MediaPlayer.h"
+#include "MediaQueryEvaluator.h"
+#include "MIMETypeRegistry.h"
+#include "Page.h"
+#include "RenderVideo.h"
+#include "RenderView.h"
+#include "ScriptEventListener.h"
+#include "Settings.h"
+#include "TimeRanges.h"
+#include <limits>
+#include <wtf/CurrentTime.h>
+#include <wtf/MathExtras.h>
+#include <wtf/text/CString.h>
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderView.h"
+#include "RenderLayerCompositor.h"
+#endif
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "RenderEmbeddedObject.h"
+#include "Widget.h"
+#endif
+
+using namespace std;
+
+namespace WebCore {
+
+#if !LOG_DISABLED
+static String urlForLogging(const String& url)
+{
+ static const unsigned maximumURLLengthForLogging = 128;
+
+ if (url.length() < maximumURLLengthForLogging)
+ return url;
+ return url.substring(0, maximumURLLengthForLogging) + "...";
+}
+
+static const char *boolString(bool val)
+{
+ return val ? "true" : "false";
+}
+#endif
+
+#ifndef LOG_MEDIA_EVENTS
+// Default to not logging events because so many are generated they can overwhelm the rest of
+// the logging.
+#define LOG_MEDIA_EVENTS 0
+#endif
+
+#ifndef LOG_CACHED_TIME_WARNINGS
+// Default to not logging warnings about excessive drift in the cached media time because it adds a
+// fair amount of overhead and logging.
+#define LOG_CACHED_TIME_WARNINGS 0
+#endif
+
+static const float invalidMediaTime = -1;
+
+using namespace HTMLNames;
+
+HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , ActiveDOMObject(document, this)
+ , m_loadTimer(this, &HTMLMediaElement::loadTimerFired)
+ , m_asyncEventTimer(this, &HTMLMediaElement::asyncEventTimerFired)
+ , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
+ , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired)
+ , m_playedTimeRanges()
+ , 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_lastSeekTime(0)
+ , m_previousProgress(0)
+ , m_previousProgressTime(numeric_limits<double>::max())
+ , m_lastTimeUpdateEventWallTime(0)
+ , m_lastTimeUpdateEventMovieTime(numeric_limits<float>::max())
+ , m_loadState(WaitingForSource)
+ , m_currentSourceNode(0)
+ , m_nextChildNodeToConsider(0)
+ , m_player(0)
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ , m_proxyWidget(0)
+#endif
+ , m_restrictions(NoRestrictions)
+ , m_preload(MediaPlayer::Auto)
+ , m_displayMode(Unknown)
+ , m_processingMediaPlayerCallback(0)
+ , m_cachedTime(invalidMediaTime)
+ , m_cachedTimeWallClockUpdateTime(0)
+ , m_minimumWallClockTimeToCacheMediaTime(0)
+ , m_playing(false)
+ , m_isWaitingUntilMediaCanStart(false)
+ , m_shouldDelayLoadEvent(false)
+ , m_haveFiredLoadedData(false)
+ , m_inActiveDocument(true)
+ , m_autoplaying(true)
+ , m_muted(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)
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ , m_needWidgetUpdate(false)
+#endif
+ , m_dispatchingCanPlayEvent(false)
+ , m_loadInitiatedByUserGesture(false)
+ , m_completelyLoaded(false)
+{
+ LOG(Media, "HTMLMediaElement::HTMLMediaElement");
+ document->registerForDocumentActivationCallbacks(this);
+ document->registerForMediaVolumeCallbacks(this);
+#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
+ // Enable the Media Element to listen to all the touch events
+ document->addListenerTypeIfNeeded(eventNames().touchstartEvent);
+#endif
+}
+
+HTMLMediaElement::~HTMLMediaElement()
+{
+ LOG(Media, "HTMLMediaElement::~HTMLMediaElement");
+ if (m_isWaitingUntilMediaCanStart)
+ document()->removeMediaCanStartListener(this);
+ setShouldDelayLoadEvent(false);
+ document()->unregisterForDocumentActivationCallbacks(this);
+ document()->unregisterForMediaVolumeCallbacks(this);
+}
+
+void HTMLMediaElement::willMoveToNewOwnerDocument()
+{
+ if (m_isWaitingUntilMediaCanStart)
+ document()->removeMediaCanStartListener(this);
+ setShouldDelayLoadEvent(false);
+ document()->unregisterForDocumentActivationCallbacks(this);
+ document()->unregisterForMediaVolumeCallbacks(this);
+ HTMLElement::willMoveToNewOwnerDocument();
+}
+
+void HTMLMediaElement::didMoveToNewOwnerDocument()
+{
+ if (m_isWaitingUntilMediaCanStart)
+ document()->addMediaCanStartListener(this);
+ if (m_readyState < HAVE_CURRENT_DATA)
+ setShouldDelayLoadEvent(true);
+ document()->registerForDocumentActivationCallbacks(this);
+ document()->registerForMediaVolumeCallbacks(this);
+ HTMLElement::didMoveToNewOwnerDocument();
+}
+
+void HTMLMediaElement::attributeChanged(Attribute* attr, bool preserveDecls)
+{
+ HTMLElement::attributeChanged(attr, preserveDecls);
+
+ const QualifiedName& attrName = attr->name();
+ if (attrName == srcAttr) {
+ // Trigger a reload, as long as the 'src' attribute is present.
+ if (!getAttribute(srcAttr).isEmpty())
+ scheduleLoad();
+ }
+ else if (attrName == controlsAttr) {
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (!isVideo() && attached() && (controls() != (renderer() != 0))) {
+ detach();
+ attach();
+ }
+ if (renderer())
+ renderer()->updateFromElement();
+#else
+ if (m_player)
+ m_player->setControls(controls());
+#endif
+ }
+}
+
+void HTMLMediaElement::parseMappedAttribute(Attribute* attr)
+{
+ const QualifiedName& attrName = attr->name();
+
+ if (attrName == preloadAttr) {
+ String value = attr->value();
+
+ if (equalIgnoringCase(value, "none"))
+ m_preload = MediaPlayer::None;
+ else if (equalIgnoringCase(value, "metadata"))
+ m_preload = MediaPlayer::MetaData;
+ else {
+ // The spec does not define an "invalid value default" but "auto" is suggested as the
+ // "missing value default", so use it for everything except "none" and "metadata"
+ m_preload = MediaPlayer::Auto;
+ }
+
+ // The attribute must be ignored if the autoplay attribute is present
+ if (!autoplay() && m_player)
+ m_player->setPreload(m_preload);
+
+ } else if (attrName == onabortAttr)
+ setAttributeEventListener(eventNames().abortEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onbeforeloadAttr)
+ setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, attr));
+ else if (attrName == oncanplayAttr)
+ setAttributeEventListener(eventNames().canplayEvent, createAttributeEventListener(this, attr));
+ else if (attrName == oncanplaythroughAttr)
+ setAttributeEventListener(eventNames().canplaythroughEvent, createAttributeEventListener(this, attr));
+ else if (attrName == ondurationchangeAttr)
+ setAttributeEventListener(eventNames().durationchangeEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onemptiedAttr)
+ setAttributeEventListener(eventNames().emptiedEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onendedAttr)
+ setAttributeEventListener(eventNames().endedEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onerrorAttr)
+ setAttributeEventListener(eventNames().errorEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onloadeddataAttr)
+ setAttributeEventListener(eventNames().loadeddataEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onloadedmetadataAttr)
+ setAttributeEventListener(eventNames().loadedmetadataEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onloadstartAttr)
+ setAttributeEventListener(eventNames().loadstartEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onpauseAttr)
+ setAttributeEventListener(eventNames().pauseEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onplayAttr)
+ setAttributeEventListener(eventNames().playEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onplayingAttr)
+ setAttributeEventListener(eventNames().playingEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onprogressAttr)
+ setAttributeEventListener(eventNames().progressEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onratechangeAttr)
+ setAttributeEventListener(eventNames().ratechangeEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onseekedAttr)
+ setAttributeEventListener(eventNames().seekedEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onseekingAttr)
+ setAttributeEventListener(eventNames().seekingEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onstalledAttr)
+ setAttributeEventListener(eventNames().stalledEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onsuspendAttr)
+ setAttributeEventListener(eventNames().suspendEvent, createAttributeEventListener(this, attr));
+ else if (attrName == ontimeupdateAttr)
+ setAttributeEventListener(eventNames().timeupdateEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onvolumechangeAttr)
+ setAttributeEventListener(eventNames().volumechangeEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onwaitingAttr)
+ setAttributeEventListener(eventNames().waitingEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onwebkitbeginfullscreenAttr)
+ setAttributeEventListener(eventNames().webkitbeginfullscreenEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onwebkitendfullscreenAttr)
+ setAttributeEventListener(eventNames().webkitendfullscreenEvent, createAttributeEventListener(this, attr));
+ else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+bool HTMLMediaElement::rendererIsNeeded(RenderStyle* style)
+{
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ UNUSED_PARAM(style);
+ Frame* frame = document()->frame();
+ if (!frame)
+ return false;
+
+ return true;
+#else
+ return controls() ? HTMLElement::rendererIsNeeded(style) : false;
+#endif
+}
+
+RenderObject* HTMLMediaElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ // Setup the renderer if we already have a proxy widget.
+ RenderEmbeddedObject* mediaRenderer = new (arena) RenderEmbeddedObject(this);
+ if (m_proxyWidget) {
+ mediaRenderer->setWidget(m_proxyWidget);
+
+ Frame* frame = document()->frame();
+ FrameLoader* loader = frame ? frame->loader() : 0;
+ if (loader)
+ loader->showMediaPlayerProxyPlugin(m_proxyWidget.get());
+ }
+ return mediaRenderer;
+#else
+ return new (arena) RenderMedia(this);
+#endif
+}
+
+void HTMLMediaElement::insertedIntoDocument()
+{
+ LOG(Media, "HTMLMediaElement::removedFromDocument");
+ HTMLElement::insertedIntoDocument();
+ if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY)
+ scheduleLoad();
+}
+
+void HTMLMediaElement::removedFromDocument()
+{
+ LOG(Media, "HTMLMediaElement::removedFromDocument");
+ if (m_networkState > NETWORK_EMPTY)
+ pause(processingUserGesture());
+ if (m_isFullscreen)
+ exitFullscreen();
+ HTMLElement::removedFromDocument();
+}
+
+void HTMLMediaElement::attach()
+{
+ ASSERT(!attached());
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ m_needWidgetUpdate = true;
+#endif
+
+ HTMLElement::attach();
+
+ if (renderer())
+ renderer()->updateFromElement();
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ else if (m_proxyWidget) {
+ Frame* frame = document()->frame();
+ FrameLoader* loader = frame ? frame->loader() : 0;
+ if (loader)
+ loader->hideMediaPlayerProxyPlugin(m_proxyWidget.get());
+ }
+#endif
+}
+
+void HTMLMediaElement::recalcStyle(StyleChange change)
+{
+ HTMLElement::recalcStyle(change);
+
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+void HTMLMediaElement::scheduleLoad()
+{
+ LOG(Media, "HTMLMediaElement::scheduleLoad");
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ createMediaPlayerProxy();
+#endif
+
+ if (m_loadTimer.isActive())
+ return;
+ prepareForLoad();
+ m_loadTimer.startOneShot(0);
+}
+
+void HTMLMediaElement::scheduleNextSourceChild()
+{
+ // Schedule the timer to try the next <source> element WITHOUT resetting state ala prepareForLoad.
+ m_loadTimer.startOneShot(0);
+}
+
+void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
+{
+#if LOG_MEDIA_EVENTS
+ LOG(Media, "HTMLMediaElement::scheduleEvent - scheduling '%s'", eventName.string().ascii().data());
+#endif
+ m_pendingEvents.append(Event::create(eventName, false, true));
+ if (!m_asyncEventTimer.isActive())
+ m_asyncEventTimer.startOneShot(0);
+}
+
+void HTMLMediaElement::asyncEventTimerFired(Timer<HTMLMediaElement>*)
+{
+ Vector<RefPtr<Event> > pendingEvents;
+ ExceptionCode ec = 0;
+
+ m_pendingEvents.swap(pendingEvents);
+ unsigned count = pendingEvents.size();
+ for (unsigned ndx = 0; ndx < count; ++ndx) {
+#if LOG_MEDIA_EVENTS
+ LOG(Media, "HTMLMediaElement::asyncEventTimerFired - dispatching '%s'", pendingEvents[ndx]->type().string().ascii().data());
+#endif
+ if (pendingEvents[ndx]->type() == eventNames().canplayEvent) {
+ m_dispatchingCanPlayEvent = true;
+ dispatchEvent(pendingEvents[ndx].release(), ec);
+ m_dispatchingCanPlayEvent = false;
+ } else
+ dispatchEvent(pendingEvents[ndx].release(), ec);
+ }
+}
+
+void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
+{
+ if (m_loadState == LoadingFromSourceElement)
+ loadNextSourceChild();
+ else
+ loadInternal();
+}
+
+PassRefPtr<MediaError> HTMLMediaElement::error() const
+{
+ return m_error;
+}
+
+void HTMLMediaElement::setSrc(const String& url)
+{
+ setAttribute(srcAttr, url);
+}
+
+String HTMLMediaElement::currentSrc() const
+{
+ return m_currentSrc;
+}
+
+HTMLMediaElement::NetworkState HTMLMediaElement::networkState() const
+{
+ return m_networkState;
+}
+
+String HTMLMediaElement::canPlayType(const String& mimeType) const
+{
+ MediaPlayer::SupportsType support = MediaPlayer::supportsType(ContentType(mimeType));
+ String canPlay;
+
+ // 4.8.10.3
+ switch (support)
+ {
+ case MediaPlayer::IsNotSupported:
+ canPlay = "";
+ break;
+ case MediaPlayer::MayBeSupported:
+ canPlay = "maybe";
+ break;
+ case MediaPlayer::IsSupported:
+ canPlay = "probably";
+ break;
+ }
+
+ LOG(Media, "HTMLMediaElement::canPlayType(%s) -> %s", mimeType.utf8().data(), canPlay.utf8().data());
+
+ return canPlay;
+}
+
+void HTMLMediaElement::load(bool isUserGesture, ExceptionCode& ec)
+{
+ LOG(Media, "HTMLMediaElement::load(isUserGesture : %s)", boolString(isUserGesture));
+
+ if (m_restrictions & RequireUserGestureForLoadRestriction && !isUserGesture)
+ ec = INVALID_STATE_ERR;
+ else {
+ m_loadInitiatedByUserGesture = isUserGesture;
+ prepareForLoad();
+ loadInternal();
+ }
+}
+
+void HTMLMediaElement::prepareForLoad()
+{
+ LOG(Media, "HTMLMediaElement::prepareForLoad");
+
+ // Perform the cleanup required for the resource load algorithm to run.
+ stopPeriodicTimers();
+ m_loadTimer.stop();
+ m_sentStalledEvent = false;
+ m_haveFiredLoadedData = false;
+ m_completelyLoaded = false;
+ m_displayMode = Unknown;
+
+ // 1 - Abort any already-running instance of the resource selection algorithm for this element.
+ m_loadState = WaitingForSource;
+ 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.
+ cancelPendingEventsAndCallbacks();
+
+ // 3 - If the media element's networkState is set to NETWORK_LOADING or NETWORK_IDLE, queue
+ // a task to fire a simple event named abort at the media element.
+ if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE)
+ scheduleEvent(eventNames().abortEvent);
+
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ m_player = MediaPlayer::create(this);
+#else
+ if (m_player)
+ m_player->cancelLoad();
+ else
+ createMediaPlayerProxy();
+#endif
+
+ // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps
+ if (m_networkState != NETWORK_EMPTY) {
+ m_networkState = NETWORK_EMPTY;
+ m_readyState = HAVE_NOTHING;
+ m_readyStateMaximum = HAVE_NOTHING;
+ refreshCachedTime();
+ m_paused = true;
+ m_seeking = false;
+ scheduleEvent(eventNames().emptiedEvent);
+ }
+
+ // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRate attribute.
+ setPlaybackRate(defaultPlaybackRate());
+
+ // 6 - Set the error attribute to null and the autoplaying flag to true.
+ m_error = 0;
+ m_autoplaying = true;
+
+ // 7 - Invoke the media element's resource selection algorithm.
+
+ // 8 - Note: Playback of any previously playing media resource for this element stops.
+
+ // The resource selection algorithm
+ // 1 - Set the networkState to NETWORK_NO_SOURCE
+ m_networkState = NETWORK_NO_SOURCE;
+
+ // 2 - Asynchronously await a stable state.
+
+ m_playedTimeRanges = TimeRanges::create();
+ m_lastSeekTime = 0;
+ m_closedCaptionsVisible = false;
+
+ // 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
+ // event may have already fired by then.
+ setShouldDelayLoadEvent(true);
+}
+
+void HTMLMediaElement::loadInternal()
+{
+ // If we can't start a load right away, start it later.
+ Page* page = document()->page();
+ if (page && !page->canStartMedia()) {
+ if (m_isWaitingUntilMediaCanStart)
+ return;
+ document()->addMediaCanStartListener(this);
+ m_isWaitingUntilMediaCanStart = true;
+ return;
+ }
+
+ selectMediaResource();
+}
+
+void HTMLMediaElement::selectMediaResource()
+{
+ LOG(Media, "HTMLMediaElement::selectMediaResource");
+
+ enum Mode { attribute, children };
+ Mode mode = attribute;
+
+ // 3 - ... the media element has neither a src attribute ...
+ if (!hasAttribute(srcAttr)) {
+ // ... nor a source element child: ...
+ Node* node;
+ for (node = firstChild(); node; node = node->nextSibling()) {
+ if (node->hasTagName(sourceTag))
+ break;
+ }
+
+ if (!node) {
+ m_loadState = WaitingForSource;
+ setShouldDelayLoadEvent(false);
+
+ // ... set the networkState to NETWORK_EMPTY, and abort these steps
+ m_networkState = NETWORK_EMPTY;
+
+ LOG(Media, "HTMLMediaElement::selectMediaResource, nothing to load");
+ return;
+ }
+
+ mode = children;
+ }
+
+ // 4 - Set the media element's delaying-the-load-event flag to true (this delays the load event),
+ // and set its networkState to NETWORK_LOADING.
+ setShouldDelayLoadEvent(true);
+ m_networkState = NETWORK_LOADING;
+
+ // 5
+ scheduleEvent(eventNames().loadstartEvent);
+
+ // 6 - If mode is attribute, then run these substeps
+ if (mode == attribute) {
+ // If the src attribute's value is the empty string ... jump down to the failed step below
+ KURL mediaURL = getNonEmptyURLAttribute(srcAttr);
+ if (mediaURL.isEmpty()) {
+ noneSupported();
+ LOG(Media, "HTMLMediaElement::selectMediaResource, empty 'src'");
+ return;
+ }
+
+ if (isSafeToLoadURL(mediaURL, Complain) && dispatchBeforeLoadEvent(mediaURL.string())) {
+ ContentType contentType("");
+ m_loadState = LoadingFromSrcAttr;
+ loadResource(mediaURL, contentType);
+ } else
+ noneSupported();
+
+ LOG(Media, "HTMLMediaElement::selectMediaResource, 'src' not used");
+ return;
+ }
+
+ // Otherwise, the source elements will be used
+ m_currentSourceNode = 0;
+ loadNextSourceChild();
+}
+
+void HTMLMediaElement::loadNextSourceChild()
+{
+ ContentType contentType("");
+ KURL mediaURL = selectNextSourceChild(&contentType, Complain);
+ if (!mediaURL.isValid()) {
+ waitForSourceChange();
+ return;
+ }
+
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ // Recreate the media player for the new url
+ m_player = MediaPlayer::create(this);
+#endif
+
+ m_loadState = LoadingFromSourceElement;
+ loadResource(mediaURL, contentType);
+}
+
+void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& contentType)
+{
+ ASSERT(isSafeToLoadURL(initialURL, Complain));
+
+ LOG(Media, "HTMLMediaElement::loadResource(%s, %s)", urlForLogging(initialURL.string()).utf8().data(), contentType.raw().utf8().data());
+
+ Frame* frame = document()->frame();
+ if (!frame)
+ return;
+ FrameLoader* loader = frame->loader();
+ if (!loader)
+ return;
+
+ KURL url(initialURL);
+ if (!loader->willLoadMediaElementURL(url))
+ return;
+
+ // The resource fetch algorithm
+ m_networkState = NETWORK_LOADING;
+
+ m_currentSrc = url;
+
+ LOG(Media, "HTMLMediaElement::loadResource - m_currentSrc -> %s", urlForLogging(m_currentSrc).utf8().data());
+
+ if (m_sendProgressEvents)
+ startProgressEventTimer();
+
+ if (!autoplay())
+ m_player->setPreload(m_preload);
+ m_player->setPreservesPitch(m_webkitPreservesPitch);
+ updateVolume();
+
+#if PLATFORM(ANDROID)
+ if (isVideo())
+ m_player->setMediaElementType(MediaPlayer::Video);
+ else
+ m_player->setMediaElementType(MediaPlayer::Audio);
+#endif
+ m_player->load(m_currentSrc, contentType);
+
+ // If there is no poster to display, allow the media engine to render video frames as soon as
+ // they are available.
+ updateDisplayState();
+
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidSourceAction actionIfInvalid)
+{
+ if (!url.isValid()) {
+ LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE because url is invalid", urlForLogging(url.string()).utf8().data());
+ return false;
+ }
+
+ Frame* frame = document()->frame();
+ if (!frame || !document()->securityOrigin()->canDisplay(url)) {
+ if (actionIfInvalid == Complain)
+ FrameLoader::reportLocalLoadFailed(frame, url.string());
+ LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE rejected by SecurityOrigin", urlForLogging(url.string()).utf8().data());
+ return false;
+ }
+
+ return true;
+}
+
+void HTMLMediaElement::startProgressEventTimer()
+{
+ if (m_progressEventTimer.isActive())
+ return;
+
+ m_previousProgressTime = WTF::currentTime();
+ m_previousProgress = 0;
+ // 350ms is not magic, it is in the spec!
+ m_progressEventTimer.startRepeating(0.350);
+}
+
+void HTMLMediaElement::waitForSourceChange()
+{
+ LOG(Media, "HTMLMediaElement::waitForSourceChange");
+
+ stopPeriodicTimers();
+ m_loadState = WaitingForSource;
+
+ // 6.17 - Waiting: Set the element's networkState attribute to the NETWORK_NO_SOURCE value
+ m_networkState = NETWORK_NO_SOURCE;
+
+ // 6.18 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
+ setShouldDelayLoadEvent(false);
+}
+
+void HTMLMediaElement::noneSupported()
+{
+ LOG(Media, "HTMLMediaElement::noneSupported");
+
+ stopPeriodicTimers();
+ m_loadState = WaitingForSource;
+ m_currentSourceNode = 0;
+
+ // 5 - Reaching this step indicates that either the URL failed to resolve, or the media
+ // resource failed to load. Set the error attribute to a new MediaError object whose
+ // code attribute is set to MEDIA_ERR_SRC_NOT_SUPPORTED.
+ m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
+
+ // 6 - Set the element's networkState attribute to the NETWORK_NO_SOURCE value.
+ m_networkState = NETWORK_NO_SOURCE;
+
+ // 7 - Queue a task to fire a progress event called error at the media element, in
+ // the context of the fetching process that was used to try to obtain the media
+ // resource in the resource fetch algorithm.
+ scheduleEvent(eventNames().errorEvent);
+
+ // 8 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
+ setShouldDelayLoadEvent(false);
+
+ // 9 -Abort these steps. Until the load() method is invoked, the element won't attempt to load another resource.
+
+ updateDisplayState();
+
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+void HTMLMediaElement::mediaEngineError(PassRefPtr<MediaError> err)
+{
+ LOG(Media, "HTMLMediaElement::mediaEngineError(%d)", static_cast<int>(err->code()));
+
+ // 1 - The user agent should cancel the fetching process.
+ stopPeriodicTimers();
+ m_loadState = WaitingForSource;
+
+ // 2 - Set the error attribute to a new MediaError object whose code attribute is
+ // set to MEDIA_ERR_NETWORK/MEDIA_ERR_DECODE.
+ m_error = err;
+
+ // 3 - Queue a task to fire a simple event named error at the media element.
+ scheduleEvent(eventNames().errorEvent);
+
+ // 4 - Set the element's networkState attribute to the NETWORK_EMPTY value and queue a
+ // task to fire a simple event called emptied at the element.
+ m_networkState = NETWORK_EMPTY;
+ scheduleEvent(eventNames().emptiedEvent);
+
+ // 5 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
+ setShouldDelayLoadEvent(false);
+
+ // 6 - Abort the overall resource selection algorithm.
+ m_currentSourceNode = 0;
+}
+
+void HTMLMediaElement::cancelPendingEventsAndCallbacks()
+{
+ LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks");
+
+ m_pendingEvents.clear();
+
+ for (Node* node = firstChild(); node; node = node->nextSibling()) {
+ if (node->hasTagName(sourceTag))
+ static_cast<HTMLSourceElement*>(node)->cancelPendingErrorEvent();
+ }
+}
+
+Document* HTMLMediaElement::mediaPlayerOwningDocument()
+{
+ Document* d = document();
+
+ if (!d)
+ d = ownerDocument();
+
+ return d;
+}
+
+void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
+{
+ beginProcessingMediaPlayerCallback();
+ setNetworkState(m_player->networkState());
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
+{
+ 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.
+ m_networkState = NETWORK_EMPTY;
+ return;
+ }
+
+ if (state == MediaPlayer::FormatError || state == MediaPlayer::NetworkError || state == MediaPlayer::DecodeError) {
+ stopPeriodicTimers();
+
+ // If we failed while trying to load a <source> element, the movie was never parsed, and there are more
+ // <source> children, schedule the next one
+ if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement) {
+
+ if (m_currentSourceNode)
+ m_currentSourceNode->scheduleErrorEvent();
+ else
+ LOG(Media, "HTMLMediaElement::setNetworkState - error event not sent, <source> was removed");
+
+ if (havePotentialSourceChild()) {
+ LOG(Media, "HTMLMediaElement::setNetworkState - scheduling next <source>");
+ scheduleNextSourceChild();
+ } else {
+ LOG(Media, "HTMLMediaElement::setNetworkState - no more <source> elements, waiting");
+ waitForSourceChange();
+ }
+
+ return;
+ }
+
+ if (state == MediaPlayer::NetworkError)
+ mediaEngineError(MediaError::create(MediaError::MEDIA_ERR_NETWORK));
+ else if (state == MediaPlayer::DecodeError)
+ mediaEngineError(MediaError::create(MediaError::MEDIA_ERR_DECODE));
+ else if (state == MediaPlayer::FormatError && m_loadState == LoadingFromSrcAttr)
+ noneSupported();
+
+ updateDisplayState();
+ return;
+ }
+
+ if (state == MediaPlayer::Idle) {
+ if (m_networkState > NETWORK_IDLE) {
+ m_progressEventTimer.stop();
+ scheduleEvent(eventNames().suspendEvent);
+ }
+ m_networkState = NETWORK_IDLE;
+ }
+
+ if (state == MediaPlayer::Loading) {
+ if (m_networkState < NETWORK_LOADING || m_networkState == NETWORK_NO_SOURCE)
+ startProgressEventTimer();
+ m_networkState = NETWORK_LOADING;
+ }
+
+ if (state == MediaPlayer::Loaded) {
+ if (m_networkState != NETWORK_IDLE) {
+ m_progressEventTimer.stop();
+
+ // Schedule one last progress event so we guarantee that at least one is fired
+ // for files that load very quickly.
+ scheduleEvent(eventNames().progressEvent);
+ }
+ m_networkState = NETWORK_IDLE;
+ m_completelyLoaded = true;
+ }
+}
+
+void HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*)
+{
+ beginProcessingMediaPlayerCallback();
+
+ setReadyState(m_player->readyState());
+
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
+{
+ 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();
+
+ ReadyState oldState = m_readyState;
+ m_readyState = static_cast<ReadyState>(state);
+
+ if (m_readyState == oldState)
+ return;
+
+ if (oldState > m_readyStateMaximum)
+ m_readyStateMaximum = oldState;
+
+ if (m_networkState == NETWORK_EMPTY)
+ return;
+
+ if (m_seeking) {
+ // 4.8.10.9, step 11
+ if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA)
+ scheduleEvent(eventNames().waitingEvent);
+
+ // 4.8.10.10 step 14 & 15.
+ if (m_readyState >= HAVE_CURRENT_DATA)
+ finishSeek();
+ } else {
+ if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA) {
+ // 4.8.10.8
+ scheduleTimeupdateEvent(false);
+ scheduleEvent(eventNames().waitingEvent);
+ }
+ }
+
+ if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) {
+ scheduleEvent(eventNames().durationchangeEvent);
+ scheduleEvent(eventNames().loadedmetadataEvent);
+ if (renderer())
+ renderer()->updateFromElement();
+ m_player->seek(0);
+ }
+
+ bool shouldUpdateDisplayState = false;
+
+ if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_haveFiredLoadedData) {
+ m_haveFiredLoadedData = true;
+ shouldUpdateDisplayState = true;
+ scheduleEvent(eventNames().loadeddataEvent);
+ setShouldDelayLoadEvent(false);
+ }
+
+ bool isPotentiallyPlaying = potentiallyPlaying();
+ if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA) {
+ scheduleEvent(eventNames().canplayEvent);
+ if (isPotentiallyPlaying)
+ scheduleEvent(eventNames().playingEvent);
+ shouldUpdateDisplayState = true;
+ }
+
+ if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA) {
+ if (oldState <= HAVE_CURRENT_DATA)
+ scheduleEvent(eventNames().canplayEvent);
+
+ scheduleEvent(eventNames().canplaythroughEvent);
+
+ if (isPotentiallyPlaying && oldState <= HAVE_CURRENT_DATA)
+ scheduleEvent(eventNames().playingEvent);
+
+ if (m_autoplaying && m_paused && autoplay()) {
+ m_paused = false;
+ scheduleEvent(eventNames().playEvent);
+ scheduleEvent(eventNames().playingEvent);
+ }
+
+ shouldUpdateDisplayState = true;
+ }
+
+ if (shouldUpdateDisplayState)
+ updateDisplayState();
+
+ updatePlayState();
+}
+
+void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
+{
+ ASSERT(m_player);
+ if (m_networkState != NETWORK_LOADING)
+ return;
+
+ unsigned progress = m_player->bytesLoaded();
+ double time = WTF::currentTime();
+ double timedelta = time - m_previousProgressTime;
+
+ if (progress == m_previousProgress) {
+ if (timedelta > 3.0 && !m_sentStalledEvent) {
+ scheduleEvent(eventNames().stalledEvent);
+ m_sentStalledEvent = true;
+ }
+ } else {
+ scheduleEvent(eventNames().progressEvent);
+ m_previousProgress = progress;
+ m_previousProgressTime = time;
+ m_sentStalledEvent = false;
+ if (renderer())
+ renderer()->updateFromElement();
+ }
+}
+
+void HTMLMediaElement::rewind(float timeDelta)
+{
+ LOG(Media, "HTMLMediaElement::rewind(%f)", timeDelta);
+
+ ExceptionCode e;
+ setCurrentTime(max(currentTime() - timeDelta, minTimeSeekable()), e);
+}
+
+void HTMLMediaElement::returnToRealtime()
+{
+ LOG(Media, "HTMLMediaElement::returnToRealtime");
+ ExceptionCode e;
+ setCurrentTime(maxTimeSeekable(), e);
+}
+
+void HTMLMediaElement::addPlayedRange(float start, float end)
+{
+ LOG(Media, "HTMLMediaElement::addPlayedRange(%f, %f)", start, end);
+ if (!m_playedTimeRanges)
+ m_playedTimeRanges = TimeRanges::create();
+ m_playedTimeRanges->add(start, end);
+}
+
+bool HTMLMediaElement::supportsSave() const
+{
+ return m_player ? m_player->supportsSave() : false;
+}
+
+void HTMLMediaElement::seek(float time, ExceptionCode& ec)
+{
+ LOG(Media, "HTMLMediaElement::seek(%f)", time);
+
+ // 4.8.9.9 Seeking
+
+ // 1 - If the media element's readyState is HAVE_NOTHING, then raise an INVALID_STATE_ERR exception.
+ if (m_readyState == HAVE_NOTHING || !m_player) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+
+ // Get the current time before setting m_seeking, m_lastSeekTime is returned once it is set.
+ refreshCachedTime();
+ float now = currentTime();
+
+ // 2 - 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.
+ // Nothing specific to be done here.
+
+ // 3 - 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;
+
+ // 5 - 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 = min(time, duration());
+
+ // 6 - If the new playback position is less than the earliest possible position, let it be that position instead.
+ float earliestTime = m_player->startTime();
+ time = max(time, earliestTime);
+
+ // Ask the media engine for the time value in the movie's time scale before comparing with current time. This
+ // is necessary because if the seek time is not equal to currentTime but the delta is less than the movie's
+ // time scale, we will ask the media engine to "seek" to the current movie time, which may be a noop and
+ // not generate a timechanged callback. This means m_seeking will never be cleared and we will never
+ // fire a 'seeked' event.
+#if !LOG_DISABLED
+ float mediaTime = m_player->mediaTimeForTimeValue(time);
+ if (time != mediaTime)
+ LOG(Media, "HTMLMediaElement::seek(%f) - media timeline equivalent is %f", time, mediaTime);
+#endif
+ time = m_player->mediaTimeForTimeValue(time);
+
+ // 7 - If the (possibly now changed) new playback position is not in one of the ranges given in the
+ // seekable attribute, then let it be the position in one of the ranges given in the seekable attribute
+ // that is the nearest to the new playback position. ... If there are no ranges given in the seekable
+ // attribute then set the seeking IDL attribute to false and abort these steps.
+ RefPtr<TimeRanges> seekableRanges = seekable();
+
+ // Short circuit seeking to the current time by just firing the events if no seek is required.
+ // Don't skip calling the media engine if we are in poster mode because a seek should always
+ // cancel poster display.
+ bool noSeekRequired = !seekableRanges->length() || (time == now && displayMode() != Poster);
+ if (noSeekRequired) {
+ if (time == now) {
+ scheduleEvent(eventNames().seekingEvent);
+ scheduleTimeupdateEvent(false);
+ scheduleEvent(eventNames().seekedEvent);
+ }
+ m_seeking = false;
+ return;
+ }
+ time = seekableRanges->nearest(time);
+
+ if (m_playing) {
+ if (m_lastSeekTime < now)
+ addPlayedRange(m_lastSeekTime, now);
+ }
+ m_lastSeekTime = time;
+ m_sentEndEvent = false;
+
+ // 8 - Set the current playback position to the given new playback position
+ m_player->seek(time);
+
+ // 9 - Queue a task to fire a simple event named seeking at the element.
+ scheduleEvent(eventNames().seekingEvent);
+
+ // 10 - Queue a task to fire a simple event named timeupdate at the element.
+ scheduleTimeupdateEvent(false);
+
+ // 11-15 are handled, if necessary, when the engine signals a readystate change.
+}
+
+void HTMLMediaElement::finishSeek()
+{
+ LOG(Media, "HTMLMediaElement::finishSeek");
+
+ // 4.8.10.9 Seeking step 14
+ m_seeking = false;
+
+ // 4.8.10.9 Seeking step 15
+ scheduleEvent(eventNames().seekedEvent);
+
+ setDisplayMode(Video);
+}
+
+HTMLMediaElement::ReadyState HTMLMediaElement::readyState() const
+{
+ return m_readyState;
+}
+
+MediaPlayer::MovieLoadType HTMLMediaElement::movieLoadType() const
+{
+ return m_player ? m_player->movieLoadType() : MediaPlayer::Unknown;
+}
+
+bool HTMLMediaElement::hasAudio() const
+{
+ return m_player ? m_player->hasAudio() : false;
+}
+
+bool HTMLMediaElement::seeking() const
+{
+ return m_seeking;
+}
+
+void HTMLMediaElement::refreshCachedTime() const
+{
+ m_cachedTime = m_player->currentTime();
+ m_cachedTimeWallClockUpdateTime = WTF::currentTime();
+}
+
+void HTMLMediaElement::invalidateCachedTime()
+{
+ 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
+ // too early.
+ static const double minimumTimePlayingBeforeCacheSnapshot = 0.5;
+
+ m_minimumWallClockTimeToCacheMediaTime = WTF::currentTime() + minimumTimePlayingBeforeCacheSnapshot;
+ m_cachedTime = invalidMediaTime;
+}
+
+// playback state
+float HTMLMediaElement::currentTime() const
+{
+#if LOG_CACHED_TIME_WARNINGS
+ static const double minCachedDeltaForWarning = 0.01;
+#endif
+
+ if (!m_player)
+ return 0;
+
+ if (m_seeking) {
+ LOG(Media, "HTMLMediaElement::currentTime - seeking, returning %f", m_lastSeekTime);
+ return m_lastSeekTime;
+ }
+
+ if (m_cachedTime != invalidMediaTime && m_paused) {
+#if LOG_CACHED_TIME_WARNINGS
+ float delta = m_cachedTime - m_player->currentTime();
+ if (delta > minCachedDeltaForWarning)
+ LOG(Media, "HTMLMediaElement::currentTime - WARNING, cached time is %f seconds off of media time when paused", delta);
+#endif
+ return m_cachedTime;
+ }
+
+ // Is it too soon use a cached time?
+ double now = WTF::currentTime();
+ double maximumDurationToCacheMediaTime = m_player->maximumDurationToCacheMediaTime();
+
+ if (maximumDurationToCacheMediaTime && m_cachedTime != invalidMediaTime && !m_paused && now > m_minimumWallClockTimeToCacheMediaTime) {
+ double wallClockDelta = now - m_cachedTimeWallClockUpdateTime;
+
+ // Not too soon, use the cached time only if it hasn't expired.
+ if (wallClockDelta < maximumDurationToCacheMediaTime) {
+ float adjustedCacheTime = static_cast<float>(m_cachedTime + (m_playbackRate * wallClockDelta));
+
+#if LOG_CACHED_TIME_WARNINGS
+ float delta = adjustedCacheTime - m_player->currentTime();
+ if (delta > minCachedDeltaForWarning)
+ LOG(Media, "HTMLMediaElement::currentTime - WARNING, cached time is %f seconds off of media time when playing", delta);
+#endif
+ return adjustedCacheTime;
+ }
+ }
+
+#if LOG_CACHED_TIME_WARNINGS
+ if (maximumDurationToCacheMediaTime && now > m_minimumWallClockTimeToCacheMediaTime && m_cachedTime != invalidMediaTime) {
+ double wallClockDelta = now - m_cachedTimeWallClockUpdateTime;
+ float delta = m_cachedTime + (m_playbackRate * wallClockDelta) - m_player->currentTime();
+ LOG(Media, "HTMLMediaElement::currentTime - cached time was %f seconds off of media time when it expired", delta);
+ }
+#endif
+
+ refreshCachedTime();
+
+ return m_cachedTime;
+}
+
+void HTMLMediaElement::setCurrentTime(float time, ExceptionCode& ec)
+{
+ seek(time, ec);
+}
+
+float HTMLMediaElement::startTime() const
+{
+ if (!m_player)
+ return 0;
+ return m_player->startTime();
+}
+
+float HTMLMediaElement::duration() const
+{
+ if (m_player && m_readyState >= HAVE_METADATA)
+ return m_player->duration();
+
+ return numeric_limits<float>::quiet_NaN();
+}
+
+bool HTMLMediaElement::paused() const
+{
+ return m_paused;
+}
+
+float HTMLMediaElement::defaultPlaybackRate() const
+{
+ return m_defaultPlaybackRate;
+}
+
+void HTMLMediaElement::setDefaultPlaybackRate(float rate)
+{
+ if (m_defaultPlaybackRate != rate) {
+ m_defaultPlaybackRate = rate;
+ scheduleEvent(eventNames().ratechangeEvent);
+ }
+}
+
+float HTMLMediaElement::playbackRate() const
+{
+ return m_player ? m_player->rate() : 0;
+}
+
+void HTMLMediaElement::setPlaybackRate(float rate)
+{
+ LOG(Media, "HTMLMediaElement::setPlaybackRate(%f)", rate);
+
+ if (m_playbackRate != rate) {
+ m_playbackRate = rate;
+ scheduleEvent(eventNames().ratechangeEvent);
+ }
+ if (m_player && potentiallyPlaying() && m_player->rate() != rate)
+ m_player->setRate(rate);
+}
+
+bool HTMLMediaElement::webkitPreservesPitch() const
+{
+ return m_webkitPreservesPitch;
+}
+
+void HTMLMediaElement::setWebkitPreservesPitch(bool preservesPitch)
+{
+ LOG(Media, "HTMLMediaElement::setWebkitPreservesPitch(%s)", boolString(preservesPitch));
+
+ m_webkitPreservesPitch = preservesPitch;
+
+ if (!m_player)
+ return;
+
+ m_player->setPreservesPitch(preservesPitch);
+}
+
+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() && m_playbackRate > 0;
+}
+
+bool HTMLMediaElement::autoplay() const
+{
+ return hasAttribute(autoplayAttr);
+}
+
+void HTMLMediaElement::setAutoplay(bool b)
+{
+ LOG(Media, "HTMLMediaElement::setAutoplay(%s)", boolString(b));
+ setBooleanAttribute(autoplayAttr, b);
+}
+
+String HTMLMediaElement::preload() const
+{
+ switch (m_preload) {
+ case MediaPlayer::None:
+ return "none";
+ break;
+ case MediaPlayer::MetaData:
+ return "metadata";
+ break;
+ case MediaPlayer::Auto:
+ return "auto";
+ break;
+ }
+
+ ASSERT_NOT_REACHED();
+ return String();
+}
+
+void HTMLMediaElement::setPreload(const String& preload)
+{
+ LOG(Media, "HTMLMediaElement::setPreload(%s)", preload.utf8().data());
+ setAttribute(preloadAttr, preload);
+}
+
+void HTMLMediaElement::play(bool isUserGesture)
+{
+ LOG(Media, "HTMLMediaElement::play(isUserGesture : %s)", boolString(isUserGesture));
+
+ if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture)
+ return;
+
+ Document* doc = document();
+ Settings* settings = doc->settings();
+ if (settings && settings->needsSiteSpecificQuirks() && m_dispatchingCanPlayEvent && !m_loadInitiatedByUserGesture) {
+ // It should be impossible to be processing the canplay event while handling a user gesture
+ // since it is dispatched asynchronously.
+ ASSERT(!isUserGesture);
+ String host = doc->baseURL().host();
+ if (host.endsWith(".npr.org", false) || equalIgnoringCase(host, "npr.org"))
+ return;
+ }
+
+ playInternal();
+}
+
+void HTMLMediaElement::playInternal()
+{
+ LOG(Media, "HTMLMediaElement::playInternal");
+
+ // 4.8.10.9. Playing the media resource
+ if (!m_player || m_networkState == NETWORK_EMPTY)
+ scheduleLoad();
+
+ if (endedPlayback()) {
+ ExceptionCode unused;
+ seek(0, unused);
+ }
+
+ setPlaybackRate(defaultPlaybackRate());
+
+ if (m_paused) {
+ m_paused = false;
+ scheduleEvent(eventNames().playEvent);
+
+ if (m_readyState <= HAVE_CURRENT_DATA)
+ scheduleEvent(eventNames().waitingEvent);
+ else if (m_readyState >= HAVE_FUTURE_DATA)
+ scheduleEvent(eventNames().playingEvent);
+ }
+ m_autoplaying = false;
+
+ updatePlayState();
+}
+
+void HTMLMediaElement::pause(bool isUserGesture)
+{
+ LOG(Media, "HTMLMediaElement::pause(isUserGesture : %s)", boolString(isUserGesture));
+
+ if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture)
+ return;
+
+ pauseInternal();
+}
+
+
+void HTMLMediaElement::pauseInternal()
+{
+ LOG(Media, "HTMLMediaElement::pauseInternal");
+
+ // 4.8.10.9. Playing the media resource
+ if (!m_player || m_networkState == NETWORK_EMPTY)
+ scheduleLoad();
+
+ m_autoplaying = false;
+
+ if (!m_paused) {
+ m_paused = true;
+ scheduleTimeupdateEvent(false);
+ scheduleEvent(eventNames().pauseEvent);
+ }
+
+ updatePlayState();
+}
+
+bool HTMLMediaElement::loop() const
+{
+ return hasAttribute(loopAttr);
+}
+
+void HTMLMediaElement::setLoop(bool b)
+{
+ LOG(Media, "HTMLMediaElement::setLoop(%s)", boolString(b));
+ setBooleanAttribute(loopAttr, b);
+}
+
+bool HTMLMediaElement::controls() const
+{
+ Frame* frame = document()->frame();
+
+ // always show controls when scripting is disabled
+ if (frame && !frame->script()->canExecuteScripts(NotAboutToExecuteScript))
+ return true;
+
+ return hasAttribute(controlsAttr);
+}
+
+void HTMLMediaElement::setControls(bool b)
+{
+ LOG(Media, "HTMLMediaElement::setControls(%s)", boolString(b));
+ setBooleanAttribute(controlsAttr, b);
+}
+
+float HTMLMediaElement::volume() const
+{
+ return m_volume;
+}
+
+void HTMLMediaElement::setVolume(float vol, ExceptionCode& ec)
+{
+ LOG(Media, "HTMLMediaElement::setVolume(%f)", vol);
+
+ if (vol < 0.0f || vol > 1.0f) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ if (m_volume != vol) {
+ m_volume = vol;
+ updateVolume();
+ scheduleEvent(eventNames().volumechangeEvent);
+ }
+}
+
+bool HTMLMediaElement::muted() const
+{
+ return m_muted;
+}
+
+void HTMLMediaElement::setMuted(bool muted)
+{
+ LOG(Media, "HTMLMediaElement::setMuted(%s)", boolString(muted));
+
+ if (m_muted != muted) {
+ m_muted = muted;
+ // Avoid recursion when the player reports volume changes.
+ if (!processingMediaPlayerCallback()) {
+ if (m_player) {
+ m_player->setMuted(m_muted);
+ if (renderer())
+ renderer()->updateFromElement();
+ } else
+ updateVolume();
+ }
+ scheduleEvent(eventNames().volumechangeEvent);
+ }
+}
+
+void HTMLMediaElement::togglePlayState()
+{
+ 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
+ if (canPlay())
+ playInternal();
+ else
+ pauseInternal();
+}
+
+void HTMLMediaElement::beginScrubbing()
+{
+ LOG(Media, "HTMLMediaElement::beginScrubbing - paused() is %s", boolString(paused()));
+
+ if (!paused()) {
+ if (ended()) {
+ // Because a media element stays in non-paused state when it reaches end, playback resumes
+ // when the slider is dragged from the end to another position unless we pause first. Do
+ // a "hard pause" so an event is generated, since we want to stay paused after scrubbing finishes.
+ pause(processingUserGesture());
+ } else {
+ // Not at the end but we still want to pause playback so the media engine doesn't try to
+ // continue playing during scrubbing. Pause without generating an event as we will
+ // unpause after scrubbing finishes.
+ setPausedInternal(true);
+ }
+ }
+}
+
+void HTMLMediaElement::endScrubbing()
+{
+ LOG(Media, "HTMLMediaElement::endScrubbing - m_pausedInternal is %s", boolString(m_pausedInternal));
+
+ if (m_pausedInternal)
+ setPausedInternal(false);
+}
+
+// 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;
+
+void HTMLMediaElement::startPlaybackProgressTimer()
+{
+ if (m_playbackProgressTimer.isActive())
+ return;
+
+ m_previousProgressTime = WTF::currentTime();
+ m_previousProgress = 0;
+ m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency);
+}
+
+void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*)
+{
+ ASSERT(m_player);
+ if (!m_playbackRate)
+ return;
+
+ scheduleTimeupdateEvent(true);
+
+ // FIXME: deal with cue ranges here
+}
+
+void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent)
+{
+ double now = WTF::currentTime();
+ double timedelta = now - m_lastTimeUpdateEventWallTime;
+
+ // throttle the periodic events
+ if (periodicEvent && timedelta < maxTimeupdateEventFrequency)
+ return;
+
+ // 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
+ float movieTime = currentTime();
+ if (movieTime != m_lastTimeUpdateEventMovieTime) {
+ scheduleEvent(eventNames().timeupdateEvent);
+ m_lastTimeUpdateEventWallTime = now;
+ m_lastTimeUpdateEventMovieTime = movieTime;
+ }
+}
+
+bool HTMLMediaElement::canPlay() const
+{
+ return paused() || ended() || m_readyState < HAVE_METADATA;
+}
+
+float HTMLMediaElement::percentLoaded() const
+{
+ if (!m_player)
+ return 0;
+ float duration = m_player->duration();
+
+ if (!duration || isinf(duration))
+ return 0;
+
+ float buffered = 0;
+ RefPtr<TimeRanges> timeRanges = m_player->buffered();
+ for (unsigned i = 0; i < timeRanges->length(); ++i) {
+ ExceptionCode ignoredException;
+ float start = timeRanges->start(i, ignoredException);
+ float end = timeRanges->end(i, ignoredException);
+ buffered += end - start;
+ }
+ return buffered / duration;
+}
+
+bool HTMLMediaElement::havePotentialSourceChild()
+{
+ // Stash the current <source> node and next nodes so we can restore them after checking
+ // to see there is another potential.
+ HTMLSourceElement* currentSourceNode = m_currentSourceNode;
+ Node* nextNode = m_nextChildNodeToConsider;
+
+ KURL nextURL = selectNextSourceChild(0, DoNothing);
+
+ m_currentSourceNode = currentSourceNode;
+ m_nextChildNodeToConsider = nextNode;
+
+ return nextURL.isValid();
+}
+
+KURL HTMLMediaElement::selectNextSourceChild(ContentType *contentType, InvalidSourceAction actionIfInvalid)
+{
+#if !LOG_DISABLED
+ // 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(contentType : \"%s\")", contentType ? contentType->raw().utf8().data() : "");
+#endif
+
+ if (m_nextChildNodeToConsider == sourceChildEndOfListValue()) {
+#if !LOG_DISABLED
+ if (shouldLog)
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild -> 0x0000, \"\"");
+#endif
+ return KURL();
+ }
+
+ KURL mediaURL;
+ Node* node;
+ HTMLSourceElement* source = 0;
+ bool lookingForStartNode = m_nextChildNodeToConsider;
+ bool canUse = false;
+
+ for (node = firstChild(); !canUse && node; node = node->nextSibling()) {
+ if (lookingForStartNode && m_nextChildNodeToConsider != node)
+ continue;
+ lookingForStartNode = false;
+
+ if (!node->hasTagName(sourceTag))
+ continue;
+
+ source = static_cast<HTMLSourceElement*>(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 - 'src' is %s", urlForLogging(mediaURL).utf8().data());
+#endif
+ if (mediaURL.isEmpty())
+ goto check_again;
+
+ if (source->hasAttribute(mediaAttr)) {
+ MediaQueryEvaluator screenEval("screen", document()->frame(), renderer() ? renderer()->style() : 0);
+ RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(source->media());
+#if !LOG_DISABLED
+ if (shouldLog)
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'media' is %s", source->media().utf8().data());
+#endif
+ if (!screenEval.eval(media.get()))
+ goto check_again;
+ }
+
+ if (source->hasAttribute(typeAttr)) {
+#if !LOG_DISABLED
+ if (shouldLog)
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'type' is %s", source->type().utf8().data());
+#endif
+ if (!MediaPlayer::supportsType(ContentType(source->type())))
+ goto check_again;
+ }
+
+ // Is it safe to load this url?
+ if (!isSafeToLoadURL(mediaURL, actionIfInvalid) || !dispatchBeforeLoadEvent(mediaURL.string()))
+ goto check_again;
+
+ // Making it this far means the <source> looks reasonable.
+ canUse = true;
+
+check_again:
+ if (!canUse && actionIfInvalid == Complain)
+ source->scheduleErrorEvent();
+ }
+
+ if (canUse) {
+ if (contentType)
+ *contentType = ContentType(source->type());
+ m_currentSourceNode = source;
+ m_nextChildNodeToConsider = source->nextSibling();
+ if (!m_nextChildNodeToConsider)
+ m_nextChildNodeToConsider = sourceChildEndOfListValue();
+ } else {
+ m_currentSourceNode = 0;
+ m_nextChildNodeToConsider = sourceChildEndOfListValue();
+ }
+
+#if !LOG_DISABLED
+ if (shouldLog)
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild -> %p, %s", m_currentSourceNode, canUse ? urlForLogging(mediaURL.string()).utf8().data() : "");
+#endif
+ return canUse ? mediaURL : KURL();
+}
+
+void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source)
+{
+ LOG(Media, "HTMLMediaElement::sourceWasAdded(%p)", source);
+
+#if !LOG_DISABLED
+ if (source->hasTagName(sourceTag)) {
+ KURL url = source->getNonEmptyURLAttribute(srcAttr);
+ LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLogging(url).utf8().data());
+ }
+#endif
+
+ // We should only consider a <source> element when there is not src attribute at all.
+ if (hasAttribute(srcAttr))
+ return;
+
+ // 4.8.8 - If a source element is inserted as a child of a media element that has no src
+ // attribute and whose networkState has the value NETWORK_EMPTY, the user agent must invoke
+ // the media element's resource selection algorithm.
+ if (networkState() == HTMLMediaElement::NETWORK_EMPTY) {
+ scheduleLoad();
+ return;
+ }
+
+ if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) {
+ LOG(Media, "HTMLMediaElement::sourceWasAdded - <source> inserted immediately after current source");
+ m_nextChildNodeToConsider = source;
+ return;
+ }
+
+ if (m_nextChildNodeToConsider != sourceChildEndOfListValue())
+ return;
+
+ // 4.8.9.5, resource selection algorithm, source elements section:
+ // 20 - Wait until the node after pointer is a node other than the end of the list. (This step might wait forever.)
+ // 21 - Asynchronously await a stable state...
+ // 22 - Set the element's delaying-the-load-event flag back to true (this delays the load event again, in case
+ // it hasn't been fired yet).
+ setShouldDelayLoadEvent(true);
+
+ // 23 - Set the networkState back to NETWORK_LOADING.
+ m_networkState = NETWORK_LOADING;
+
+ // 24 - Jump back to the find next candidate step above.
+ m_nextChildNodeToConsider = source;
+ scheduleNextSourceChild();
+}
+
+void HTMLMediaElement::sourceWillBeRemoved(HTMLSourceElement* source)
+{
+ LOG(Media, "HTMLMediaElement::sourceWillBeRemoved(%p)", source);
+
+#if !LOG_DISABLED
+ if (source->hasTagName(sourceTag)) {
+ KURL url = source->getNonEmptyURLAttribute(srcAttr);
+ LOG(Media, "HTMLMediaElement::sourceWillBeRemoved - 'src' is %s", urlForLogging(url).utf8().data());
+ }
+#endif
+
+ if (source != m_currentSourceNode && source != m_nextChildNodeToConsider)
+ return;
+
+ if (source == m_nextChildNodeToConsider) {
+ m_nextChildNodeToConsider = m_nextChildNodeToConsider->nextSibling();
+ if (!m_nextChildNodeToConsider)
+ m_nextChildNodeToConsider = sourceChildEndOfListValue();
+ LOG(Media, "HTMLMediaElement::sourceRemoved - m_nextChildNodeToConsider set to %p", m_nextChildNodeToConsider);
+ } 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 = 0;
+ LOG(Media, "HTMLMediaElement::sourceRemoved - m_currentSourceNode set to 0");
+ }
+}
+
+void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
+{
+ LOG(Media, "HTMLMediaElement::mediaPlayerTimeChanged");
+
+ beginProcessingMediaPlayerCallback();
+
+ invalidateCachedTime();
+
+ // 4.8.10.9 step 14 & 15. Needed if no ReadyState change is associated with the seek.
+ if (m_seeking && m_readyState >= HAVE_CURRENT_DATA)
+ finishSeek();
+
+ // 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.
+ scheduleTimeupdateEvent(false);
+
+ float now = currentTime();
+ float dur = duration();
+ if (!isnan(dur) && dur && now >= dur) {
+ if (loop()) {
+ ExceptionCode ignoredException;
+ m_sentEndEvent = false;
+ seek(0, ignoredException);
+ } else {
+ if (!m_sentEndEvent) {
+ m_sentEndEvent = true;
+ scheduleEvent(eventNames().endedEvent);
+ }
+ }
+ }
+ else
+ m_sentEndEvent = false;
+
+ updatePlayState();
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::mediaPlayerVolumeChanged(MediaPlayer*)
+{
+ LOG(Media, "HTMLMediaElement::mediaPlayerVolumeChanged");
+
+ beginProcessingMediaPlayerCallback();
+ if (m_player)
+ m_volume = m_player->volume();
+ updateVolume();
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::mediaPlayerMuteChanged(MediaPlayer*)
+{
+ LOG(Media, "HTMLMediaElement::mediaPlayerMuteChanged");
+
+ beginProcessingMediaPlayerCallback();
+ if (m_player)
+ setMuted(m_player->muted());
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::mediaPlayerDurationChanged(MediaPlayer*)
+{
+ LOG(Media, "HTMLMediaElement::mediaPlayerDurationChanged");
+
+ beginProcessingMediaPlayerCallback();
+ scheduleEvent(eventNames().durationchangeEvent);
+ if (renderer())
+ renderer()->updateFromElement();
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::mediaPlayerRateChanged(MediaPlayer*)
+{
+ LOG(Media, "HTMLMediaElement::mediaPlayerRateChanged");
+
+ beginProcessingMediaPlayerCallback();
+
+ invalidateCachedTime();
+
+ // 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_playbackRate = m_player->rate();
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::mediaPlayerPlaybackStateChanged(MediaPlayer*)
+{
+ LOG(Media, "HTMLMediaElement::mediaPlayerPlaybackStateChanged");
+
+ if (!m_player)
+ return;
+
+ beginProcessingMediaPlayerCallback();
+ if (m_player->paused())
+ pauseInternal();
+ else
+ playInternal();
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::mediaPlayerSawUnsupportedTracks(MediaPlayer*)
+{
+ 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 (ownerDocument()->isMediaDocument()) {
+ MediaDocument* mediaDocument = static_cast<MediaDocument*>(ownerDocument());
+ mediaDocument->mediaElementSawUnsupportedTracks();
+ }
+}
+
+// MediaPlayerPresentation methods
+void HTMLMediaElement::mediaPlayerRepaint(MediaPlayer*)
+{
+ beginProcessingMediaPlayerCallback();
+ updateDisplayState();
+ if (renderer())
+ renderer()->repaint();
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::mediaPlayerSizeChanged(MediaPlayer*)
+{
+ LOG(Media, "HTMLMediaElement::mediaPlayerSizeChanged");
+
+ beginProcessingMediaPlayerCallback();
+ if (renderer())
+ renderer()->updateFromElement();
+ endProcessingMediaPlayerCallback();
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+bool HTMLMediaElement::mediaPlayerRenderingCanBeAccelerated(MediaPlayer*)
+{
+ if (renderer() && renderer()->isVideo()) {
+ ASSERT(renderer()->view());
+ return renderer()->view()->compositor()->canAccelerateVideoRendering(toRenderVideo(renderer()));
+ }
+ return false;
+}
+
+void HTMLMediaElement::mediaPlayerRenderingModeChanged(MediaPlayer*)
+{
+ LOG(Media, "HTMLMediaElement::mediaPlayerRenderingModeChanged");
+
+ // Kick off a fake recalcStyle that will update the compositing tree.
+ setNeedsStyleRecalc(SyntheticStyleChange);
+}
+#endif
+
+void HTMLMediaElement::mediaPlayerEngineUpdated(MediaPlayer*)
+{
+ beginProcessingMediaPlayerCallback();
+ LOG(Media, "HTMLMediaElement::mediaPlayerEngineUpdated");
+ if (renderer())
+ renderer()->updateFromElement();
+ endProcessingMediaPlayerCallback();
+}
+
+PassRefPtr<TimeRanges> HTMLMediaElement::buffered() const
+{
+ if (!m_player)
+ return TimeRanges::create();
+ return m_player->buffered();
+}
+
+PassRefPtr<TimeRanges> HTMLMediaElement::played()
+{
+ if (m_playing) {
+ float time = currentTime();
+ if (time > m_lastSeekTime)
+ addPlayedRange(m_lastSeekTime, time);
+ }
+
+ if (!m_playedTimeRanges)
+ m_playedTimeRanges = TimeRanges::create();
+
+ return m_playedTimeRanges->copy();
+}
+
+PassRefPtr<TimeRanges> HTMLMediaElement::seekable() const
+{
+ // FIXME real ranges support
+ if (!maxTimeSeekable())
+ return TimeRanges::create();
+ return TimeRanges::create(minTimeSeekable(), maxTimeSeekable());
+}
+
+bool HTMLMediaElement::potentiallyPlaying() const
+{
+ // "pausedToBuffer" means the media engine's rate is 0, but only because it had to stop playing
+ // when it ran out of buffered data. A movie is this state is "potentially playing", modulo the
+ // checks in couldPlayIfEnoughData().
+ bool pausedToBuffer = m_readyStateMaximum >= HAVE_FUTURE_DATA && m_readyState < HAVE_FUTURE_DATA;
+ return (pausedToBuffer || m_readyState >= HAVE_FUTURE_DATA) && couldPlayIfEnoughData();
+}
+
+bool HTMLMediaElement::couldPlayIfEnoughData() const
+{
+ return !paused() && !endedPlayback() && !stoppedDueToErrors() && !pausedForUserInteraction();
+}
+
+bool HTMLMediaElement::endedPlayback() const
+{
+ float dur = duration();
+ if (!m_player || isnan(dur))
+ return false;
+
+ // 4.8.10.8 Playing the media resource
+
+ // A media element is said to have ended playback when the element's
+ // readyState attribute is HAVE_METADATA or greater,
+ if (m_readyState < HAVE_METADATA)
+ return false;
+
+ // and the current playback position is the end of the media resource and the direction
+ // of playback is forwards and the media element does not have a loop attribute specified,
+ float now = currentTime();
+ if (m_playbackRate > 0)
+ return dur > 0 && now >= dur && !loop();
+
+ // or the current playback position is the earliest possible position and the direction
+ // of playback is backwards
+ if (m_playbackRate < 0)
+ return now <= 0;
+
+ return false;
+}
+
+bool HTMLMediaElement::stoppedDueToErrors() const
+{
+ if (m_readyState >= HAVE_METADATA && m_error) {
+ RefPtr<TimeRanges> seekableRanges = seekable();
+ if (!seekableRanges->contain(currentTime()))
+ return true;
+ }
+
+ return false;
+}
+
+bool HTMLMediaElement::pausedForUserInteraction() const
+{
+// return !paused() && m_readyState >= HAVE_FUTURE_DATA && [UA requires a decitions from the user]
+ return false;
+}
+
+float HTMLMediaElement::minTimeSeekable() const
+{
+ return 0;
+}
+
+float HTMLMediaElement::maxTimeSeekable() const
+{
+ return m_player ? m_player->maxTimeSeekable() : 0;
+}
+
+void HTMLMediaElement::updateVolume()
+{
+ if (!m_player)
+ return;
+
+ // Avoid recursion when the player reports volume changes.
+ if (!processingMediaPlayerCallback()) {
+ Page* page = document()->page();
+ float volumeMultiplier = page ? page->mediaVolume() : 1;
+
+ m_player->setMuted(m_muted);
+ m_player->setVolume(m_volume * volumeMultiplier);
+ }
+
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+void HTMLMediaElement::updatePlayState()
+{
+ if (!m_player)
+ return;
+
+ if (m_pausedInternal) {
+ if (!m_player->paused())
+ m_player->pause();
+ refreshCachedTime();
+ m_playbackProgressTimer.stop();
+ return;
+ }
+
+ bool shouldBePlaying = potentiallyPlaying();
+ bool playerPaused = m_player->paused();
+
+ LOG(Media, "HTMLMediaElement::updatePlayState - shouldBePlaying = %s, playerPaused = %s",
+ boolString(shouldBePlaying), boolString(playerPaused));
+
+ if (shouldBePlaying) {
+ setDisplayMode(Video);
+ invalidateCachedTime();
+
+ if (playerPaused) {
+ if (!m_isFullscreen && isVideo() && document() && document()->page() && document()->page()->chrome()->requiresFullscreenForVideoPlayback())
+ enterFullscreen();
+
+ // Set rate before calling play in case the rate was set before the media engine was setup.
+ // The media engine should just stash the rate since it isn't already playing.
+ m_player->setRate(m_playbackRate);
+ m_player->play();
+ }
+
+ startPlaybackProgressTimer();
+ m_playing = true;
+
+ } else { // Should not be playing right now
+ if (!playerPaused)
+ m_player->pause();
+ refreshCachedTime();
+
+ m_playbackProgressTimer.stop();
+ m_playing = false;
+ float time = currentTime();
+ if (time > m_lastSeekTime)
+ addPlayedRange(m_lastSeekTime, time);
+
+ if (couldPlayIfEnoughData())
+ m_player->prepareToPlay();
+ }
+
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+void HTMLMediaElement::setPausedInternal(bool b)
+{
+ m_pausedInternal = b;
+ updatePlayState();
+}
+
+void HTMLMediaElement::stopPeriodicTimers()
+{
+ m_progressEventTimer.stop();
+ m_playbackProgressTimer.stop();
+}
+
+void HTMLMediaElement::userCancelledLoad()
+{
+ LOG(Media, "HTMLMediaElement::userCancelledLoad");
+
+ if (m_networkState == NETWORK_EMPTY || m_completelyLoaded)
+ return;
+
+ // If the media data fetching process is aborted by the user:
+
+ // 1 - The user agent should cancel the fetching process.
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ m_player.clear();
+#endif
+ stopPeriodicTimers();
+ m_loadState = WaitingForSource;
+
+ // 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);
+
+ // 3 - Queue a task to fire a simple event named error at the media element.
+ scheduleEvent(eventNames().abortEvent);
+
+ // 4 - If the media element's readyState attribute has a value equal to HAVE_NOTHING, set the
+ // element's networkState attribute to the NETWORK_EMPTY value and queue a task to fire a
+ // simple event named emptied at the element. Otherwise, set the element's networkState
+ // attribute to the NETWORK_IDLE value.
+ if (m_readyState == HAVE_NOTHING) {
+ m_networkState = NETWORK_EMPTY;
+ scheduleEvent(eventNames().emptiedEvent);
+ }
+ else
+ m_networkState = NETWORK_IDLE;
+
+ // 5 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
+ setShouldDelayLoadEvent(false);
+
+ // 6 - Abort the overall resource selection algorithm.
+ m_currentSourceNode = 0;
+
+ // Reset m_readyState since m_player is gone.
+ m_readyState = HAVE_NOTHING;
+}
+
+bool HTMLMediaElement::canSuspend() const
+{
+ return true;
+}
+
+void HTMLMediaElement::stop()
+{
+ LOG(Media, "HTMLMediaElement::stop");
+ if (m_isFullscreen)
+ exitFullscreen();
+
+ m_inActiveDocument = false;
+ userCancelledLoad();
+
+ // Stop the playback without generating events
+ setPausedInternal(true);
+
+ if (renderer())
+ renderer()->updateFromElement();
+
+ stopPeriodicTimers();
+ cancelPendingEventsAndCallbacks();
+}
+
+void HTMLMediaElement::suspend(ReasonForSuspension why)
+{
+ LOG(Media, "HTMLMediaElement::suspend");
+
+ switch (why)
+ {
+ case DocumentWillBecomeInactive:
+ stop();
+ break;
+ case JavaScriptDebuggerPaused:
+ case WillShowDialog:
+ // Do nothing, we don't pause media playback in these cases.
+ break;
+ }
+}
+
+void HTMLMediaElement::resume()
+{
+ LOG(Media, "HTMLMediaElement::resume");
+
+ m_inActiveDocument = true;
+ setPausedInternal(false);
+
+ 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.
+ ExceptionCode ec;
+ load(processingUserGesture(), ec);
+ }
+
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+bool HTMLMediaElement::hasPendingActivity() const
+{
+ // Return true when we have pending events so we can't fire events after the JS
+ // object gets collected.
+ bool pending = m_pendingEvents.size();
+ LOG(Media, "HTMLMediaElement::hasPendingActivity -> %s", boolString(pending));
+ return pending;
+}
+
+void HTMLMediaElement::mediaVolumeDidChange()
+{
+ LOG(Media, "HTMLMediaElement::mediaVolumeDidChange");
+ updateVolume();
+}
+
+void HTMLMediaElement::defaultEventHandler(Event* event)
+{
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ RenderObject* r = renderer();
+ if (!r || !r->isWidget())
+ return;
+
+ Widget* widget = toRenderWidget(r)->widget();
+ if (widget)
+ widget->handleEvent(event);
+#else
+ if (renderer() && renderer()->isMedia())
+ toRenderMedia(renderer())->forwardEvent(event);
+ if (event->defaultHandled())
+ return;
+ HTMLElement::defaultEventHandler(event);
+#endif
+}
+
+bool HTMLMediaElement::processingUserGesture() const
+{
+ Frame* frame = document()->frame();
+ FrameLoader* loader = frame ? frame->loader() : 0;
+
+ // return 'true' for safety if we don't know the answer
+ return loader ? loader->isProcessingUserGesture() : true;
+}
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+
+void HTMLMediaElement::ensureMediaPlayer()
+{
+ if (!m_player)
+ m_player = MediaPlayer::create(this);
+}
+
+void HTMLMediaElement::deliverNotification(MediaPlayerProxyNotificationType notification)
+{
+ if (notification == MediaPlayerNotificationPlayPauseButtonPressed) {
+ togglePlayState();
+ return;
+ }
+
+ if (m_player)
+ m_player->deliverNotification(notification);
+}
+
+void HTMLMediaElement::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
+{
+ ensureMediaPlayer();
+ m_player->setMediaPlayerProxy(proxy);
+}
+
+void HTMLMediaElement::getPluginProxyParams(KURL& url, Vector<String>& names, Vector<String>& values)
+{
+ Frame* frame = document()->frame();
+ FrameLoader* loader = frame ? frame->loader() : 0;
+
+ if (isVideo()) {
+ KURL posterURL = getNonEmptyURLAttribute(posterAttr);
+ if (!posterURL.isEmpty() && loader && loader->willLoadMediaElementURL(posterURL)) {
+ names.append("_media_element_poster_");
+ values.append(posterURL.string());
+ }
+ }
+
+ if (controls()) {
+ names.append("_media_element_controls_");
+ values.append("true");
+ }
+
+ url = src();
+ if (!isSafeToLoadURL(url, Complain))
+ url = selectNextSourceChild(0, DoNothing);
+
+ m_currentSrc = url.string();
+ if (url.isValid() && loader && loader->willLoadMediaElementURL(url)) {
+ names.append("_media_element_src_");
+ values.append(m_currentSrc);
+ }
+}
+
+void HTMLMediaElement::finishParsingChildren()
+{
+ HTMLElement::finishParsingChildren();
+ document()->updateStyleIfNeeded();
+ createMediaPlayerProxy();
+}
+
+void HTMLMediaElement::createMediaPlayerProxy()
+{
+ ensureMediaPlayer();
+
+ if (m_proxyWidget || (inDocument() && !m_needWidgetUpdate))
+ return;
+
+ Frame* frame = document()->frame();
+ FrameLoader* loader = frame ? frame->loader() : 0;
+ if (!loader)
+ return;
+
+ LOG(Media, "HTMLMediaElement::createMediaPlayerProxy");
+
+ KURL 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 = loader->subframeLoader()->loadMediaPlayerProxyPlugin(this, url, paramNames, paramValues);
+ if (m_proxyWidget)
+ m_needWidgetUpdate = false;
+}
+
+void HTMLMediaElement::updateWidget(bool)
+{
+ mediaElement->setNeedWidgetUpdate(false);
+
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+ KURL kurl;
+
+ mediaElement->getPluginProxyParams(kurl, paramNames, paramValues);
+ SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
+ loader->loadMediaPlayerProxyPlugin(mediaElement, kurl, paramNames, paramValues);
+}
+
+#endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+
+void HTMLMediaElement::enterFullscreen()
+{
+ LOG(Media, "HTMLMediaElement::enterFullscreen");
+
+ ASSERT(!m_isFullscreen);
+ m_isFullscreen = true;
+ if (document() && document()->page()) {
+ document()->page()->chrome()->client()->enterFullscreenForNode(this);
+ scheduleEvent(eventNames().webkitbeginfullscreenEvent);
+ }
+}
+
+void HTMLMediaElement::exitFullscreen()
+{
+ LOG(Media, "HTMLMediaElement::exitFullscreen");
+
+ ASSERT(m_isFullscreen);
+ m_isFullscreen = false;
+ if (document() && document()->page()) {
+ if (document()->page()->chrome()->requiresFullscreenForVideoPlayback())
+ pauseInternal();
+ document()->page()->chrome()->client()->exitFullscreenForNode(this);
+ scheduleEvent(eventNames().webkitendfullscreenEvent);
+ }
+}
+
+PlatformMedia HTMLMediaElement::platformMedia() const
+{
+ return m_player ? m_player->platformMedia() : NoPlatformMedia;
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+PlatformLayer* HTMLMediaElement::platformLayer() const
+{
+ return m_player ? m_player->platformLayer() : 0;
+}
+#endif
+
+bool HTMLMediaElement::hasClosedCaptions() const
+{
+ return m_player && m_player->hasClosedCaptions();
+}
+
+bool HTMLMediaElement::closedCaptionsVisible() const
+{
+ return m_closedCaptionsVisible;
+}
+
+void HTMLMediaElement::setClosedCaptionsVisible(bool closedCaptionVisible)
+{
+ LOG(Media, "HTMLMediaElement::setClosedCaptionsVisible(%s)", boolString(closedCaptionVisible));
+
+ if (!m_player ||!hasClosedCaptions())
+ return;
+
+ m_closedCaptionsVisible = closedCaptionVisible;
+ m_player->setClosedCaptionsVisible(closedCaptionVisible);
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+void HTMLMediaElement::setWebkitClosedCaptionsVisible(bool visible)
+{
+ setClosedCaptionsVisible(visible);
+}
+
+bool HTMLMediaElement::webkitClosedCaptionsVisible() const
+{
+ return closedCaptionsVisible();
+}
+
+
+bool HTMLMediaElement::webkitHasClosedCaptions() const
+{
+ return hasClosedCaptions();
+}
+
+void HTMLMediaElement::mediaCanStart()
+{
+ LOG(Media, "HTMLMediaElement::mediaCanStart");
+
+ ASSERT(m_isWaitingUntilMediaCanStart);
+ m_isWaitingUntilMediaCanStart = false;
+ loadInternal();
+}
+
+bool HTMLMediaElement::isURLAttribute(Attribute* attribute) const
+{
+ return attribute->name() == srcAttr;
+}
+
+void HTMLMediaElement::setShouldDelayLoadEvent(bool shouldDelay)
+{
+ if (m_shouldDelayLoadEvent == shouldDelay)
+ return;
+
+ LOG(Media, "HTMLMediaElement::setShouldDelayLoadEvent(%s)", boolString(shouldDelay));
+
+ m_shouldDelayLoadEvent = shouldDelay;
+ if (shouldDelay)
+ document()->incrementLoadEventDelayCount();
+ else
+ document()->decrementLoadEventDelayCount();
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h
new file mode 100644
index 0000000..bdc3447
--- /dev/null
+++ b/Source/WebCore/html/HTMLMediaElement.h
@@ -0,0 +1,395 @@
+/*
+ * Copyright (C) 2007, 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,
+ * 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 HTMLMediaElement_h
+#define HTMLMediaElement_h
+
+#if ENABLE(VIDEO)
+
+#include "HTMLElement.h"
+#include "ActiveDOMObject.h"
+#include "MediaCanStartListener.h"
+#include "MediaPlayer.h"
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "MediaPlayerProxy.h"
+#endif
+
+namespace WebCore {
+
+class Event;
+class HTMLSourceElement;
+class MediaError;
+class KURL;
+class TimeRanges;
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+class Widget;
+#endif
+
+// FIXME: The inheritance from MediaPlayerClient here should be private inheritance.
+// But it can't be until the Chromium WebMediaPlayerClientImpl class is fixed so it
+// no longer depends on typecasting a MediaPlayerClient to an HTMLMediaElement.
+
+class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, private MediaCanStartListener, private ActiveDOMObject {
+public:
+ MediaPlayer* player() const { return m_player.get(); }
+
+ virtual bool isVideo() const = 0;
+ virtual bool hasVideo() const { return false; }
+ virtual bool hasAudio() const;
+
+ void rewind(float timeDelta);
+ void returnToRealtime();
+
+ // Eventually overloaded in HTMLVideoElement
+ virtual bool supportsFullscreen() const { return false; };
+
+ virtual bool supportsSave() const;
+
+ PlatformMedia platformMedia() const;
+#if USE(ACCELERATED_COMPOSITING)
+ PlatformLayer* platformLayer() const;
+#endif
+
+ void scheduleLoad();
+
+ MediaPlayer::MovieLoadType movieLoadType() const;
+
+ bool inActiveDocument() const { return m_inActiveDocument; }
+
+// DOM API
+// error state
+ PassRefPtr<MediaError> error() const;
+
+// network state
+ void setSrc(const String&);
+ String currentSrc() const;
+
+ enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE };
+ NetworkState networkState() const;
+
+ String preload() const;
+ void setPreload(const String&);
+
+ PassRefPtr<TimeRanges> buffered() const;
+ void load(bool isUserGesture, ExceptionCode&);
+ String canPlayType(const String& mimeType) const;
+
+// ready state
+ enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
+ ReadyState readyState() const;
+ bool seeking() const;
+
+// playback state
+ float currentTime() const;
+ void setCurrentTime(float, ExceptionCode&);
+ float startTime() const;
+ float duration() const;
+ bool paused() const;
+ float defaultPlaybackRate() const;
+ void setDefaultPlaybackRate(float);
+ float playbackRate() const;
+ void setPlaybackRate(float);
+ bool webkitPreservesPitch() const;
+ void setWebkitPreservesPitch(bool);
+ PassRefPtr<TimeRanges> played();
+ PassRefPtr<TimeRanges> seekable() const;
+ bool ended() const;
+ bool autoplay() const;
+ void setAutoplay(bool b);
+ bool loop() const;
+ void setLoop(bool b);
+ void play(bool isUserGesture);
+ void pause(bool isUserGesture);
+
+// captions
+ bool webkitHasClosedCaptions() const;
+ bool webkitClosedCaptionsVisible() const;
+ void setWebkitClosedCaptionsVisible(bool);
+
+// controls
+ bool controls() const;
+ void setControls(bool);
+ float volume() const;
+ void setVolume(float, ExceptionCode&);
+ bool muted() const;
+ void setMuted(bool);
+ void togglePlayState();
+ void beginScrubbing();
+ void endScrubbing();
+
+ bool canPlay() const;
+
+ float percentLoaded() const;
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ void allocateMediaPlayerIfNecessary();
+ void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; }
+ void deliverNotification(MediaPlayerProxyNotificationType notification);
+ void setMediaPlayerProxy(WebMediaPlayerProxy* proxy);
+ void getPluginProxyParams(KURL& url, Vector<String>& names, Vector<String>& values);
+ virtual void finishParsingChildren();
+ void createMediaPlayerProxy();
+ void updateWidget(bool onlyCreateNonNetscapePlugins);
+#endif
+
+ bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
+
+ bool isFullscreen() const { return m_isFullscreen; }
+ void enterFullscreen();
+ void exitFullscreen();
+
+ bool hasClosedCaptions() const;
+ bool closedCaptionsVisible() const;
+ void setClosedCaptionsVisible(bool);
+
+ bool processingUserGesture() const;
+
+ void sourceWillBeRemoved(HTMLSourceElement*);
+ void sourceWasAdded(HTMLSourceElement*);
+
+protected:
+ HTMLMediaElement(const QualifiedName&, Document*);
+ virtual ~HTMLMediaElement();
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual bool isURLAttribute(Attribute*) const;
+ virtual void attach();
+
+ virtual void willMoveToNewOwnerDocument();
+ virtual void didMoveToNewOwnerDocument();
+
+ enum DisplayMode { Unknown, None, Poster, Video };
+ DisplayMode displayMode() const { return m_displayMode; }
+ virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
+
+private:
+ virtual void attributeChanged(Attribute*, bool preserveDecls);
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+ virtual void recalcStyle(StyleChange);
+
+ virtual void defaultEventHandler(Event*);
+
+ // ActiveDOMObject functions.
+ virtual bool canSuspend() const;
+ virtual void suspend(ReasonForSuspension);
+ virtual void resume();
+ virtual void stop();
+ virtual bool hasPendingActivity() const;
+
+ virtual void mediaVolumeDidChange();
+
+ virtual void updateDisplayState() { }
+
+ void setReadyState(MediaPlayer::ReadyState);
+ void setNetworkState(MediaPlayer::NetworkState);
+
+ virtual Document* mediaPlayerOwningDocument();
+ virtual void mediaPlayerNetworkStateChanged(MediaPlayer*);
+ virtual void mediaPlayerReadyStateChanged(MediaPlayer*);
+ virtual void mediaPlayerTimeChanged(MediaPlayer*);
+ virtual void mediaPlayerVolumeChanged(MediaPlayer*);
+ virtual void mediaPlayerMuteChanged(MediaPlayer*);
+ virtual void mediaPlayerDurationChanged(MediaPlayer*);
+ virtual void mediaPlayerRateChanged(MediaPlayer*);
+ virtual void mediaPlayerPlaybackStateChanged(MediaPlayer*);
+ virtual void mediaPlayerSawUnsupportedTracks(MediaPlayer*);
+ virtual void mediaPlayerRepaint(MediaPlayer*);
+ virtual void mediaPlayerSizeChanged(MediaPlayer*);
+#if USE(ACCELERATED_COMPOSITING)
+ virtual bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*);
+ virtual void mediaPlayerRenderingModeChanged(MediaPlayer*);
+#endif
+ virtual void mediaPlayerEngineUpdated(MediaPlayer*);
+
+ void loadTimerFired(Timer<HTMLMediaElement>*);
+ void asyncEventTimerFired(Timer<HTMLMediaElement>*);
+ void progressEventTimerFired(Timer<HTMLMediaElement>*);
+ void playbackProgressTimerFired(Timer<HTMLMediaElement>*);
+ void startPlaybackProgressTimer();
+ void startProgressEventTimer();
+ void stopPeriodicTimers();
+
+ void seek(float time, ExceptionCode&);
+ void finishSeek();
+ void checkIfSeekNeeded();
+ void addPlayedRange(float start, float end);
+
+ void scheduleTimeupdateEvent(bool periodicEvent);
+ void scheduleEvent(const AtomicString& eventName);
+
+ // loading
+ void selectMediaResource();
+ void loadResource(const KURL&, ContentType&);
+ void scheduleNextSourceChild();
+ void loadNextSourceChild();
+ void userCancelledLoad();
+ bool havePotentialSourceChild();
+ void noneSupported();
+ void mediaEngineError(PassRefPtr<MediaError> err);
+ void cancelPendingEventsAndCallbacks();
+ void waitForSourceChange();
+
+ enum InvalidSourceAction { DoNothing, Complain };
+ bool isSafeToLoadURL(const KURL&, InvalidSourceAction);
+ KURL selectNextSourceChild(ContentType*, InvalidSourceAction);
+
+ // These "internal" functions do not check user gesture restrictions.
+ void loadInternal();
+ void playInternal();
+ void pauseInternal();
+
+ void prepareForLoad();
+ void allowVideoRendering();
+
+ bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
+ void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
+ void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
+
+ void updateVolume();
+ void updatePlayState();
+ bool potentiallyPlaying() const;
+ bool endedPlayback() const;
+ bool stoppedDueToErrors() const;
+ bool pausedForUserInteraction() const;
+ bool couldPlayIfEnoughData() const;
+
+ float minTimeSeekable() const;
+ float maxTimeSeekable() const;
+
+ // Pauses playback without changing any states or generating events
+ void setPausedInternal(bool);
+
+ virtual void mediaCanStart();
+
+ void setShouldDelayLoadEvent(bool);
+
+ void invalidateCachedTime();
+ void refreshCachedTime() const;
+
+ // Restrictions to change default behaviors. This is effectively a compile time choice at the moment
+ // because there are no accessor functions.
+ enum BehaviorRestrictions {
+ NoRestrictions = 0,
+ RequireUserGestureForLoadRestriction = 1 << 0,
+ RequireUserGestureForRateChangeRestriction = 1 << 1,
+ };
+
+ Timer<HTMLMediaElement> m_loadTimer;
+ Timer<HTMLMediaElement> m_asyncEventTimer;
+ Timer<HTMLMediaElement> m_progressEventTimer;
+ Timer<HTMLMediaElement> m_playbackProgressTimer;
+ Vector<RefPtr<Event> > m_pendingEvents;
+ RefPtr<TimeRanges> m_playedTimeRanges;
+
+ float m_playbackRate;
+ float m_defaultPlaybackRate;
+ bool m_webkitPreservesPitch;
+ NetworkState m_networkState;
+ ReadyState m_readyState;
+ ReadyState m_readyStateMaximum;
+ String m_currentSrc;
+
+ RefPtr<MediaError> m_error;
+
+ float m_volume;
+ float m_lastSeekTime;
+
+ unsigned m_previousProgress;
+ double m_previousProgressTime;
+
+ // the last time a timeupdate event was sent (wall clock)
+ double m_lastTimeUpdateEventWallTime;
+
+ // the last time a timeupdate event was sent in movie time
+ float m_lastTimeUpdateEventMovieTime;
+
+ // loading state
+ enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
+ LoadState m_loadState;
+ HTMLSourceElement* m_currentSourceNode;
+ Node* m_nextChildNodeToConsider;
+ Node* sourceChildEndOfListValue() { return static_cast<Node*>(this); }
+
+ OwnPtr<MediaPlayer> m_player;
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ RefPtr<Widget> m_proxyWidget;
+#endif
+
+ BehaviorRestrictions m_restrictions;
+
+ MediaPlayer::Preload m_preload;
+
+ DisplayMode m_displayMode;
+
+ // Counter incremented while processing a callback from the media player, so we can avoid
+ // calling the media engine recursively.
+ int m_processingMediaPlayerCallback;
+
+ mutable float m_cachedTime;
+ mutable double m_cachedTimeWallClockUpdateTime;
+ mutable double m_minimumWallClockTimeToCacheMediaTime;
+
+ bool m_playing : 1;
+ bool m_isWaitingUntilMediaCanStart : 1;
+ bool m_shouldDelayLoadEvent : 1;
+ bool m_haveFiredLoadedData : 1;
+ bool m_inActiveDocument : 1;
+ bool m_autoplaying : 1;
+ bool m_muted : 1;
+ bool m_paused : 1;
+ bool m_seeking : 1;
+
+ // data has not been loaded since sending a "stalled" event
+ bool m_sentStalledEvent : 1;
+
+ // time has not changed since sending an "ended" event
+ bool m_sentEndEvent : 1;
+
+ bool m_pausedInternal : 1;
+
+ // Not all media engines provide enough information about a file to be able to
+ // support progress events so setting m_sendProgressEvents disables them
+ bool m_sendProgressEvents : 1;
+
+ bool m_isFullscreen : 1;
+ bool m_closedCaptionsVisible : 1;
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ bool m_needWidgetUpdate : 1;
+#endif
+
+ bool m_dispatchingCanPlayEvent : 1;
+ bool m_loadInitiatedByUserGesture : 1;
+ bool m_completelyLoaded : 1;
+};
+
+} //namespace
+
+#endif
+#endif
diff --git a/Source/WebCore/html/HTMLMediaElement.idl b/Source/WebCore/html/HTMLMediaElement.idl
new file mode 100644
index 0000000..d6ba79d
--- /dev/null
+++ b/Source/WebCore/html/HTMLMediaElement.idl
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007, 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,
+ * 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.
+ */
+
+module html {
+interface [Conditional=VIDEO] HTMLMediaElement : HTMLElement {
+
+ // error state
+ readonly attribute MediaError error;
+
+ // network state
+ attribute [Reflect, URL] DOMString src;
+ readonly attribute DOMString currentSrc;
+
+ const unsigned short NETWORK_EMPTY = 0;
+ const unsigned short NETWORK_IDLE = 1;
+ const unsigned short NETWORK_LOADING = 2;
+ const unsigned short NETWORK_NO_SOURCE = 3;
+ readonly attribute unsigned short networkState;
+ attribute DOMString preload;
+
+ readonly attribute TimeRanges buffered;
+ [NeedsUserGestureCheck] void load()
+ raises (DOMException);
+ DOMString canPlayType(in DOMString type);
+
+ // ready state
+ const unsigned short HAVE_NOTHING = 0;
+ const unsigned short HAVE_METADATA = 1;
+ const unsigned short HAVE_CURRENT_DATA = 2;
+ const unsigned short HAVE_FUTURE_DATA = 3;
+ const unsigned short HAVE_ENOUGH_DATA = 4;
+ readonly attribute unsigned short readyState;
+ readonly attribute boolean seeking;
+
+ // playback state
+ attribute float currentTime
+ setter raises (DOMException);
+ readonly attribute float startTime;
+ readonly attribute float duration;
+ readonly attribute boolean paused;
+ attribute float defaultPlaybackRate;
+ attribute float playbackRate;
+ readonly attribute TimeRanges played;
+ readonly attribute TimeRanges seekable;
+ readonly attribute boolean ended;
+ attribute [Reflect] boolean autoplay;
+ attribute [Reflect] boolean loop;
+ [NeedsUserGestureCheck] void play();
+ [NeedsUserGestureCheck] void pause();
+
+ // controls
+ attribute boolean controls;
+ attribute float volume
+ setter raises (DOMException);
+ attribute boolean muted;
+
+ // WebKit extensions
+ attribute boolean webkitPreservesPitch;
+
+ readonly attribute boolean webkitHasClosedCaptions;
+ attribute boolean webkitClosedCaptionsVisible;
+};
+}
diff --git a/Source/WebCore/html/HTMLMenuElement.cpp b/Source/WebCore/html/HTMLMenuElement.cpp
new file mode 100644
index 0000000..9f706ef
--- /dev/null
+++ b/Source/WebCore/html/HTMLMenuElement.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLMenuElement.h"
+
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLMenuElement::HTMLMenuElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(menuTag));
+}
+
+PassRefPtr<HTMLMenuElement> HTMLMenuElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLMenuElement(tagName, document));
+}
+
+}
diff --git a/Source/WebCore/html/HTMLMenuElement.h b/Source/WebCore/html/HTMLMenuElement.h
new file mode 100644
index 0000000..6b588ec
--- /dev/null
+++ b/Source/WebCore/html/HTMLMenuElement.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLMenuElement_h
+#define HTMLMenuElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLMenuElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLMenuElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLMenuElement(const QualifiedName&, Document*);
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLMenuElement.idl b/Source/WebCore/html/HTMLMenuElement.idl
new file mode 100644
index 0000000..ff14754
--- /dev/null
+++ b/Source/WebCore/html/HTMLMenuElement.idl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLMenuElement : HTMLElement {
+ attribute [Reflect] boolean compact;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLMetaElement.cpp b/Source/WebCore/html/HTMLMetaElement.cpp
new file mode 100644
index 0000000..4863f3b
--- /dev/null
+++ b/Source/WebCore/html/HTMLMetaElement.cpp
@@ -0,0 +1,137 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLMetaElement.h"
+
+#include "Attribute.h"
+#include "Document.h"
+#include "HTMLNames.h"
+
+#ifdef ANDROID_META_SUPPORT
+#include "PlatformBridge.h"
+#include "Settings.h"
+#endif
+
+#if ENABLE(ANDROID_INSTALLABLE_WEB_APPS)
+#include "ChromeClient.h"
+#endif
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLMetaElement::HTMLMetaElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(metaTag));
+}
+
+PassRefPtr<HTMLMetaElement> HTMLMetaElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLMetaElement(tagName, document));
+}
+
+void HTMLMetaElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == http_equivAttr) {
+ m_equiv = attr->value();
+ process();
+ } else if (attr->name() == contentAttr) {
+ m_content = attr->value();
+ process();
+ } else if (attr->name() == nameAttr) {
+ // Do nothing.
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+void HTMLMetaElement::insertedIntoDocument()
+{
+ HTMLElement::insertedIntoDocument();
+ process();
+}
+
+void HTMLMetaElement::process()
+{
+ if (!inDocument() || m_content.isNull())
+ return;
+#ifdef ANDROID_META_SUPPORT
+ // TODO: Evaluate whether to take upstreamed meta support
+ bool updateViewport = false;
+ if (equalIgnoringCase(name(), "viewport")) {
+ document()->processMetadataSettings(m_content);
+ updateViewport = true;
+ } else if (equalIgnoringCase(name(), "format-detection"))
+ document()->processMetadataSettings(m_content);
+ else if ((equalIgnoringCase(name(), "HandheldFriendly")
+ && equalIgnoringCase(m_content, "true") ||
+ equalIgnoringCase(name(), "MobileOptimized"))
+ && document()->settings()
+ && document()->settings()->viewportWidth() == -1) {
+ // fit mobile sites directly in the screen
+ document()->settings()->setMetadataSettings("width", "device-width");
+ updateViewport = true;
+ }
+ // update the meta data if it is the top document
+ if (updateViewport && !document()->ownerElement()) {
+ FrameView* view = document()->view();
+ if (view)
+ PlatformBridge::updateViewport(view);
+ }
+#else
+ if (equalIgnoringCase(name(), "viewport"))
+ document()->processViewport(m_content);
+#endif
+
+#if ENABLE(ANDROID_INSTALLABLE_WEB_APPS)
+ // If this web site is informing us it is possible for it to be installed, inform the chrome
+ // client so it can offer this to the user.
+ if (equalIgnoringCase(name(), "fullscreen-web-app-capable")
+ && equalIgnoringCase(m_content, "yes")) {
+ if (Page* page = document()->page())
+ page->chrome()->client()->webAppCanBeInstalled();
+ }
+#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)
+ if (!m_equiv.isNull())
+ document()->processHttpEquiv(m_equiv, m_content);
+}
+
+String HTMLMetaElement::content() const
+{
+ return getAttribute(contentAttr);
+}
+
+String HTMLMetaElement::httpEquiv() const
+{
+ return getAttribute(http_equivAttr);
+}
+
+String HTMLMetaElement::name() const
+{
+ return getAttribute(nameAttr);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLMetaElement.h b/Source/WebCore/html/HTMLMetaElement.h
new file mode 100644
index 0000000..9b0178e
--- /dev/null
+++ b/Source/WebCore/html/HTMLMetaElement.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLMetaElement_h
+#define HTMLMetaElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLMetaElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLMetaElement> create(const QualifiedName&, Document*);
+
+ String content() const;
+ String httpEquiv() const;
+ String name() const;
+
+private:
+ HTMLMetaElement(const QualifiedName&, Document*);
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoDocument();
+
+ void process();
+
+ String m_equiv;
+ String m_content;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLMetaElement.idl b/Source/WebCore/html/HTMLMetaElement.idl
new file mode 100644
index 0000000..f4ffb2d
--- /dev/null
+++ b/Source/WebCore/html/HTMLMetaElement.idl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLMetaElement : HTMLElement {
+ attribute [Reflect] DOMString content;
+ attribute [Reflect=http_equiv] DOMString httpEquiv;
+ attribute [Reflect] DOMString name;
+ attribute [Reflect] DOMString scheme;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLMeterElement.cpp b/Source/WebCore/html/HTMLMeterElement.cpp
new file mode 100644
index 0000000..2ebf57e
--- /dev/null
+++ b/Source/WebCore/html/HTMLMeterElement.cpp
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#if ENABLE(METER_TAG)
+#include "HTMLMeterElement.h"
+
+#include "Attribute.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
+#include "FormDataList.h"
+#include "HTMLFormElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "RenderMeter.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLMeterElement::HTMLMeterElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLFormControlElement(tagName, document, form)
+{
+ ASSERT(hasTagName(meterTag));
+}
+
+PassRefPtr<HTMLMeterElement> HTMLMeterElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLMeterElement(tagName, document, form));
+}
+
+RenderObject* HTMLMeterElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderMeter(this);
+}
+
+const AtomicString& HTMLMeterElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, meter, ("meter"));
+ return meter;
+}
+
+void HTMLMeterElement::parseMappedAttribute(Attribute* attribute)
+{
+ if (attribute->name() == valueAttr || attribute->name() == minAttr || attribute->name() == maxAttr || attribute->name() == lowAttr || attribute->name() == highAttr || attribute->name() == optimumAttr) {
+ if (renderer())
+ renderer()->updateFromElement();
+ } else
+ HTMLFormControlElement::parseMappedAttribute(attribute);
+}
+
+void HTMLMeterElement::attach()
+{
+ HTMLFormControlElement::attach();
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+double HTMLMeterElement::min() const
+{
+ double min = 0;
+ parseToDoubleForNumberType(getAttribute(minAttr), &min);
+ return min;
+}
+
+void HTMLMeterElement::setMin(double min, ExceptionCode& ec)
+{
+ if (!isfinite(min)) {
+ ec = NOT_SUPPORTED_ERR;
+ return;
+ }
+ setAttribute(minAttr, String::number(min));
+}
+
+double HTMLMeterElement::max() const
+{
+ double max = std::max(1.0, min());
+ parseToDoubleForNumberType(getAttribute(maxAttr), &max);
+ return std::max(max, min());
+}
+
+void HTMLMeterElement::setMax(double max, ExceptionCode& ec)
+{
+ if (!isfinite(max)) {
+ ec = NOT_SUPPORTED_ERR;
+ return;
+ }
+ setAttribute(maxAttr, String::number(max));
+}
+
+double HTMLMeterElement::value() const
+{
+ double value = 0;
+ parseToDoubleForNumberType(getAttribute(valueAttr), &value);
+ return std::min(std::max(value, min()), max());
+}
+
+void HTMLMeterElement::setValue(double value, ExceptionCode& ec)
+{
+ if (!isfinite(value)) {
+ ec = NOT_SUPPORTED_ERR;
+ return;
+ }
+ setAttribute(valueAttr, String::number(value));
+}
+
+double HTMLMeterElement::low() const
+{
+ double low = min();
+ parseToDoubleForNumberType(getAttribute(lowAttr), &low);
+ return std::min(std::max(low, min()), max());
+}
+
+void HTMLMeterElement::setLow(double low, ExceptionCode& ec)
+{
+ if (!isfinite(low)) {
+ ec = NOT_SUPPORTED_ERR;
+ return;
+ }
+ setAttribute(lowAttr, String::number(low));
+}
+
+double HTMLMeterElement::high() const
+{
+ double high = max();
+ parseToDoubleForNumberType(getAttribute(highAttr), &high);
+ return std::min(std::max(high, low()), max());
+}
+
+void HTMLMeterElement::setHigh(double high, ExceptionCode& ec)
+{
+ if (!isfinite(high)) {
+ ec = NOT_SUPPORTED_ERR;
+ return;
+ }
+ setAttribute(highAttr, String::number(high));
+}
+
+double HTMLMeterElement::optimum() const
+{
+ double optimum = (max() + min()) / 2;
+ parseToDoubleForNumberType(getAttribute(optimumAttr), &optimum);
+ return std::min(std::max(optimum, min()), max());
+}
+
+void HTMLMeterElement::setOptimum(double optimum, ExceptionCode& ec)
+{
+ if (!isfinite(optimum)) {
+ ec = NOT_SUPPORTED_ERR;
+ return;
+ }
+ setAttribute(optimumAttr, String::number(optimum));
+}
+
+HTMLMeterElement::GaugeRegion HTMLMeterElement::gaugeRegion() const
+{
+ double lowValue = low();
+ double highValue = high();
+ double theValue = value();
+ double optimumValue = optimum();
+
+ if (optimumValue < lowValue) {
+ // The optimum range stays under low
+ if (theValue <= lowValue)
+ return GaugeRegionOptimum;
+ if (theValue <= highValue)
+ return GaugeRegionSuboptimal;
+ return GaugeRegionEvenLessGood;
+ }
+
+ if (highValue < optimumValue) {
+ // The optimum range stays over high
+ if (highValue <= theValue)
+ return GaugeRegionOptimum;
+ if (lowValue <= theValue)
+ return GaugeRegionSuboptimal;
+ return GaugeRegionEvenLessGood;
+ }
+
+ // The optimum range stays between high and low.
+ // According to the standard, <meter> never show GaugeRegionEvenLessGood in this case
+ // because the value is never less or greater than min or max.
+ if (lowValue <= theValue && theValue <= highValue)
+ return GaugeRegionOptimum;
+ return GaugeRegionSuboptimal;
+}
+
+} // namespace
+#endif
diff --git a/Source/WebCore/html/HTMLMeterElement.h b/Source/WebCore/html/HTMLMeterElement.h
new file mode 100644
index 0000000..d5038e0
--- /dev/null
+++ b/Source/WebCore/html/HTMLMeterElement.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLMeterElement_h
+#define HTMLMeterElement_h
+
+#if ENABLE(METER_TAG)
+#include "HTMLFormControlElement.h"
+
+namespace WebCore {
+
+class HTMLMeterElement : public HTMLFormControlElement {
+public:
+ static PassRefPtr<HTMLMeterElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+
+ enum GaugeRegion {
+ GaugeRegionOptimum,
+ GaugeRegionSuboptimal,
+ GaugeRegionEvenLessGood
+ };
+
+ double min() const;
+ void setMin(double, ExceptionCode&);
+
+ double max() const;
+ void setMax(double, ExceptionCode&);
+
+ double value() const;
+ void setValue(double, ExceptionCode&);
+
+ double low() const;
+ void setLow(double, ExceptionCode&);
+
+ double high() const;
+ void setHigh(double, ExceptionCode&);
+
+ double optimum() const;
+ void setOptimum(double, ExceptionCode&);
+
+ GaugeRegion gaugeRegion() const;
+private:
+ HTMLMeterElement(const QualifiedName&, Document*, HTMLFormElement*);
+
+ virtual bool recalcWillValidate() const { return false; }
+
+ virtual const AtomicString& formControlType() const;
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void attach();
+};
+
+} // namespace
+
+#endif
+#endif
diff --git a/Source/WebCore/html/HTMLMeterElement.idl b/Source/WebCore/html/HTMLMeterElement.idl
new file mode 100644
index 0000000..3398688
--- /dev/null
+++ b/Source/WebCore/html/HTMLMeterElement.idl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=METER_TAG
+ ] HTMLMeterElement : HTMLElement {
+ attribute double value
+ setter raises(DOMException);
+ attribute double min
+ setter raises(DOMException);
+ attribute double max
+ setter raises(DOMException);
+ attribute double low
+ setter raises(DOMException);
+ attribute double high
+ setter raises(DOMException);
+ attribute double optimum
+ setter raises(DOMException);
+ readonly attribute HTMLFormElement form;
+ readonly attribute NodeList labels;
+ };
+}
+
diff --git a/Source/WebCore/html/HTMLModElement.cpp b/Source/WebCore/html/HTMLModElement.cpp
new file mode 100644
index 0000000..2d409b0
--- /dev/null
+++ b/Source/WebCore/html/HTMLModElement.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLModElement.h"
+
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLModElement::HTMLModElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+}
+
+PassRefPtr<HTMLModElement> HTMLModElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLModElement(tagName, document));
+}
+
+bool HTMLModElement::isURLAttribute(Attribute* attribute) const
+{
+ return attribute->name() == citeAttr;
+}
+
+}
diff --git a/Source/WebCore/html/HTMLModElement.h b/Source/WebCore/html/HTMLModElement.h
new file mode 100644
index 0000000..cdb6dce
--- /dev/null
+++ b/Source/WebCore/html/HTMLModElement.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2000 Simon Hausmann <hausmann@kde.org>
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLModElement_h
+#define HTMLModElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLModElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLModElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLModElement(const QualifiedName&, Document*);
+
+ virtual bool isURLAttribute(Attribute*) const;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLModElement.idl b/Source/WebCore/html/HTMLModElement.idl
new file mode 100644
index 0000000..ad8281c
--- /dev/null
+++ b/Source/WebCore/html/HTMLModElement.idl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLModElement : HTMLElement {
+ attribute [Reflect, URL] DOMString cite;
+ attribute [Reflect] DOMString dateTime;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLNameCollection.cpp b/Source/WebCore/html/HTMLNameCollection.cpp
new file mode 100644
index 0000000..4075e4c
--- /dev/null
+++ b/Source/WebCore/html/HTMLNameCollection.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLNameCollection.h"
+
+#include "Element.h"
+#include "HTMLDocument.h"
+#include "HTMLNames.h"
+#include "HTMLObjectElement.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLNameCollection::HTMLNameCollection(PassRefPtr<Document> document, CollectionType type, const String& name)
+ : HTMLCollection(document.get(), type, document->nameCollectionInfo(type, name))
+ , m_name(name)
+{
+}
+
+Element* HTMLNameCollection::itemAfter(Element* previous) const
+{
+ ASSERT(previous != base());
+
+ Node* current;
+ if (!previous)
+ current = base()->firstChild();
+ else
+ current = previous->traverseNextNode(base());
+
+ for (; current; current = current->traverseNextNode(base())) {
+ if (!current->isElementNode())
+ continue;
+ Element* e = static_cast<Element*>(current);
+ switch (type()) {
+ case WindowNamedItems:
+ // find only images, forms, applets, embeds and objects by name,
+ // but anything by id
+ if (e->hasTagName(imgTag) ||
+ e->hasTagName(formTag) ||
+ e->hasTagName(appletTag) ||
+ e->hasTagName(embedTag) ||
+ e->hasTagName(objectTag))
+ if (e->getAttribute(nameAttr) == m_name)
+ return e;
+ if (e->getIdAttribute() == m_name)
+ return e;
+ break;
+ case DocumentNamedItems:
+ // 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 (e->hasTagName(formTag) || e->hasTagName(embedTag) || e->hasTagName(iframeTag)) {
+ if (e->getAttribute(nameAttr) == m_name)
+ return e;
+ } else if (e->hasTagName(appletTag)) {
+ if (e->getAttribute(nameAttr) == m_name || e->getIdAttribute() == m_name)
+ return e;
+ } else if (e->hasTagName(objectTag)) {
+ if ((e->getAttribute(nameAttr) == m_name || e->getIdAttribute() == m_name)
+ && static_cast<HTMLObjectElement*>(e)->isDocNamedItem())
+ return e;
+ } else if (e->hasTagName(imgTag)) {
+ if (e->getAttribute(nameAttr) == m_name || (e->getIdAttribute() == m_name && e->hasAttribute(nameAttr)))
+ return e;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
+
+ return 0;
+}
+
+}
diff --git a/Source/WebCore/html/HTMLNameCollection.h b/Source/WebCore/html/HTMLNameCollection.h
new file mode 100644
index 0000000..3e990d7
--- /dev/null
+++ b/Source/WebCore/html/HTMLNameCollection.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLNameCollection_h
+#define HTMLNameCollection_h
+
+#include "HTMLCollection.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class Document;
+
+class HTMLNameCollection : public HTMLCollection {
+public:
+ static PassRefPtr<HTMLNameCollection> create(PassRefPtr<Document> document, CollectionType type, const String& name)
+ {
+ return adoptRef(new HTMLNameCollection(document, type, name));
+ }
+
+private:
+ HTMLNameCollection(PassRefPtr<Document>, CollectionType, const String& name);
+
+ virtual Element* itemAfter(Element*) const;
+
+ String m_name;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/HTMLNoScriptElement.cpp b/Source/WebCore/html/HTMLNoScriptElement.cpp
new file mode 100644
index 0000000..5bba16f
--- /dev/null
+++ b/Source/WebCore/html/HTMLNoScriptElement.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(XHTMLMP)
+#include "HTMLNoScriptElement.h"
+
+#include "CSSStyleSelector.h"
+#include "HTMLNames.h"
+#include "RenderObject.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLNoScriptElement::HTMLNoScriptElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(noscriptTag));
+}
+
+PassRefPtr<HTMLNoScriptElement> HTMLNoScriptElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLNoScriptElement(tagName, document));
+}
+
+void HTMLNoScriptElement::attach()
+{
+ HTMLElement::attach();
+
+ // If no need to process <noscript>, we hide it by setting display:none temporarily
+ if (!document()->shouldProcessNoscriptElement()) {
+ if (renderer() && renderer()->style())
+ renderer()->style()->setDisplay(NONE);
+ setNeedsStyleRecalc();
+ }
+}
+
+void HTMLNoScriptElement::recalcStyle(StyleChange change)
+{
+ if (!document()->shouldProcessNoscriptElement() || !renderer() || !renderer()->style())
+ return;
+
+ // If <noscript> needs processing, we make it visiable here, including its visible children
+ RefPtr<RenderStyle> style = renderer()->style();
+ if (style->display() == NONE) {
+ style->setDisplay(INLINE);
+
+ // Create renderers for its children
+ if (hasChildNodes()) {
+ for (Node* n = firstChild(); n; n = n->traverseNextNode(this))
+ if (!n->renderer())
+ n->createRendererIfNeeded();
+ }
+ }
+}
+
+bool HTMLNoScriptElement::childShouldCreateRenderer(Node*) const
+{
+ return document()->shouldProcessNoscriptElement();
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/html/HTMLNoScriptElement.h b/Source/WebCore/html/HTMLNoScriptElement.h
new file mode 100644
index 0000000..9a3b92d
--- /dev/null
+++ b/Source/WebCore/html/HTMLNoScriptElement.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLNoScriptElement_h
+#define HTMLNoScriptElement_h
+
+#if ENABLE(XHTMLMP)
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLNoScriptElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLNoScriptElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLNoScriptElement(const QualifiedName&, Document*);
+
+ virtual void attach();
+ virtual void recalcStyle(StyleChange);
+ virtual bool childShouldCreateRenderer(Node*) const;
+ virtual bool rendererIsNeeded(RenderStyle*) { return true; }
+};
+
+} //namespace
+
+#endif
+#endif
diff --git a/Source/WebCore/html/HTMLOListElement.cpp b/Source/WebCore/html/HTMLOListElement.cpp
new file mode 100644
index 0000000..4c1d5a7
--- /dev/null
+++ b/Source/WebCore/html/HTMLOListElement.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLOListElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "HTMLNames.h"
+#include "RenderListItem.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLOListElement::HTMLOListElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , m_start(1)
+{
+ ASSERT(hasTagName(olTag));
+}
+
+PassRefPtr<HTMLOListElement> HTMLOListElement::create(Document* document)
+{
+ return adoptRef(new HTMLOListElement(olTag, document));
+}
+
+PassRefPtr<HTMLOListElement> HTMLOListElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLOListElement(tagName, document));
+}
+
+bool HTMLOListElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == typeAttr) {
+ result = eListItem; // Share with <li>
+ return false;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLOListElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == typeAttr) {
+ if (attr->value() == "a")
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueLowerAlpha);
+ else if (attr->value() == "A")
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueUpperAlpha);
+ else if (attr->value() == "i")
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueLowerRoman);
+ else if (attr->value() == "I")
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueUpperRoman);
+ else if (attr->value() == "1")
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueDecimal);
+ } else if (attr->name() == startAttr) {
+ bool canParse;
+ int start = attr->value().toInt(&canParse);
+ if (!canParse)
+ start = 1;
+ if (start == m_start)
+ return;
+ m_start = start;
+ for (RenderObject* child = renderer(); child; child = child->nextInPreOrder(renderer())) {
+ if (child->isListItem())
+ toRenderListItem(child)->updateValue();
+ }
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+void HTMLOListElement::setStart(int start)
+{
+ setAttribute(startAttr, String::number(start));
+}
+
+}
diff --git a/Source/WebCore/html/HTMLOListElement.h b/Source/WebCore/html/HTMLOListElement.h
new file mode 100644
index 0000000..179fec0
--- /dev/null
+++ b/Source/WebCore/html/HTMLOListElement.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLOListElement_h
+#define HTMLOListElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLOListElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLOListElement> create(Document*);
+ static PassRefPtr<HTMLOListElement> create(const QualifiedName&, Document*);
+
+ int start() const { return m_start; }
+ void setStart(int);
+
+private:
+ HTMLOListElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ int m_start;
+};
+
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLOListElement.idl b/Source/WebCore/html/HTMLOListElement.idl
new file mode 100644
index 0000000..63e06b2
--- /dev/null
+++ b/Source/WebCore/html/HTMLOListElement.idl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLOListElement : HTMLElement {
+ attribute [Reflect] boolean compact;
+ attribute long start;
+ attribute [Reflect] DOMString type;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLObjectElement.cpp b/Source/WebCore/html/HTMLObjectElement.cpp
new file mode 100644
index 0000000..2c6e6de
--- /dev/null
+++ b/Source/WebCore/html/HTMLObjectElement.cpp
@@ -0,0 +1,505 @@
+/*
+ * 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, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLObjectElement.h"
+
+#include "Attribute.h"
+#include "CSSValueKeywords.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
+#include "Frame.h"
+#include "HTMLDocument.h"
+#include "HTMLFormElement.h"
+#include "HTMLImageLoader.h"
+#include "HTMLNames.h"
+#include "HTMLParamElement.h"
+#include "HTMLParserIdioms.h"
+#include "MIMETypeRegistry.h"
+#include "RenderEmbeddedObject.h"
+#include "RenderImage.h"
+#include "RenderWidget.h"
+#include "ScriptController.h"
+#include "ScriptEventListener.h"
+#include "Text.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLObjectElement::HTMLObjectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
+ : HTMLPlugInImageElement(tagName, document, createdByParser)
+ , FormAssociatedElement(form)
+ , m_docNamedItem(true)
+ , m_useFallbackContent(false)
+{
+ ASSERT(hasTagName(objectTag));
+ if (!this->form())
+ setForm(findFormAncestor());
+ if (this->form())
+ this->form()->registerFormElement(this);
+}
+
+inline HTMLObjectElement::~HTMLObjectElement()
+{
+ if (form())
+ form()->removeFormElement(this);
+}
+
+PassRefPtr<HTMLObjectElement> HTMLObjectElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
+{
+ return adoptRef(new HTMLObjectElement(tagName, document, form, createdByParser));
+}
+
+RenderWidget* HTMLObjectElement::renderWidgetForJSBindings() const
+{
+ document()->updateLayoutIgnorePendingStylesheets();
+ return renderPart(); // This will return 0 if the renderer is not a RenderPart.
+}
+
+void HTMLObjectElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == typeAttr) {
+ m_serviceType = attr->value().lower();
+ size_t pos = m_serviceType.find(";");
+ if (pos != notFound)
+ m_serviceType = m_serviceType.left(pos);
+ if (renderer())
+ setNeedsWidgetUpdate(true);
+ if (!isImageType() && m_imageLoader)
+ m_imageLoader.clear();
+ } else if (attr->name() == dataAttr) {
+ m_url = stripLeadingAndTrailingHTMLSpaces(attr->value());
+ if (renderer()) {
+ setNeedsWidgetUpdate(true);
+ if (isImageType()) {
+ if (!m_imageLoader)
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader->updateFromElementIgnoringPreviousError();
+ }
+ }
+ } else if (attr->name() == classidAttr) {
+ m_classId = attr->value();
+ if (renderer())
+ setNeedsWidgetUpdate(true);
+ } else if (attr->name() == onloadAttr)
+ setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
+ else if (attr->name() == onbeforeloadAttr)
+ setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, attr));
+ else if (attr->name() == nameAttr) {
+ const AtomicString& newName = attr->value();
+ if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->addNamedItem(newName);
+ }
+ m_name = newName;
+ } else if (attr->name() == borderAttr) {
+ addCSSLength(attr, CSSPropertyBorderWidth, attr->value().toInt() ? attr->value() : "0");
+ addCSSProperty(attr, CSSPropertyBorderTopStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderRightStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderBottomStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderLeftStyle, CSSValueSolid);
+ } else if (isIdAttributeName(attr->name())) {
+ const AtomicString& newId = attr->value();
+ if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeExtraNamedItem(m_id);
+ document->addExtraNamedItem(newId);
+ }
+ m_id = newId;
+ // also call superclass
+ HTMLPlugInImageElement::parseMappedAttribute(attr);
+ } else
+ HTMLPlugInImageElement::parseMappedAttribute(attr);
+}
+
+static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramValues)
+{
+ // Some plugins don't understand the "data" attribute of the OBJECT tag (i.e. Real and WMP
+ // require "src" attribute).
+ int srcIndex = -1, dataIndex = -1;
+ for (unsigned int i = 0; i < paramNames->size(); ++i) {
+ if (equalIgnoringCase((*paramNames)[i], "src"))
+ srcIndex = i;
+ else if (equalIgnoringCase((*paramNames)[i], "data"))
+ dataIndex = i;
+ }
+
+ if (srcIndex == -1 && dataIndex != -1) {
+ paramNames->append("src");
+ paramValues->append((*paramValues)[dataIndex]);
+ }
+}
+
+// FIXME: This function should not deal with url or serviceType!
+void HTMLObjectElement::parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues, String& url, String& serviceType)
+{
+ HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
+ String urlParameter;
+
+ // Scan the PARAM children and store their name/value pairs.
+ // Get the URL and type from the params if we don't already have them.
+ for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ if (!child->hasTagName(paramTag))
+ continue;
+
+ HTMLParamElement* p = static_cast<HTMLParamElement*>(child);
+ String name = p->name();
+ if (name.isEmpty())
+ continue;
+
+ uniqueParamNames.add(name.impl());
+ paramNames.append(p->name());
+ paramValues.append(p->value());
+
+ // FIXME: url adjustment does not belong in this function.
+ if (url.isEmpty() && urlParameter.isEmpty() && (equalIgnoringCase(name, "src") || equalIgnoringCase(name, "movie") || equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url")))
+ urlParameter = stripLeadingAndTrailingHTMLSpaces(p->value());
+ // FIXME: serviceType calculation does not belong in this function.
+ if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
+ serviceType = p->value();
+ size_t pos = serviceType.find(";");
+ if (pos != notFound)
+ serviceType = serviceType.left(pos);
+ }
+ }
+
+ // When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE attribute in the tag
+ // points to the Java plugin itself (an ActiveX component) while the actual applet CODEBASE is
+ // in a PARAM tag. See <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means
+ // we have to explicitly suppress the tag's CODEBASE attribute if there is none in a PARAM,
+ // else our Java plugin will misinterpret it. [4004531]
+ String codebase;
+ if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) {
+ codebase = "codebase";
+ uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already
+ }
+
+ // Turn the attributes of the <object> element into arrays, but don't override <param> values.
+ NamedNodeMap* attributes = this->attributes(true);
+ if (attributes) {
+ for (unsigned i = 0; i < attributes->length(); ++i) {
+ Attribute* it = attributes->attributeItem(i);
+ const AtomicString& name = it->name().localName();
+ if (!uniqueParamNames.contains(name.impl())) {
+ paramNames.append(name.string());
+ paramValues.append(it->value().string());
+ }
+ }
+ }
+
+ mapDataParamToSrc(&paramNames, &paramValues);
+
+ // HTML5 says that an object resource's URL is specified by the object's data
+ // attribute, not by a param element. However, for compatibility, allow the
+ // resource's URL to be given by a param named "src", "movie", "code" or "url"
+ // if we know that resource points to a plug-in.
+ if (url.isEmpty() && !urlParameter.isEmpty()) {
+ SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
+ if (loader->resourceWillUsePlugin(urlParameter, serviceType))
+ url = urlParameter;
+ }
+}
+
+
+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 (child->isTextNode()) {
+ if (!static_cast<Text*>(child)->containsOnlyWhitespace())
+ return true;
+ } else if (!child->hasTagName(paramTag))
+ return true;
+ }
+ return false;
+}
+
+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.
+ // WebKit supports no classids, with the exception of Qt plug-ins, which use
+ // classid to specify which QObject to load.
+#if PLATFORM(QT)
+ return classId().isEmpty() || equalIgnoringCase(serviceType(), "application/x-qt-plugin");
+#else
+ return classId().isEmpty();
+#endif
+}
+
+// FIXME: This should be unified with HTMLEmbedElement::updateWidget and
+// moved down into HTMLPluginImageElement.cpp
+void HTMLObjectElement::updateWidget(bool onlyCreateNonNetscapePlugins)
+{
+ ASSERT(!renderEmbeddedObject()->pluginCrashedOrWasMissing());
+ // FIXME: We should ASSERT(needsWidgetUpdate()), but currently
+ // FrameView::updateWidget() calls updateWidget(false) without checking if
+ // the widget actually needs updating!
+ setNeedsWidgetUpdate(false);
+ // FIXME: This should ASSERT isFinishedParsingChildren() instead.
+ if (!isFinishedParsingChildren())
+ return;
+
+ String url = this->url();
+ String serviceType = this->serviceType();
+
+ // FIXME: These should be joined into a PluginParameters class.
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+ parametersForPlugin(paramNames, paramValues, url, serviceType);
+
+ // Note: url is modified above by parametersForPlugin.
+ if (!allowedToLoadFrameURL(url))
+ return;
+
+ bool fallbackContent = hasFallbackContent();
+ renderEmbeddedObject()->setHasFallbackContent(fallbackContent);
+
+ if (onlyCreateNonNetscapePlugins && wouldLoadAsNetscapePlugin(url, serviceType))
+ return;
+
+ ASSERT(!m_inBeforeLoadEventHandler);
+ m_inBeforeLoadEventHandler = true;
+ bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(url);
+ m_inBeforeLoadEventHandler = false;
+
+ // beforeload events can modify the DOM, potentially causing
+ // RenderWidget::destroy() to be called. Ensure we haven't been
+ // destroyed before continuing.
+ // FIXME: Should this render fallback content?
+ if (!renderer())
+ return;
+
+ SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
+ bool success = beforeLoadAllowedLoad && hasValidClassId() && loader->requestObject(this, url, getAttribute(nameAttr), serviceType, paramNames, paramValues);
+
+ if (!success && fallbackContent)
+ renderFallbackContent();
+}
+
+bool HTMLObjectElement::rendererIsNeeded(RenderStyle* style)
+{
+ // FIXME: This check should not be needed, detached documents never render!
+ Frame* frame = document()->frame();
+ if (!frame)
+ return false;
+
+ return HTMLPlugInImageElement::rendererIsNeeded(style);
+}
+
+void HTMLObjectElement::insertedIntoDocument()
+{
+ if (isDocNamedItem() && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->addNamedItem(m_name);
+ document->addExtraNamedItem(m_id);
+ }
+
+ HTMLPlugInImageElement::insertedIntoDocument();
+}
+
+void HTMLObjectElement::removedFromDocument()
+{
+ if (isDocNamedItem() && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->removeExtraNamedItem(m_id);
+ }
+
+ HTMLPlugInImageElement::removedFromDocument();
+}
+
+void HTMLObjectElement::attributeChanged(Attribute* attr, bool preserveDecls)
+{
+ if (attr->name() == formAttr)
+ formAttributeChanged();
+ else
+ HTMLPlugInImageElement::attributeChanged(attr, preserveDecls);
+}
+
+void HTMLObjectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ updateDocNamedItem();
+ if (inDocument() && !useFallbackContent()) {
+ setNeedsWidgetUpdate(true);
+ setNeedsStyleRecalc();
+ }
+ HTMLPlugInImageElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+}
+
+bool HTMLObjectElement::isURLAttribute(Attribute *attr) const
+{
+ return (attr->name() == dataAttr || (attr->name() == usemapAttr && attr->value().string()[0] != '#'));
+}
+
+const QualifiedName& HTMLObjectElement::imageSourceAttributeName() const
+{
+ return dataAttr;
+}
+
+void HTMLObjectElement::renderFallbackContent()
+{
+ if (useFallbackContent())
+ return;
+
+ if (!inDocument())
+ return;
+
+ // Before we give up and use fallback content, check to see if this is a MIME type issue.
+ 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 ditch the image loader.
+ m_imageLoader.clear();
+ detach();
+ attach();
+ return;
+ }
+ }
+
+ m_useFallbackContent = true;
+
+ // FIXME: Style gets recalculated which is suboptimal.
+ detach();
+ attach();
+}
+
+// FIXME: This should be removed, all callers are almost certainly wrong.
+static bool isRecognizedTagName(const QualifiedName& tagName)
+{
+ DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
+ if (tagList.isEmpty()) {
+ size_t tagCount = 0;
+ QualifiedName** tags = HTMLNames::getHTMLTags(&tagCount);
+ for (size_t i = 0; i < tagCount; i++) {
+ if (*tags[i] == bgsoundTag
+ || *tags[i] == commandTag
+ || *tags[i] == detailsTag
+ || *tags[i] == figcaptionTag
+ || *tags[i] == figureTag
+ || *tags[i] == summaryTag
+ || *tags[i] == trackTag) {
+ // Even though we have atoms for these tags, we don't want to
+ // treat them as "recognized tags" for the purpose of parsing
+ // because that changes how we parse documents.
+ continue;
+ }
+ tagList.add(tags[i]->localName().impl());
+ }
+ }
+ return tagList.contains(tagName.localName().impl());
+}
+
+void HTMLObjectElement::updateDocNamedItem()
+{
+ // The rule is "<object> elements with no children other than
+ // <param> elements, unknown elements and whitespace can be
+ // found by name in a document, and other <object> elements cannot."
+ bool wasNamedItem = m_docNamedItem;
+ bool isNamedItem = true;
+ Node* child = firstChild();
+ while (child && isNamedItem) {
+ if (child->isElementNode()) {
+ Element* element = static_cast<Element*>(child);
+ // FIXME: Use of isRecognizedTagName is almost certainly wrong here.
+ if (isRecognizedTagName(element->tagQName()) && !element->hasTagName(paramTag))
+ isNamedItem = false;
+ } else if (child->isTextNode()) {
+ if (!static_cast<Text*>(child)->containsOnlyWhitespace())
+ isNamedItem = false;
+ } else
+ isNamedItem = false;
+ child = child->nextSibling();
+ }
+ if (isNamedItem != wasNamedItem && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ if (isNamedItem) {
+ document->addNamedItem(m_name);
+ document->addExtraNamedItem(m_id);
+ } else {
+ document->removeNamedItem(m_name);
+ document->removeExtraNamedItem(m_id);
+ }
+ }
+ m_docNamedItem = isNamedItem;
+}
+
+bool HTMLObjectElement::containsJavaApplet() const
+{
+ if (MIMETypeRegistry::isJavaAppletMIMEType(getAttribute(typeAttr)))
+ return true;
+
+ for (Element* child = firstElementChild(); child; child = child->nextElementSibling()) {
+ if (child->hasTagName(paramTag)
+ && equalIgnoringCase(child->getAttribute(nameAttr), "type")
+ && MIMETypeRegistry::isJavaAppletMIMEType(child->getAttribute(valueAttr).string()))
+ return true;
+ if (child->hasTagName(objectTag)
+ && static_cast<HTMLObjectElement*>(child)->containsJavaApplet())
+ return true;
+ if (child->hasTagName(appletTag))
+ return true;
+ }
+
+ return false;
+}
+
+void HTMLObjectElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+{
+ HTMLPlugInImageElement::addSubresourceAttributeURLs(urls);
+
+ 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 = getAttribute(usemapAttr);
+ if (useMap.startsWith("#"))
+ addSubresourceURL(urls, document()->completeURL(useMap));
+}
+
+void HTMLObjectElement::insertedIntoTree(bool deep)
+{
+ FormAssociatedElement::insertedIntoTree();
+ HTMLPlugInImageElement::insertedIntoTree(deep);
+}
+
+void HTMLObjectElement::removedFromTree(bool deep)
+{
+ FormAssociatedElement::removedFromTree();
+ HTMLPlugInImageElement::removedFromTree(deep);
+}
+
+bool HTMLObjectElement::appendFormData(FormDataList&, bool)
+{
+ // FIXME: Implements this function.
+ return false;
+}
+
+const AtomicString& HTMLObjectElement::formControlName() const
+{
+ return m_name.isNull() ? emptyAtom : m_name;
+}
+
+}
diff --git a/Source/WebCore/html/HTMLObjectElement.h b/Source/WebCore/html/HTMLObjectElement.h
new file mode 100644
index 0000000..d5797ff
--- /dev/null
+++ b/Source/WebCore/html/HTMLObjectElement.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2004, 2006, 2007, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLObjectElement_h
+#define HTMLObjectElement_h
+
+#include "FormAssociatedElement.h"
+#include "HTMLPlugInImageElement.h"
+
+namespace WebCore {
+
+class HTMLFormElement;
+
+class HTMLObjectElement : public HTMLPlugInImageElement, public FormAssociatedElement {
+public:
+ 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;
+
+ virtual bool useFallbackContent() const { return m_useFallbackContent; }
+ void renderFallbackContent();
+
+ // Implementations of FormAssociatedElement
+ HTMLFormElement* form() const { return FormAssociatedElement::form(); }
+
+ virtual bool isFormControlElement() const { return false; }
+
+ virtual bool isEnumeratable() const { return true; }
+ virtual bool appendFormData(FormDataList&, bool);
+
+ // Implementations of constraint validation API.
+ // Note that the object elements are always barred from constraint validation.
+ String validationMessage() { return String(); }
+ bool checkValidity() { return true; }
+ void setCustomValidity(const String&) { }
+
+ virtual void attributeChanged(Attribute*, bool preserveDecls = false);
+
+ using TreeShared<ContainerNode>::ref;
+ using TreeShared<ContainerNode>::deref;
+
+private:
+ HTMLObjectElement(const QualifiedName&, Document*, HTMLFormElement*, bool createdByParser);
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoTree(bool deep);
+ virtual void removedFromTree(bool deep);
+
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+
+ virtual bool isURLAttribute(Attribute*) const;
+ virtual const QualifiedName& imageSourceAttributeName() const;
+
+ virtual RenderWidget* renderWidgetForJSBindings() const;
+
+ virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+
+ virtual void updateWidget(bool onlyCreateNonNetscapePlugins);
+ void updateDocNamedItem();
+
+ bool hasFallbackContent() const;
+
+ // FIXME: This function should not deal with url or serviceType
+ // so that we can better share code between <object> and <embed>.
+ void parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues, String& url, String& serviceType);
+
+ bool hasValidClassId();
+
+ virtual void refFormAssociatedElement() { ref(); }
+ virtual void derefFormAssociatedElement() { deref(); }
+
+ virtual const AtomicString& formControlName() const;
+
+ AtomicString m_id;
+ String m_classId;
+ bool m_docNamedItem : 1;
+ bool m_useFallbackContent : 1;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/HTMLObjectElement.idl b/Source/WebCore/html/HTMLObjectElement.idl
new file mode 100644
index 0000000..c1fa8c0
--- /dev/null
+++ b/Source/WebCore/html/HTMLObjectElement.idl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ DelegatingPutFunction,
+ DelegatingGetOwnPropertySlot,
+ CustomCall
+ ] HTMLObjectElement : HTMLElement {
+ readonly attribute HTMLFormElement form;
+ attribute [Reflect] DOMString code;
+ attribute [Reflect] DOMString align;
+ attribute [Reflect] DOMString archive;
+ attribute [Reflect] DOMString border;
+ attribute [Reflect] DOMString codeBase;
+ attribute [Reflect] DOMString codeType;
+ attribute [Reflect, URL] DOMString data;
+ attribute [Reflect] boolean declare;
+ attribute [Reflect] DOMString height;
+ attribute [Reflect] long hspace;
+ attribute [Reflect] DOMString name;
+ attribute [Reflect] DOMString standby;
+ attribute [Reflect] DOMString type;
+ attribute [Reflect] DOMString useMap;
+ attribute [Reflect] long vspace;
+ attribute [Reflect] DOMString width;
+ readonly attribute boolean willValidate;
+ readonly attribute ValidityState validity;
+ readonly attribute DOMString validationMessage;
+ boolean checkValidity();
+ void setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error);
+
+ // Introduced in DOM Level 2:
+ readonly attribute [CheckFrameSecurity] Document contentDocument;
+
+#if defined(ENABLE_SVG) && ENABLE_SVG
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS
+ [SVGCheckSecurityDocument] SVGDocument getSVGDocument() raises(DOMException);
+#endif
+#endif
+
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+ // Objective-C extension:
+ readonly attribute URL absoluteImageURL;
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLOptGroupElement.cpp b/Source/WebCore/html/HTMLOptGroupElement.cpp
new file mode 100644
index 0000000..987eb51
--- /dev/null
+++ b/Source/WebCore/html/HTMLOptGroupElement.cpp
@@ -0,0 +1,144 @@
+/*
+ * 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 Apple Inc. All rights reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLOptGroupElement.h"
+
+#include "CSSStyleSelector.h"
+#include "Document.h"
+#include "HTMLNames.h"
+#include "HTMLSelectElement.h"
+#include "RenderMenuList.h"
+#include "NodeRenderStyle.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLOptGroupElement::HTMLOptGroupElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLFormControlElement(tagName, document, form)
+{
+ ASSERT(hasTagName(optgroupTag));
+}
+
+PassRefPtr<HTMLOptGroupElement> HTMLOptGroupElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLOptGroupElement(tagName, document, form));
+}
+
+bool HTMLOptGroupElement::supportsFocus() const
+{
+ return HTMLElement::supportsFocus();
+}
+
+bool HTMLOptGroupElement::isFocusable() const
+{
+ // Optgroup elements do not have a renderer so we check the renderStyle instead.
+ return supportsFocus() && renderStyle() && renderStyle()->display() != NONE;
+}
+
+const AtomicString& HTMLOptGroupElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, optgroup, ("optgroup"));
+ return optgroup;
+}
+
+void HTMLOptGroupElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ recalcSelectOptions();
+ HTMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+}
+
+void HTMLOptGroupElement::parseMappedAttribute(Attribute* attr)
+{
+ HTMLFormControlElement::parseMappedAttribute(attr);
+ recalcSelectOptions();
+}
+
+void HTMLOptGroupElement::recalcSelectOptions()
+{
+ ContainerNode* select = parentNode();
+ while (select && !select->hasTagName(selectTag))
+ select = select->parentNode();
+ if (select)
+ static_cast<HTMLSelectElement*>(select)->setRecalcListItems();
+}
+
+void HTMLOptGroupElement::attach()
+{
+ if (parentNode()->renderStyle())
+ setRenderStyle(styleForRenderer());
+ HTMLFormControlElement::attach();
+}
+
+void HTMLOptGroupElement::detach()
+{
+ m_style.clear();
+ HTMLFormControlElement::detach();
+}
+
+void HTMLOptGroupElement::setRenderStyle(PassRefPtr<RenderStyle> newStyle)
+{
+ m_style = newStyle;
+}
+
+RenderStyle* HTMLOptGroupElement::nonRendererRenderStyle() const
+{
+ return m_style.get();
+}
+
+String HTMLOptGroupElement::groupLabelText() const
+{
+ 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();
+ // We want to collapse our whitespace too. This will match other browsers.
+ itemText = itemText.simplifyWhiteSpace();
+
+ return itemText;
+}
+
+HTMLSelectElement* HTMLOptGroupElement::ownerSelectElement() const
+{
+ ContainerNode* select = parentNode();
+ while (select && !select->hasTagName(selectTag))
+ select = select->parentNode();
+
+ if (!select)
+ return 0;
+
+ return static_cast<HTMLSelectElement*>(select);
+}
+
+void HTMLOptGroupElement::accessKeyAction(bool)
+{
+ HTMLSelectElement* select = ownerSelectElement();
+ // send to the parent to bring focus to the list box
+ if (select && !select->focused())
+ select->accessKeyAction(false);
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLOptGroupElement.h b/Source/WebCore/html/HTMLOptGroupElement.h
new file mode 100644
index 0000000..a58e957
--- /dev/null
+++ b/Source/WebCore/html/HTMLOptGroupElement.h
@@ -0,0 +1,67 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLOptGroupElement_h
+#define HTMLOptGroupElement_h
+
+#include "HTMLFormControlElement.h"
+#include "OptionGroupElement.h"
+
+namespace WebCore {
+
+class HTMLSelectElement;
+
+class HTMLOptGroupElement : public HTMLFormControlElement, public OptionGroupElement {
+public:
+ static PassRefPtr<HTMLOptGroupElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+
+ HTMLSelectElement* ownerSelectElement() const;
+
+ virtual String groupLabelText() const;
+
+private:
+ HTMLOptGroupElement(const QualifiedName&, Document*, HTMLFormElement*);
+
+ virtual const AtomicString& formControlType() const;
+ virtual bool supportsFocus() const;
+ virtual bool isFocusable() const;
+ virtual void parseMappedAttribute(Attribute*);
+ virtual bool rendererIsNeeded(RenderStyle*) { return false; }
+ virtual void attach();
+ virtual void detach();
+ virtual void setRenderStyle(PassRefPtr<RenderStyle>);
+
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+
+ virtual void accessKeyAction(bool sendToAnyElement);
+
+ virtual RenderStyle* nonRendererRenderStyle() const;
+
+ void recalcSelectOptions();
+
+ RefPtr<RenderStyle> m_style;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLOptGroupElement.idl b/Source/WebCore/html/HTMLOptGroupElement.idl
new file mode 100644
index 0000000..75cead0
--- /dev/null
+++ b/Source/WebCore/html/HTMLOptGroupElement.idl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLOptGroupElement : HTMLElement {
+ attribute [Reflect] boolean disabled;
+ attribute [Reflect] DOMString label;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLOptionElement.cpp b/Source/WebCore/html/HTMLOptionElement.cpp
new file mode 100644
index 0000000..e8f624c
--- /dev/null
+++ b/Source/WebCore/html/HTMLOptionElement.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLOptionElement.h"
+
+#include "Attribute.h"
+#include "CSSStyleSelector.h"
+#include "Document.h"
+#include "ExceptionCode.h"
+#include "HTMLNames.h"
+#include "HTMLSelectElement.h"
+#include "NodeRenderStyle.h"
+#include "RenderMenuList.h"
+#include "Text.h"
+#include <wtf/StdLibExtras.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLOptionElement::HTMLOptionElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLFormControlElement(tagName, document, form)
+{
+ ASSERT(hasTagName(optionTag));
+}
+
+PassRefPtr<HTMLOptionElement> HTMLOptionElement::create(Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLOptionElement(optionTag, document, form));
+}
+
+PassRefPtr<HTMLOptionElement> HTMLOptionElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLOptionElement(tagName, document, form));
+}
+
+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));
+
+ RefPtr<Text> text = Text::create(document, data.isNull() ? "" : data);
+
+ ec = 0;
+ element->appendChild(text.release(), ec);
+ if (ec)
+ return 0;
+
+ if (!value.isNull())
+ element->setValue(value);
+ element->setDefaultSelected(defaultSelected);
+ element->setSelected(selected);
+
+ return element.release();
+}
+
+void HTMLOptionElement::attach()
+{
+ if (parentNode()->renderStyle())
+ setRenderStyle(styleForRenderer());
+ HTMLFormControlElement::attach();
+}
+
+void HTMLOptionElement::detach()
+{
+ m_style.clear();
+ HTMLFormControlElement::detach();
+}
+
+bool HTMLOptionElement::supportsFocus() const
+{
+ return HTMLElement::supportsFocus();
+}
+
+bool HTMLOptionElement::isFocusable() const
+{
+ // Option elements do not have a renderer so we check the renderStyle instead.
+ return supportsFocus() && renderStyle() && renderStyle()->display() != NONE;
+}
+
+const AtomicString& HTMLOptionElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, option, ("option"));
+ return option;
+}
+
+String HTMLOptionElement::text() const
+{
+ return OptionElement::collectOptionLabelOrText(m_data, this);
+}
+
+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 (child && child->isTextNode() && !child->nextSibling()) {
+ static_cast<Text *>(child)->setData(text, ec);
+ return;
+ }
+
+ removeChildren();
+ appendChild(Text::create(document(), text), ec);
+}
+
+void HTMLOptionElement::accessKeyAction(bool)
+{
+ HTMLSelectElement* select = ownerSelectElement();
+ if (select)
+ select->accessKeySetSelectedIndex(index());
+}
+
+int HTMLOptionElement::index() const
+{
+ return OptionElement::optionIndex(ownerSelectElement(), this);
+}
+
+void HTMLOptionElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == selectedAttr)
+ m_data.setSelected(!attr->isNull());
+ else if (attr->name() == valueAttr)
+ m_data.setValue(attr->value());
+ else if (attr->name() == labelAttr)
+ m_data.setLabel(attr->value());
+ else
+ HTMLFormControlElement::parseMappedAttribute(attr);
+}
+
+String HTMLOptionElement::value() const
+{
+ return OptionElement::collectOptionValue(m_data, this);
+}
+
+void HTMLOptionElement::setValue(const String& value)
+{
+ setAttribute(valueAttr, value);
+}
+
+bool HTMLOptionElement::selected() const
+{
+ if (HTMLSelectElement* select = ownerSelectElement())
+ select->recalcListItemsIfNeeded();
+ return m_data.selected();
+}
+
+void HTMLOptionElement::setSelected(bool selected)
+{
+ if (m_data.selected() == selected)
+ return;
+
+ OptionElement::setSelectedState(m_data, this, selected);
+
+ if (HTMLSelectElement* select = ownerSelectElement())
+ select->setSelectedIndex(selected ? index() : -1, false);
+}
+
+void HTMLOptionElement::setSelectedState(bool selected)
+{
+ OptionElement::setSelectedState(m_data, this, selected);
+}
+
+void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ HTMLSelectElement* select = ownerSelectElement();
+ if (select)
+ select->childrenChanged(changedByParser);
+ HTMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+}
+
+HTMLSelectElement* HTMLOptionElement::ownerSelectElement() const
+{
+ ContainerNode* select = parentNode();
+ while (select && !(select->hasTagName(selectTag) || select->hasTagName(keygenTag)))
+ select = select->parentNode();
+
+ if (!select)
+ return 0;
+
+ return static_cast<HTMLSelectElement*>(select);
+}
+
+bool HTMLOptionElement::defaultSelected() const
+{
+ return fastHasAttribute(selectedAttr);
+}
+
+void HTMLOptionElement::setDefaultSelected(bool b)
+{
+ setAttribute(selectedAttr, b ? "" : 0);
+}
+
+String HTMLOptionElement::label() const
+{
+ return m_data.label();
+}
+
+void HTMLOptionElement::setRenderStyle(PassRefPtr<RenderStyle> newStyle)
+{
+ m_style = newStyle;
+}
+
+RenderStyle* HTMLOptionElement::nonRendererRenderStyle() const
+{
+ return m_style.get();
+}
+
+String HTMLOptionElement::textIndentedToRespectGroupLabel() const
+{
+ return OptionElement::collectOptionTextRespectingGroupLabel(m_data, this);
+}
+
+bool HTMLOptionElement::disabled() const
+{
+ return ownElementDisabled() || (parentNode() && static_cast<HTMLFormControlElement*>(parentNode())->disabled());
+}
+
+void HTMLOptionElement::insertedIntoTree(bool deep)
+{
+ if (HTMLSelectElement* select = ownerSelectElement()) {
+ select->setRecalcListItems();
+ // Avoid our selected() getter since it will recalculate list items incorrectly for us.
+ if (m_data.selected())
+ select->setSelectedIndex(index(), false);
+ select->scrollToSelection();
+ }
+
+ HTMLFormControlElement::insertedIntoTree(deep);
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLOptionElement.h b/Source/WebCore/html/HTMLOptionElement.h
new file mode 100644
index 0000000..c1791d7
--- /dev/null
+++ b/Source/WebCore/html/HTMLOptionElement.h
@@ -0,0 +1,97 @@
+/*
+ * 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 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+#ifndef HTMLOptionElement_h
+#define HTMLOptionElement_h
+
+#include "HTMLFormControlElement.h"
+#include "OptionElement.h"
+
+namespace WebCore {
+
+class HTMLSelectElement;
+
+class HTMLOptionElement : public HTMLFormControlElement, public OptionElement {
+ friend class HTMLSelectElement;
+ friend class RenderMenuList;
+
+public:
+ static PassRefPtr<HTMLOptionElement> create(Document*, HTMLFormElement*);
+ static PassRefPtr<HTMLOptionElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+ static PassRefPtr<HTMLOptionElement> createForJSConstructor(Document*, const String& data, const String& value,
+ bool defaultSelected, bool selected, ExceptionCode&);
+
+ virtual String text() const;
+ void setText(const String&, ExceptionCode&);
+
+ int index() const;
+
+ virtual String value() const;
+ void setValue(const String&);
+
+ virtual bool selected() const;
+ void setSelected(bool);
+
+ HTMLSelectElement* ownerSelectElement() const;
+
+ bool defaultSelected() const;
+ void setDefaultSelected(bool);
+
+ String label() const;
+
+ bool ownElementDisabled() const { return HTMLFormControlElement::disabled(); }
+
+ virtual bool disabled() const;
+
+private:
+ HTMLOptionElement(const QualifiedName&, Document*, HTMLFormElement* = 0);
+
+ virtual bool supportsFocus() const;
+ virtual bool isFocusable() const;
+ virtual bool rendererIsNeeded(RenderStyle*) { return false; }
+ virtual void attach();
+ virtual void detach();
+ virtual void setRenderStyle(PassRefPtr<RenderStyle>);
+
+ virtual const AtomicString& formControlType() const;
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void setSelectedState(bool);
+
+ virtual String textIndentedToRespectGroupLabel() const;
+
+ virtual void insertedIntoTree(bool);
+ virtual void accessKeyAction(bool);
+
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+
+ virtual RenderStyle* nonRendererRenderStyle() const;
+
+ OptionElementData m_data;
+ RefPtr<RenderStyle> m_style;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLOptionElement.idl b/Source/WebCore/html/HTMLOptionElement.idl
new file mode 100644
index 0000000..eb299ef
--- /dev/null
+++ b/Source/WebCore/html/HTMLOptionElement.idl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2006, 2007, 2010 Apple, Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ GenerateNativeConverter
+ ] HTMLOptionElement : HTMLElement {
+ readonly attribute HTMLFormElement form;
+ attribute [Reflect=selected] boolean defaultSelected;
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ attribute [ConvertNullToNullString] DOMString text setter raises(DOMException);
+#else
+ readonly attribute DOMString text;
+#endif
+ readonly attribute long index;
+ attribute [Reflect] boolean disabled;
+ attribute [Reflect] DOMString label;
+ attribute boolean selected;
+ attribute [ConvertNullToNullString] DOMString value;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLOptionsCollection.cpp b/Source/WebCore/html/HTMLOptionsCollection.cpp
new file mode 100644
index 0000000..db9a457
--- /dev/null
+++ b/Source/WebCore/html/HTMLOptionsCollection.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLOptionsCollection.h"
+
+#include "ExceptionCode.h"
+#include "HTMLOptionElement.h"
+#include "HTMLSelectElement.h"
+
+namespace WebCore {
+
+HTMLOptionsCollection::HTMLOptionsCollection(PassRefPtr<HTMLSelectElement> select)
+ : HTMLCollection(select.get(), SelectOptions, select->collectionInfo())
+{
+}
+
+PassRefPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(PassRefPtr<HTMLSelectElement> select)
+{
+ return adoptRef(new HTMLOptionsCollection(select));
+}
+
+void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, ExceptionCode &ec)
+{
+ add(element, length(), ec);
+}
+
+void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, int index, ExceptionCode &ec)
+{
+ HTMLOptionElement* newOption = element.get();
+
+ if (!newOption) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+
+ if (index < -1) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ ec = 0;
+ HTMLSelectElement* select = static_cast<HTMLSelectElement*>(base());
+
+ if (index == -1 || unsigned(index) >= length())
+ select->add(newOption, 0, ec);
+ else
+ select->add(newOption, static_cast<HTMLOptionElement*>(item(index)), ec);
+
+ ASSERT(ec == 0);
+}
+
+void HTMLOptionsCollection::remove(int index)
+{
+ static_cast<HTMLSelectElement*>(base())->remove(index);
+}
+
+int HTMLOptionsCollection::selectedIndex() const
+{
+ return static_cast<HTMLSelectElement*>(base())->selectedIndex();
+}
+
+void HTMLOptionsCollection::setSelectedIndex(int index)
+{
+ static_cast<HTMLSelectElement*>(base())->setSelectedIndex(index);
+}
+
+void HTMLOptionsCollection::setLength(unsigned length, ExceptionCode& ec)
+{
+ static_cast<HTMLSelectElement*>(base())->setLength(length, ec);
+}
+
+} //namespace
diff --git a/Source/WebCore/html/HTMLOptionsCollection.h b/Source/WebCore/html/HTMLOptionsCollection.h
new file mode 100644
index 0000000..a82749b
--- /dev/null
+++ b/Source/WebCore/html/HTMLOptionsCollection.h
@@ -0,0 +1,55 @@
+/*
+ * 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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLOptionsCollection_h
+#define HTMLOptionsCollection_h
+
+#include "HTMLCollection.h"
+
+namespace WebCore {
+
+class HTMLOptionElement;
+class HTMLSelectElement;
+
+typedef int ExceptionCode;
+
+class HTMLOptionsCollection : public HTMLCollection {
+public:
+ static PassRefPtr<HTMLOptionsCollection> create(PassRefPtr<HTMLSelectElement>);
+
+ void add(PassRefPtr<HTMLOptionElement>, ExceptionCode&);
+ void add(PassRefPtr<HTMLOptionElement>, int index, ExceptionCode&);
+ void remove(int index);
+
+ int selectedIndex() const;
+ void setSelectedIndex(int);
+
+ void setLength(unsigned, ExceptionCode&);
+
+private:
+ HTMLOptionsCollection(PassRefPtr<HTMLSelectElement>);
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLOptionsCollection.idl b/Source/WebCore/html/HTMLOptionsCollection.idl
new file mode 100644
index 0000000..d9bfd45
--- /dev/null
+++ b/Source/WebCore/html/HTMLOptionsCollection.idl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ // FIXME: The W3C spec says that HTMLOptionsCollection should not have a parent class.
+ interface [
+ GenerateNativeConverter,
+ HasCustomIndexSetter
+ ] HTMLOptionsCollection : HTMLCollection {
+ attribute long selectedIndex;
+ attribute [Custom] unsigned long length
+ setter raises (DOMException);
+
+ [Custom] void add(in HTMLOptionElement option, in [Optional] unsigned long index)
+ raises (DOMException);
+ [Custom] void remove(in unsigned long index);
+
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+ Node item(in unsigned long index);
+ Node namedItem(in DOMString name);
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLOutputElement.cpp b/Source/WebCore/html/HTMLOutputElement.cpp
new file mode 100644
index 0000000..2f1d490
--- /dev/null
+++ b/Source/WebCore/html/HTMLOutputElement.cpp
@@ -0,0 +1,137 @@
+/*
+ * 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:
+ *
+ * * 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 "HTMLOutputElement.h"
+
+#include "HTMLFormElement.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+inline HTMLOutputElement::HTMLOutputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLFormControlElement(tagName, document, form)
+ , m_isDefaultValueMode(true)
+ , m_isSetTextContentInProgress(false)
+ , m_defaultValue("")
+ , m_tokens(DOMSettableTokenList::create())
+{
+}
+
+PassRefPtr<HTMLOutputElement> HTMLOutputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLOutputElement(tagName, document, form));
+}
+
+const AtomicString& HTMLOutputElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, output, ("output"));
+ return output;
+}
+
+void HTMLOutputElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::forAttr)
+ setFor(attr->value());
+ else
+ HTMLFormControlElement::parseMappedAttribute(attr);
+}
+
+DOMSettableTokenList* HTMLOutputElement::htmlFor() const
+{
+ return m_tokens.get();
+}
+
+void HTMLOutputElement::setFor(const String& value)
+{
+ m_tokens->setValue(value);
+}
+
+void HTMLOutputElement::childrenChanged(bool createdByParser, Node*, Node*, int)
+{
+ if (createdByParser || m_isSetTextContentInProgress) {
+ m_isSetTextContentInProgress = false;
+ return;
+ }
+
+ if (m_isDefaultValueMode)
+ m_defaultValue = textContent();
+}
+
+void HTMLOutputElement::reset()
+{
+ // The reset algorithm for output elements is to set the element's
+ // value mode flag to "default" and then to set the element's textContent
+ // attribute to the default value.
+ m_isDefaultValueMode = true;
+ if (m_defaultValue == value())
+ return;
+ setTextContentInternal(m_defaultValue);
+}
+
+String HTMLOutputElement::value() const
+{
+ return textContent();
+}
+
+void HTMLOutputElement::setValue(const String& value)
+{
+ // The value mode flag set to "value" when the value attribute is set.
+ m_isDefaultValueMode = false;
+ if (value == this->value())
+ return;
+ setTextContentInternal(value);
+}
+
+String HTMLOutputElement::defaultValue() const
+{
+ return m_defaultValue;
+}
+
+void HTMLOutputElement::setDefaultValue(const String& value)
+{
+ if (m_defaultValue == value)
+ return;
+ m_defaultValue = value;
+ // The spec requires the value attribute set to the default value
+ // when the element's value mode flag to "default".
+ if (m_isDefaultValueMode)
+ setTextContentInternal(value);
+}
+
+void HTMLOutputElement::setTextContentInternal(const String& value)
+{
+ ASSERT(!m_isSetTextContentInProgress);
+ ExceptionCode ec;
+ m_isSetTextContentInProgress = true;
+ setTextContent(value, ec);
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLOutputElement.h b/Source/WebCore/html/HTMLOutputElement.h
new file mode 100644
index 0000000..83ecee2
--- /dev/null
+++ b/Source/WebCore/html/HTMLOutputElement.h
@@ -0,0 +1,72 @@
+/*
+ * 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:
+ *
+ * * 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 HTMLOutputElement_h
+#define HTMLOutputElement_h
+
+#include "DOMSettableTokenList.h"
+#include "HTMLFormControlElement.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class HTMLOutputElement : public HTMLFormControlElement {
+public:
+ static PassRefPtr<HTMLOutputElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+
+ virtual bool willValidate() const { return false; }
+
+ String value() const;
+ void setValue(const String&);
+ String defaultValue() const;
+ void setDefaultValue(const String&);
+ void setFor(const String&);
+ DOMSettableTokenList* htmlFor() const;
+
+private:
+ HTMLOutputElement(const QualifiedName&, Document*, HTMLFormElement*);
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual const AtomicString& formControlType() const;
+ virtual bool isEnumeratable() const { return true; }
+ virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void reset();
+
+ void setTextContentInternal(const String&);
+
+ bool m_isDefaultValueMode;
+ bool m_isSetTextContentInProgress;
+ String m_defaultValue;
+ RefPtr<DOMSettableTokenList> m_tokens;
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLOutputElement.idl b/Source/WebCore/html/HTMLOutputElement.idl
new file mode 100644
index 0000000..4e6cbfb
--- /dev/null
+++ b/Source/WebCore/html/HTMLOutputElement.idl
@@ -0,0 +1,43 @@
+/*
+ * 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. 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.
+ */
+
+module html {
+ interface HTMLOutputElement : HTMLElement {
+ attribute [Custom] DOMSettableTokenList htmlFor;
+ readonly attribute HTMLFormElement form;
+ attribute [Reflect] DOMString name;
+
+ readonly attribute DOMString type;
+ attribute [ConvertNullToNullString] DOMString defaultValue;
+ attribute [ConvertNullToNullString] DOMString value;
+
+ readonly attribute boolean willValidate;
+ readonly attribute ValidityState validity;
+ readonly attribute DOMString validationMessage;
+ boolean checkValidity();
+ void setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error);
+
+ readonly attribute NodeList labels;
+ };
+}
diff --git a/Source/WebCore/html/HTMLParagraphElement.cpp b/Source/WebCore/html/HTMLParagraphElement.cpp
new file mode 100644
index 0000000..0b3e83f
--- /dev/null
+++ b/Source/WebCore/html/HTMLParagraphElement.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLParagraphElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "Document.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLParagraphElement::HTMLParagraphElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(pTag));
+}
+
+PassRefPtr<HTMLParagraphElement> HTMLParagraphElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLParagraphElement(tagName, document));
+}
+
+bool HTMLParagraphElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == alignAttr) {
+ result = eBlock; // We can share with DIV here.
+ return false;
+ }
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLParagraphElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == alignAttr) {
+ String v = attr->value();
+ if (equalIgnoringCase(attr->value(), "middle") || equalIgnoringCase(attr->value(), "center"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitCenter);
+ else if (equalIgnoringCase(attr->value(), "left"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitLeft);
+ else if (equalIgnoringCase(attr->value(), "right"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitRight);
+ else
+ addCSSProperty(attr, CSSPropertyTextAlign, v);
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLParagraphElement.h b/Source/WebCore/html/HTMLParagraphElement.h
new file mode 100644
index 0000000..6dbf071
--- /dev/null
+++ b/Source/WebCore/html/HTMLParagraphElement.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLParagraphElement_h
+#define HTMLParagraphElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLParagraphElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLParagraphElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLParagraphElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+};
+
+} // namespace WebCore
+
+#endif // HTMLParagraphElement_h
diff --git a/Source/WebCore/html/HTMLParagraphElement.idl b/Source/WebCore/html/HTMLParagraphElement.idl
new file mode 100644
index 0000000..246e9e9
--- /dev/null
+++ b/Source/WebCore/html/HTMLParagraphElement.idl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLParagraphElement : HTMLElement {
+ attribute [Reflect] DOMString align;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLParamElement.cpp b/Source/WebCore/html/HTMLParamElement.cpp
new file mode 100644
index 0000000..2dc9d1d
--- /dev/null
+++ b/Source/WebCore/html/HTMLParamElement.cpp
@@ -0,0 +1,86 @@
+/*
+ * 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, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLParamElement.h"
+
+#include "Attribute.h"
+#include "Document.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLParamElement::HTMLParamElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(paramTag));
+}
+
+PassRefPtr<HTMLParamElement> HTMLParamElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLParamElement(tagName, document));
+}
+
+void HTMLParamElement::parseMappedAttribute(Attribute* attr)
+{
+ if (isIdAttributeName(attr->name())) {
+ // Must call base class so that hasID bit gets set.
+ HTMLElement::parseMappedAttribute(attr);
+ if (document()->isHTMLDocument())
+ return;
+ m_name = attr->value();
+ } else if (attr->name() == nameAttr) {
+ m_name = attr->value();
+ } else if (attr->name() == valueAttr) {
+ m_value = attr->value();
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+bool HTMLParamElement::isURLAttribute(Attribute* attr) const
+{
+ if (attr->name() == valueAttr) {
+ Attribute* attr = attributes()->getAttributeItem(nameAttr);
+ if (attr) {
+ const AtomicString& value = attr->value();
+ if (equalIgnoringCase(value, "data") || equalIgnoringCase(value, "movie") || equalIgnoringCase(value, "src"))
+ return true;
+ }
+ }
+ return false;
+}
+
+void HTMLParamElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+{
+ HTMLElement::addSubresourceAttributeURLs(urls);
+
+ if (!equalIgnoringCase(name(), "data") &&
+ !equalIgnoringCase(name(), "movie") &&
+ !equalIgnoringCase(name(), "src"))
+ return;
+
+ addSubresourceURL(urls, document()->completeURL(value()));
+}
+
+}
diff --git a/Source/WebCore/html/HTMLParamElement.h b/Source/WebCore/html/HTMLParamElement.h
new file mode 100644
index 0000000..f13f8fa
--- /dev/null
+++ b/Source/WebCore/html/HTMLParamElement.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2004, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLParamElement_h
+#define HTMLParamElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLParamElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLParamElement> create(const QualifiedName&, Document*);
+
+ String name() const { return m_name; }
+ String value() const { return m_value; }
+
+private:
+ HTMLParamElement(const QualifiedName&, Document*);
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual bool isURLAttribute(Attribute*) const;
+
+ virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+
+ // FIXME: These don't need to be stored as members and instead
+ // name() value() could use getAttribute(nameAttr/valueAttr).
+ AtomicString m_name;
+ AtomicString m_value;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/HTMLParamElement.idl b/Source/WebCore/html/HTMLParamElement.idl
new file mode 100644
index 0000000..1f0c0de
--- /dev/null
+++ b/Source/WebCore/html/HTMLParamElement.idl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLParamElement : HTMLElement {
+ attribute [Reflect] DOMString name;
+ attribute [Reflect] DOMString type;
+ attribute [Reflect] DOMString value;
+ attribute [Reflect] DOMString valueType;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLParserErrorCodes.cpp b/Source/WebCore/html/HTMLParserErrorCodes.cpp
new file mode 100644
index 0000000..6f973df
--- /dev/null
+++ b/Source/WebCore/html/HTMLParserErrorCodes.cpp
@@ -0,0 +1,70 @@
+/*
+ * 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
+ * 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"
+#include "HTMLParserErrorCodes.h"
+
+namespace WebCore {
+
+const char* htmlParserErrorMessageTemplate(HTMLParserErrorCode errorCode)
+{
+ static const char* const errors[] = {
+ "%tag1 is not allowed inside %tag2. Moving %tag1 into the nearest enclosing <table>.",
+ "<head> must be a child of <html>. Content ignored.",
+ "%tag1 is not allowed inside %tag2. Moving %tag1 into the <head>.",
+ "Extra %tag1 encountered. Migrating attributes back to the original %tag1 element and ignoring the tag.",
+ "<area> is not allowed inside %tag1. Moving the <area> into the nearest enclosing <map>.",
+ "%tag1 is not allowed inside %tag2. Content ignored.",
+ "%tag1 is not allowed in a <frameset> page. Content ignored.",
+ "%tag1 is not allowed inside %tag2. Closing %tag2 and trying the insertion again.",
+ "%tag1 is not allowed inside <caption>. Closing the <caption> and trying the insertion again.",
+ "<table> is not allowed inside %tag1. Closing the current <table> and inserting the new <table> as a sibling.",
+ "%tag1 is not allowed inside %tag2. Inserting %tag1 before the <table> instead.",
+ "%tag1 misplaced in <table>. Creating %tag2 and putting %tag1 inside it.",
+ "</br> encountered. Converting </br> into <br>.",
+ "XML self-closing tag syntax used on %tag1. The tag will not be closed.",
+ "Unmatched </p> encountered. Converting </p> into <p></p>.",
+ "Unmatched %tag1 encountered. Ignoring tag.",
+ "%tag1 misnested or not properly closed. Cloning %tag1 in order to preserve the styles applied by it.",
+ "<form> cannot act as a container inside %tag1 without disrupting the table. The children of the <form> will be placed inside the %tag1 instead.",
+ "XML self-closing tag syntax used on <script>. The tag will be closed by WebKit, but not all browsers do this. Change to <script></script> instead for best cross-browser compatibility."
+ };
+
+ if (errorCode >= MisplacedTablePartError && errorCode <= IncorrectXMLCloseScriptWarning)
+ return errors[errorCode];
+ return 0;
+}
+
+const char* htmlParserDocumentWriteMessage()
+{
+ return "[The HTML that caused this error was generated by a script.] ";
+}
+
+bool isWarning(HTMLParserErrorCode code)
+{
+ return code >= IncorrectXMLCloseScriptWarning;
+}
+
+}
diff --git a/Source/WebCore/html/HTMLParserErrorCodes.h b/Source/WebCore/html/HTMLParserErrorCodes.h
new file mode 100644
index 0000000..4da6b90
--- /dev/null
+++ b/Source/WebCore/html/HTMLParserErrorCodes.h
@@ -0,0 +1,60 @@
+/*
+ * 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
+ * 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 HTMLParserErrorCodes_h
+#define HTMLParserErrorCodes_h
+
+namespace WebCore {
+
+enum HTMLParserErrorCode {
+ MisplacedTablePartError,
+ MisplacedHeadError,
+ MisplacedHeadContentError,
+ RedundantHTMLBodyError,
+ MisplacedAreaError,
+ IgnoredContentError,
+ MisplacedFramesetContentError,
+ MisplacedContentRetryError,
+ MisplacedCaptionContentError,
+ MisplacedTableError,
+ StrayTableContentError,
+ TablePartRequiredError,
+ MalformedBRError,
+ IncorrectXMLSelfCloseError,
+ StrayParagraphCloseError,
+ StrayCloseTagError,
+ ResidualStyleError,
+ FormInsideTablePartError,
+ IncorrectXMLCloseScriptWarning
+};
+
+const char* htmlParserErrorMessageTemplate(HTMLParserErrorCode);
+const char* htmlParserDocumentWriteMessage();
+
+bool isWarning(HTMLParserErrorCode);
+
+}
+
+#endif
diff --git a/Source/WebCore/html/HTMLParserQuirks.h b/Source/WebCore/html/HTMLParserQuirks.h
new file mode 100644
index 0000000..50de710
--- /dev/null
+++ b/Source/WebCore/html/HTMLParserQuirks.h
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ * 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 HTMLParserQuirks_h
+#define HTMLParserQuirks_h
+
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class Node;
+
+class HTMLParserQuirks : public Noncopyable {
+public:
+ HTMLParserQuirks() { }
+ virtual ~HTMLParserQuirks() { }
+
+ virtual void reset() = 0;
+
+ virtual bool shouldInsertNode(Node* parent, Node* newNode) = 0;
+ virtual bool shouldPopBlock(const AtomicString& tagNameOnStack, const AtomicString& tagNameToPop) = 0;
+};
+
+} // namespace WebCore
+
+#endif // HTMLParserQuirks_h
diff --git a/Source/WebCore/html/HTMLPlugInElement.cpp b/Source/WebCore/html/HTMLPlugInElement.cpp
new file mode 100644
index 0000000..bf2722b
--- /dev/null
+++ b/Source/WebCore/html/HTMLPlugInElement.cpp
@@ -0,0 +1,194 @@
+/**
+ * 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 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLPlugInElement.h"
+
+#include "Attribute.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "CSSPropertyNames.h"
+#include "Document.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameTree.h"
+#include "HTMLNames.h"
+#include "Page.h"
+#include "RenderEmbeddedObject.h"
+#include "RenderWidget.h"
+#include "ScriptController.h"
+#include "Settings.h"
+#include "Widget.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+#include "npruntime_impl.h"
+#endif
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document* doc)
+ : HTMLFrameOwnerElement(tagName, doc)
+ , m_inBeforeLoadEventHandler(false)
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ , m_NPObject(0)
+#endif
+ , m_isCapturingMouseEvents(false)
+{
+}
+
+HTMLPlugInElement::~HTMLPlugInElement()
+{
+ ASSERT(!m_instance); // cleared in detach()
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ if (m_NPObject) {
+ _NPN_ReleaseObject(m_NPObject);
+ m_NPObject = 0;
+ }
+#endif
+}
+
+void HTMLPlugInElement::detach()
+{
+ m_instance.clear();
+
+ if (m_isCapturingMouseEvents) {
+ if (Frame* frame = document()->frame())
+ frame->eventHandler()->setCapturingMouseEventsNode(0);
+ m_isCapturingMouseEvents = false;
+ }
+
+ HTMLFrameOwnerElement::detach();
+}
+
+PassScriptInstance HTMLPlugInElement::getInstance() const
+{
+ Frame* frame = document()->frame();
+ if (!frame)
+ return 0;
+
+ // If the host dynamically turns off JavaScript (or Java) we will still return
+ // the cached allocated Bindings::Instance. Not supporting this edge-case is OK.
+ if (m_instance)
+ return m_instance;
+
+ if (Widget* widget = pluginWidget())
+ m_instance = frame->script()->createScriptInstanceForWidget(widget);
+
+ return m_instance;
+}
+
+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 0;
+ }
+
+ RenderWidget* renderWidget = renderWidgetForJSBindings();
+ if (!renderWidget)
+ return 0;
+
+ return renderWidget->widget();
+}
+
+bool HTMLPlugInElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == widthAttr ||
+ attrName == heightAttr ||
+ attrName == vspaceAttr ||
+ attrName == hspaceAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ if (attrName == alignAttr) {
+ result = eReplaced; // Share with <img> since the alignment behavior is the same.
+ return false;
+ }
+
+ return HTMLFrameOwnerElement::mapToEntry(attrName, result);
+}
+
+void HTMLPlugInElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == widthAttr)
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
+ else if (attr->name() == heightAttr)
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
+ else if (attr->name() == vspaceAttr) {
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
+ } else if (attr->name() == hspaceAttr) {
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
+ } else if (attr->name() == alignAttr)
+ addHTMLAlignment(attr);
+ else
+ HTMLFrameOwnerElement::parseMappedAttribute(attr);
+}
+
+void HTMLPlugInElement::defaultEventHandler(Event* event)
+{
+ // Firefox seems to use a fake event listener to dispatch events to plug-in (tested with mouse events only).
+ // This is observable via different order of events - in Firefox, event listeners specified in HTML attributes fires first, then an event
+ // gets dispatched to plug-in, and only then other event listeners fire. Hopefully, this difference does not matter in practice.
+
+ // FIXME: Mouse down and scroll events are passed down to plug-in via custom code in EventHandler; these code paths should be united.
+
+ RenderObject* r = renderer();
+ if (r && r->isEmbeddedObject() && toRenderEmbeddedObject(r)->showsMissingPluginIndicator()) {
+ toRenderEmbeddedObject(r)->handleMissingPluginIndicatorEvent(event);
+ return;
+ }
+
+ if (!r || !r->isWidget())
+ return;
+ Widget* widget = toRenderWidget(r)->widget();
+ if (!widget)
+ return;
+ widget->handleEvent(event);
+}
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+NPObject* HTMLPlugInElement::getNPObject()
+{
+ ASSERT(document()->frame());
+ if (!m_NPObject)
+ m_NPObject = document()->frame()->script()->createScriptObjectForPluginElement(this);
+ return m_NPObject;
+}
+
+#endif /* ENABLE(NETSCAPE_PLUGIN_API) */
+
+#if PLATFORM(ANDROID)
+bool HTMLPlugInElement::supportsFocus() const
+{
+ return true;
+}
+#endif
+
+}
diff --git a/Source/WebCore/html/HTMLPlugInElement.h b/Source/WebCore/html/HTMLPlugInElement.h
new file mode 100644
index 0000000..9d25fee
--- /dev/null
+++ b/Source/WebCore/html/HTMLPlugInElement.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2004, 2006, 2007, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLPlugInElement_h
+#define HTMLPlugInElement_h
+
+#include "HTMLFrameOwnerElement.h"
+#include "ScriptInstance.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+struct NPObject;
+#endif
+
+namespace WebCore {
+
+class RenderEmbeddedObject;
+class RenderWidget;
+class Widget;
+
+class HTMLPlugInElement : public HTMLFrameOwnerElement {
+public:
+ virtual ~HTMLPlugInElement();
+
+ PassScriptInstance getInstance() const;
+
+ Widget* pluginWidget() const;
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ NPObject* getNPObject();
+#endif
+
+ bool isCapturingMouseEvents() const { return m_isCapturingMouseEvents; }
+ void setIsCapturingMouseEvents(bool capturing) { m_isCapturingMouseEvents = capturing; }
+
+protected:
+ HTMLPlugInElement(const QualifiedName& tagName, Document*);
+
+ virtual void detach();
+
+ virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ bool m_inBeforeLoadEventHandler;
+
+#if PLATFORM(ANDROID)
+ // in Android, plugin has a focused mode where it accepts all the touch events.
+ // so need to claim that plugin element supports focus instead of using the default.
+ virtual bool supportsFocus() const;
+#endif
+
+private:
+ virtual void defaultEventHandler(Event*);
+
+ virtual RenderWidget* renderWidgetForJSBindings() const = 0;
+
+protected:
+ AtomicString m_name;
+
+private:
+ mutable ScriptInstance m_instance;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ NPObject* m_NPObject;
+#endif
+ bool m_isCapturingMouseEvents;
+};
+
+} // namespace WebCore
+
+#endif // HTMLPlugInElement_h
diff --git a/Source/WebCore/html/HTMLPlugInImageElement.cpp b/Source/WebCore/html/HTMLPlugInImageElement.cpp
new file mode 100644
index 0000000..9ac5ad8
--- /dev/null
+++ b/Source/WebCore/html/HTMLPlugInImageElement.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2008 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLPlugInImageElement.h"
+
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
+#include "HTMLImageLoader.h"
+#include "Image.h"
+#include "Page.h"
+#include "RenderEmbeddedObject.h"
+#include "RenderImage.h"
+
+namespace WebCore {
+
+HTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Document* document, bool createdByParser)
+ : HTMLPlugInElement(tagName, document)
+ // m_needsWidgetUpdate(!createdByParser) allows HTMLObjectElement to delay
+ // widget updates until after all children are parsed. For HTMLEmbedElement
+ // this delay is unnecessary, but it is simpler to make both classes share
+ // the same codepath in this class.
+ , m_needsWidgetUpdate(!createdByParser)
+{
+}
+
+RenderEmbeddedObject* HTMLPlugInImageElement::renderEmbeddedObject() const
+{
+ // HTMLObjectElement and HTMLEmbedElement may return arbitrary renderers
+ // when using fallback content.
+ if (!renderer() || !renderer()->isEmbeddedObject())
+ return 0;
+ return toRenderEmbeddedObject(renderer());
+}
+
+bool HTMLPlugInImageElement::isImageType()
+{
+ if (m_serviceType.isEmpty() && protocolIs(m_url, "data"))
+ m_serviceType = mimeTypeFromDataURL(m_url);
+
+ if (Frame* frame = document()->frame()) {
+ KURL completedURL = frame->loader()->completeURL(m_url);
+ return frame->loader()->client()->objectContentType(completedURL, m_serviceType) == ObjectContentImage;
+ }
+
+ return Image::supportsType(m_serviceType);
+}
+
+// We don't use m_url, as it may not be the final URL that the object loads,
+// depending on <param> values.
+bool HTMLPlugInImageElement::allowedToLoadFrameURL(const String& url)
+{
+ ASSERT(document());
+ ASSERT(document()->frame());
+ if (document()->frame()->page()->frameCount() >= Page::maxNumberOfFrames)
+ return false;
+
+ // We allow one level of self-reference because some sites depend on that.
+ // But we don't allow more than one.
+ KURL completeURL = document()->completeURL(url);
+ bool foundSelfReference = false;
+ for (Frame* frame = document()->frame(); frame; frame = frame->tree()->parent()) {
+ if (equalIgnoringFragmentIdentifier(frame->loader()->url(), completeURL)) {
+ if (foundSelfReference)
+ return false;
+ foundSelfReference = true;
+ }
+ }
+ return true;
+}
+
+// We don't use m_url, or m_serviceType as they may not be the final values
+// that <object> uses depending on <param> values.
+bool HTMLPlugInImageElement::wouldLoadAsNetscapePlugin(const String& url, const String& serviceType)
+{
+ ASSERT(document());
+ ASSERT(document()->frame());
+ FrameLoader* frameLoader = document()->frame()->loader();
+ ASSERT(frameLoader);
+ KURL completedURL;
+ if (!url.isEmpty())
+ completedURL = frameLoader->completeURL(url);
+
+ if (frameLoader->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
+ return true;
+ return false;
+}
+
+RenderObject* HTMLPlugInImageElement::createRenderer(RenderArena* arena, RenderStyle* style)
+{
+ // Fallback content breaks the DOM->Renderer class relationship of this
+ // class and all superclasses because createObject won't necessarily
+ // return a RenderEmbeddedObject, RenderPart or even RenderWidget.
+ if (useFallbackContent())
+ return RenderObject::createObject(this, style);
+ if (isImageType()) {
+ RenderImage* image = new (arena) RenderImage(this);
+ image->setImageResource(RenderImageResource::create());
+ return image;
+ }
+ return new (arena) RenderEmbeddedObject(this);
+}
+
+void HTMLPlugInImageElement::recalcStyle(StyleChange ch)
+{
+ // FIXME: Why is this necessary? Manual re-attach is almost always wrong.
+ if (!useFallbackContent() && needsWidgetUpdate() && renderer() && !isImageType()) {
+ detach();
+ attach();
+ }
+ HTMLPlugInElement::recalcStyle(ch);
+}
+
+void HTMLPlugInImageElement::attach()
+{
+ bool isImage = isImageType();
+
+ if (!isImage)
+ queuePostAttachCallback(&HTMLPlugInImageElement::updateWidgetCallback, this);
+
+ HTMLPlugInElement::attach();
+
+ if (isImage && renderer() && !useFallbackContent()) {
+ if (!m_imageLoader)
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader->updateFromElement();
+ }
+}
+
+void HTMLPlugInImageElement::detach()
+{
+ // FIXME: Because of the insanity that is HTMLPlugInImageElement::recalcStyle,
+ // 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.
+ if (attached() && renderer() && !useFallbackContent())
+ // Update the widget the next time we attach (detaching destroys the plugin).
+ setNeedsWidgetUpdate(true);
+ HTMLPlugInElement::detach();
+}
+
+void HTMLPlugInImageElement::updateWidgetIfNecessary()
+{
+ document()->updateStyleIfNeeded();
+
+ if (!needsWidgetUpdate() || useFallbackContent() || isImageType())
+ return;
+
+ if (!renderEmbeddedObject() || renderEmbeddedObject()->pluginCrashedOrWasMissing())
+ return;
+
+ // True indicates that this code path should only create non-netscape plugins (no clue why).
+ updateWidget(true);
+}
+
+void HTMLPlugInImageElement::finishParsingChildren()
+{
+ HTMLPlugInElement::finishParsingChildren();
+ if (useFallbackContent())
+ return;
+
+ setNeedsWidgetUpdate(true);
+ if (inDocument())
+ setNeedsStyleRecalc();
+}
+
+void HTMLPlugInImageElement::willMoveToNewOwnerDocument()
+{
+ if (m_imageLoader)
+ m_imageLoader->elementWillMoveToNewOwnerDocument();
+ HTMLPlugInElement::willMoveToNewOwnerDocument();
+}
+
+void HTMLPlugInImageElement::updateWidgetCallback(Node* n)
+{
+ static_cast<HTMLPlugInImageElement*>(n)->updateWidgetIfNecessary();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLPlugInImageElement.h b/Source/WebCore/html/HTMLPlugInImageElement.h
new file mode 100644
index 0000000..377fd99
--- /dev/null
+++ b/Source/WebCore/html/HTMLPlugInImageElement.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLPlugInImageElement_h
+#define HTMLPlugInImageElement_h
+
+#include "HTMLPlugInElement.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class HTMLImageLoader;
+class FrameLoader;
+
+// Base class for HTMLObjectElement and HTMLEmbedElement
+class HTMLPlugInImageElement : public HTMLPlugInElement {
+public:
+ RenderEmbeddedObject* renderEmbeddedObject() const;
+
+ virtual void updateWidget(bool onlyCreateNonNetscapePlugins) = 0;
+
+ const String& serviceType() const { return m_serviceType; }
+ const String& url() const { return m_url; }
+
+protected:
+ HTMLPlugInImageElement(const QualifiedName& tagName, Document*, bool createdByParser);
+
+ bool isImageType();
+
+ OwnPtr<HTMLImageLoader> m_imageLoader;
+ String m_serviceType;
+ String m_url;
+
+ static void updateWidgetCallback(Node*);
+ virtual void attach();
+ virtual void detach();
+
+ bool needsWidgetUpdate() const { return m_needsWidgetUpdate; }
+ void setNeedsWidgetUpdate(bool needsWidgetUpdate) { m_needsWidgetUpdate = needsWidgetUpdate; }
+
+ bool allowedToLoadFrameURL(const String& url);
+ bool wouldLoadAsNetscapePlugin(const String& url, const String& serviceType);
+
+private:
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+ virtual void recalcStyle(StyleChange);
+
+ virtual void finishParsingChildren();
+ virtual void willMoveToNewOwnerDocument();
+
+ void updateWidgetIfNecessary();
+ virtual bool useFallbackContent() const { return false; }
+
+ bool m_needsWidgetUpdate;
+};
+
+} // namespace WebCore
+
+#endif // HTMLPlugInImageElement_h
diff --git a/Source/WebCore/html/HTMLPreElement.cpp b/Source/WebCore/html/HTMLPreElement.cpp
new file mode 100644
index 0000000..fc67aca
--- /dev/null
+++ b/Source/WebCore/html/HTMLPreElement.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLPreElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLPreElement::HTMLPreElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+}
+
+PassRefPtr<HTMLPreElement> HTMLPreElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLPreElement(tagName, document));
+}
+
+bool HTMLPreElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == widthAttr || attrName == wrapAttr) {
+ result = ePre;
+ return false;
+ }
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLPreElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == widthAttr) {
+ // FIXME: Implement this some day. Width on a <pre> is the # of characters that
+ // we should size the pre to. We basically need to take the width of a space,
+ // multiply by the value of the attribute and then set that as the width CSS
+ // property.
+ } else if (attr->name() == wrapAttr) {
+ if (!attr->value().isNull())
+ addCSSProperty(attr, CSSPropertyWhiteSpace, CSSValuePreWrap);
+ } else
+ return HTMLElement::parseMappedAttribute(attr);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLPreElement.h b/Source/WebCore/html/HTMLPreElement.h
new file mode 100644
index 0000000..3ccdb86
--- /dev/null
+++ b/Source/WebCore/html/HTMLPreElement.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLPreElement_h
+#define HTMLPreElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLPreElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLPreElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLPreElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+};
+
+} // namespace WebCore
+
+#endif // HTMLPreElement_h
diff --git a/Source/WebCore/html/HTMLPreElement.idl b/Source/WebCore/html/HTMLPreElement.idl
new file mode 100644
index 0000000..ae137f0
--- /dev/null
+++ b/Source/WebCore/html/HTMLPreElement.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Inc. All right reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLPreElement : HTMLElement {
+ // FIXME: DOM spec says that width should be of type DOMString
+ // see http://bugs.webkit.org/show_bug.cgi?id=8992
+ attribute [Reflect] long width;
+
+ // Extensions
+ attribute [Reflect] boolean wrap;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLProgressElement.cpp b/Source/WebCore/html/HTMLProgressElement.cpp
new file mode 100644
index 0000000..4a55a1e
--- /dev/null
+++ b/Source/WebCore/html/HTMLProgressElement.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#if ENABLE(PROGRESS_TAG)
+#include "HTMLProgressElement.h"
+
+#include "Attribute.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
+#include "FormDataList.h"
+#include "HTMLFormElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "RenderProgress.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLProgressElement::HTMLProgressElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLFormControlElement(tagName, document, form)
+{
+ ASSERT(hasTagName(progressTag));
+}
+
+PassRefPtr<HTMLProgressElement> HTMLProgressElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLProgressElement(tagName, document, form));
+}
+
+RenderObject* HTMLProgressElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderProgress(this);
+}
+
+const AtomicString& HTMLProgressElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, progress, ("progress"));
+ return progress;
+}
+
+void HTMLProgressElement::parseMappedAttribute(Attribute* attribute)
+{
+ if (attribute->name() == valueAttr) {
+ if (renderer())
+ renderer()->updateFromElement();
+ } else if (attribute->name() == maxAttr) {
+ if (renderer())
+ renderer()->updateFromElement();
+ } else
+ HTMLFormControlElement::parseMappedAttribute(attribute);
+}
+
+void HTMLProgressElement::attach()
+{
+ HTMLFormControlElement::attach();
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+double HTMLProgressElement::value() const
+{
+ const AtomicString& valueString = getAttribute(valueAttr);
+ double value;
+ bool ok = parseToDoubleForNumberType(valueString, &value);
+ if (!ok || value < 0)
+ return valueString.isNull() ? 1 : 0;
+ return (value > max()) ? max() : value;
+}
+
+void HTMLProgressElement::setValue(double value, ExceptionCode& ec)
+{
+ if (!isfinite(value)) {
+ ec = NOT_SUPPORTED_ERR;
+ return;
+ }
+ setAttribute(valueAttr, String::number(value >= 0 ? value : 0));
+}
+
+double HTMLProgressElement::max() const
+{
+ double max;
+ bool ok = parseToDoubleForNumberType(getAttribute(maxAttr), &max);
+ if (!ok || max <= 0)
+ return 1;
+ return max;
+}
+
+void HTMLProgressElement::setMax(double max, ExceptionCode& ec)
+{
+ if (!isfinite(max)) {
+ ec = NOT_SUPPORTED_ERR;
+ return;
+ }
+ setAttribute(maxAttr, String::number(max > 0 ? max : 1));
+}
+
+double HTMLProgressElement::position() const
+{
+ if (!hasAttribute(valueAttr))
+ return -1;
+ return value() / max();
+}
+
+} // namespace
+#endif
diff --git a/Source/WebCore/html/HTMLProgressElement.h b/Source/WebCore/html/HTMLProgressElement.h
new file mode 100644
index 0000000..c80f50f
--- /dev/null
+++ b/Source/WebCore/html/HTMLProgressElement.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLProgressElement_h
+#define HTMLProgressElement_h
+
+#if ENABLE(PROGRESS_TAG)
+#include "HTMLFormControlElement.h"
+
+namespace WebCore {
+
+class HTMLProgressElement : public HTMLFormControlElement {
+public:
+ static PassRefPtr<HTMLProgressElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+
+ double value() const;
+ void setValue(double, ExceptionCode&);
+
+ double max() const;
+ void setMax(double, ExceptionCode&);
+
+ double position() const;
+
+private:
+ HTMLProgressElement(const QualifiedName&, Document*, HTMLFormElement*);
+
+ virtual bool recalcWillValidate() const { return false; }
+
+ virtual const AtomicString& formControlType() const;
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void attach();
+};
+
+} // namespace
+
+#endif
+#endif
diff --git a/Source/WebCore/html/HTMLProgressElement.idl b/Source/WebCore/html/HTMLProgressElement.idl
new file mode 100644
index 0000000..b49252c
--- /dev/null
+++ b/Source/WebCore/html/HTMLProgressElement.idl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=PROGRESS_TAG
+ ] HTMLProgressElement : HTMLElement {
+ attribute double value
+ setter raises(DOMException);
+ attribute double max
+ setter raises(DOMException);
+ readonly attribute double position;
+ readonly attribute HTMLFormElement form;
+ readonly attribute NodeList labels;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLQuoteElement.cpp b/Source/WebCore/html/HTMLQuoteElement.cpp
new file mode 100644
index 0000000..a58a504
--- /dev/null
+++ b/Source/WebCore/html/HTMLQuoteElement.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLQuoteElement.h"
+
+#include "Document.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLQuoteElement::HTMLQuoteElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(qTag));
+}
+
+PassRefPtr<HTMLQuoteElement> HTMLQuoteElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLQuoteElement(tagName, document));
+}
+
+void HTMLQuoteElement::insertedIntoDocument()
+{
+ document()->setUsesBeforeAfterRules(true);
+
+ HTMLElement::insertedIntoDocument();
+}
+
+bool HTMLQuoteElement::isURLAttribute(Attribute* attribute) const
+{
+ return attribute->name() == citeAttr;
+}
+
+}
diff --git a/Source/WebCore/html/HTMLQuoteElement.h b/Source/WebCore/html/HTMLQuoteElement.h
new file mode 100644
index 0000000..d378de4
--- /dev/null
+++ b/Source/WebCore/html/HTMLQuoteElement.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2000 Simon Hausmann <hausmann@kde.org>
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLQuoteElement_h
+#define HTMLQuoteElement_h
+
+#include <wtf/Forward.h>
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLQuoteElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLQuoteElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLQuoteElement(const QualifiedName&, Document*);
+
+ virtual void insertedIntoDocument();
+ virtual bool isURLAttribute(Attribute*) const;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLQuoteElement.idl b/Source/WebCore/html/HTMLQuoteElement.idl
new file mode 100644
index 0000000..fa1bcdb
--- /dev/null
+++ b/Source/WebCore/html/HTMLQuoteElement.idl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLQuoteElement : HTMLElement {
+ attribute [Reflect, URL] DOMString cite;
+ };
+}
diff --git a/Source/WebCore/html/HTMLScriptElement.cpp b/Source/WebCore/html/HTMLScriptElement.cpp
new file mode 100644
index 0000000..603b2a8
--- /dev/null
+++ b/Source/WebCore/html/HTMLScriptElement.cpp
@@ -0,0 +1,181 @@
+/*
+ * 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, 2004, 2005, 2006, 2007, 2008 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLScriptElement.h"
+
+#include "Attribute.h"
+#include "Document.h"
+#include "Event.h"
+#include "EventNames.h"
+#include "HTMLNames.h"
+#include "ScriptEventListener.h"
+#include "Text.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLScriptElement::HTMLScriptElement(const QualifiedName& tagName, Document* document, bool wasInsertedByParser, bool wasAlreadyStarted)
+ : HTMLElement(tagName, document)
+ , ScriptElement(this, wasInsertedByParser, wasAlreadyStarted)
+{
+ ASSERT(hasTagName(scriptTag));
+}
+
+PassRefPtr<HTMLScriptElement> HTMLScriptElement::create(const QualifiedName& tagName, Document* document, bool wasInsertedByParser)
+{
+ return adoptRef(new HTMLScriptElement(tagName, document, wasInsertedByParser, false));
+}
+
+bool HTMLScriptElement::isURLAttribute(Attribute* attr) const
+{
+ return attr->name() == srcAttr;
+}
+
+void HTMLScriptElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ ScriptElement::childrenChanged();
+ HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+}
+
+void HTMLScriptElement::parseMappedAttribute(Attribute* attr)
+{
+ const QualifiedName& attrName = attr->name();
+
+ if (attrName == srcAttr)
+ handleSourceAttribute(attr->value());
+ else if (attrName == onloadAttr)
+ setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onbeforeloadAttr)
+ setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, attr));
+ else if (attrName == onbeforeprocessAttr)
+ setAttributeEventListener(eventNames().beforeprocessEvent, createAttributeEventListener(this, attr));
+ else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+void HTMLScriptElement::finishParsingChildren()
+{
+ ScriptElement::finishParsingChildren(sourceAttributeValue());
+ HTMLElement::finishParsingChildren();
+}
+
+void HTMLScriptElement::insertedIntoDocument()
+{
+ HTMLElement::insertedIntoDocument();
+ ScriptElement::insertedIntoDocument(sourceAttributeValue());
+}
+
+void HTMLScriptElement::removedFromDocument()
+{
+ HTMLElement::removedFromDocument();
+ ScriptElement::removedFromDocument();
+}
+
+void HTMLScriptElement::setText(const String &value)
+{
+ ExceptionCode ec = 0;
+ int numChildren = childNodeCount();
+
+ if (numChildren == 1 && firstChild()->isTextNode()) {
+ static_cast<Text*>(firstChild())->setData(value, ec);
+ return;
+ }
+
+ if (numChildren > 0)
+ removeChildren();
+
+ appendChild(document()->createTextNode(value.impl()), ec);
+}
+
+KURL HTMLScriptElement::src() const
+{
+ return document()->completeURL(sourceAttributeValue());
+}
+
+void HTMLScriptElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+{
+ HTMLElement::addSubresourceAttributeURLs(urls);
+
+ addSubresourceURL(urls, src());
+}
+
+String HTMLScriptElement::sourceAttributeValue() const
+{
+ return getAttribute(srcAttr).string();
+}
+
+String HTMLScriptElement::charsetAttributeValue() const
+{
+ return getAttribute(charsetAttr).string();
+}
+
+String HTMLScriptElement::typeAttributeValue() const
+{
+ return getAttribute(typeAttr).string();
+}
+
+String HTMLScriptElement::languageAttributeValue() const
+{
+ return getAttribute(languageAttr).string();
+}
+
+String HTMLScriptElement::forAttributeValue() const
+{
+ return getAttribute(forAttr).string();
+}
+
+String HTMLScriptElement::eventAttributeValue() const
+{
+ return getAttribute(eventAttr).string();
+}
+
+bool HTMLScriptElement::asyncAttributeValue() const
+{
+ return fastHasAttribute(asyncAttr);
+}
+
+bool HTMLScriptElement::deferAttributeValue() const
+{
+ return fastHasAttribute(deferAttr);
+}
+
+void HTMLScriptElement::dispatchLoadEvent()
+{
+ ASSERT(!haveFiredLoadEvent());
+ setHaveFiredLoadEvent(true);
+
+ dispatchEvent(Event::create(eventNames().loadEvent, false, false));
+}
+
+void HTMLScriptElement::dispatchErrorEvent()
+{
+ dispatchEvent(Event::create(eventNames().errorEvent, true, false));
+}
+
+PassRefPtr<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren() const
+{
+ return adoptRef(new HTMLScriptElement(tagQName(), document(), false, wasAlreadyStarted()));
+}
+
+}
diff --git a/Source/WebCore/html/HTMLScriptElement.h b/Source/WebCore/html/HTMLScriptElement.h
new file mode 100644
index 0000000..09773c5
--- /dev/null
+++ b/Source/WebCore/html/HTMLScriptElement.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLScriptElement_h
+#define HTMLScriptElement_h
+
+#include "ScriptElement.h"
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLScriptElement : public HTMLElement, public ScriptElement {
+public:
+ static PassRefPtr<HTMLScriptElement> create(const QualifiedName&, Document*, bool wasInsertedByParser);
+
+ String text() const { return scriptContent(); }
+ void setText(const String&);
+
+ KURL src() const;
+
+private:
+ HTMLScriptElement(const QualifiedName&, Document*, bool wasInsertedByParser, bool wasAlreadyStarted);
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+
+ virtual bool isURLAttribute(Attribute*) const;
+ virtual void finishParsingChildren();
+
+ virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+
+ virtual String sourceAttributeValue() const;
+ virtual String charsetAttributeValue() const;
+ virtual String typeAttributeValue() const;
+ virtual String languageAttributeValue() const;
+ virtual String forAttributeValue() const;
+ virtual String eventAttributeValue() const;
+ virtual bool asyncAttributeValue() const;
+ virtual bool deferAttributeValue() const;
+
+ virtual void dispatchLoadEvent();
+ virtual void dispatchErrorEvent();
+
+ PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() const;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLScriptElement.idl b/Source/WebCore/html/HTMLScriptElement.idl
new file mode 100644
index 0000000..20b7331
--- /dev/null
+++ b/Source/WebCore/html/HTMLScriptElement.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLScriptElement : HTMLElement {
+ attribute [ConvertNullToNullString] DOMString text;
+ attribute [Reflect=for] DOMString htmlFor;
+ attribute [Reflect] DOMString event;
+ attribute [Reflect] DOMString charset;
+ attribute [Reflect] boolean async;
+ attribute [Reflect] boolean defer;
+ attribute [Reflect, URL] DOMString src;
+ attribute [Reflect] DOMString type;
+ };
+}
diff --git a/Source/WebCore/html/HTMLSelectElement.cpp b/Source/WebCore/html/HTMLSelectElement.cpp
new file mode 100644
index 0000000..c7f47f2
--- /dev/null
+++ b/Source/WebCore/html/HTMLSelectElement.cpp
@@ -0,0 +1,534 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * 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, 2009, 2010 Apple Inc. All rights reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ * Copyright (C) 2010 Google 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLSelectElement.h"
+
+#include "AXObjectCache.h"
+#include "Attribute.h"
+#include "EventNames.h"
+#include "HTMLNames.h"
+#include "HTMLOptionElement.h"
+#include "HTMLOptionsCollection.h"
+#include "RenderListBox.h"
+#include "RenderMenuList.h"
+#include "ScriptEventListener.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+// Upper limit agreed upon with representatives of Opera and Mozilla.
+static const unsigned maxSelectItems = 10000;
+
+HTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLFormControlElementWithState(tagName, document, form)
+{
+ ASSERT(hasTagName(selectTag) || hasTagName(keygenTag));
+}
+
+PassRefPtr<HTMLSelectElement> HTMLSelectElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ ASSERT(tagName.matches(selectTag));
+ return adoptRef(new HTMLSelectElement(tagName, document, form));
+}
+
+void HTMLSelectElement::recalcStyle(StyleChange change)
+{
+ HTMLFormControlElementWithState::recalcStyle(change);
+}
+
+const AtomicString& HTMLSelectElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, selectMultiple, ("select-multiple"));
+ DEFINE_STATIC_LOCAL(const AtomicString, selectOne, ("select-one"));
+ return m_data.multiple() ? selectMultiple : selectOne;
+}
+
+int HTMLSelectElement::selectedIndex() const
+{
+ return SelectElement::selectedIndex(m_data, this);
+}
+
+void HTMLSelectElement::deselectItems(HTMLOptionElement* excludeElement)
+{
+ SelectElement::deselectItems(m_data, this, excludeElement);
+ setNeedsValidityCheck();
+}
+
+void HTMLSelectElement::setSelectedIndex(int optionIndex, bool deselect)
+{
+ SelectElement::setSelectedIndex(m_data, this, optionIndex, deselect, false, false);
+ setNeedsValidityCheck();
+}
+
+void HTMLSelectElement::setSelectedIndexByUser(int optionIndex, bool deselect, bool fireOnChangeNow, bool allowMultipleSelection)
+{
+ // List box selects can fire onchange events through user interaction, such as
+ // mousedown events. This allows that same behavior programmatically.
+ if (!m_data.usesMenuList()) {
+ updateSelectedState(m_data, this, optionIndex, allowMultipleSelection, false);
+ setNeedsValidityCheck();
+ if (fireOnChangeNow)
+ listBoxOnChange();
+ return;
+ }
+
+ // Bail out if this index is already the selected one, to avoid running unnecessary JavaScript that can mess up
+ // autofill, when there is no actual change (see https://bugs.webkit.org/show_bug.cgi?id=35256 and rdar://7467917 ).
+ // Perhaps this logic could be moved into SelectElement, but some callers of SelectElement::setSelectedIndex()
+ // seem to expect it to fire its change event even when the index was already selected.
+ if (optionIndex == selectedIndex())
+ return;
+
+ SelectElement::setSelectedIndex(m_data, this, optionIndex, deselect, fireOnChangeNow, true);
+ setNeedsValidityCheck();
+}
+
+bool HTMLSelectElement::hasPlaceholderLabelOption() const
+{
+ // The select element has no placeholder label option if it has an attribute "multiple" specified or a display size of non-1.
+ //
+ // The condition "size() > 1" is actually not compliant with the HTML5 spec as of Dec 3, 2010. "size() != 1" is correct.
+ // Using "size() > 1" here because size() may be 0 in WebKit.
+ // See the discussion at https://bugs.webkit.org/show_bug.cgi?id=43887
+ //
+ // "0 size()" happens when an attribute "size" is absent or an invalid size attribute is specified.
+ // In this case, the display size should be assumed as the default.
+ // The default display size is 1 for non-multiple select elements, and 4 for multiple select elements.
+ //
+ // Finally, if size() == 0 and non-multiple, the display size can be assumed as 1.
+ if (multiple() || size() > 1)
+ return false;
+
+ int listIndex = optionToListIndex(0);
+ ASSERT(listIndex >= 0);
+ if (listIndex < 0)
+ return false;
+ HTMLOptionElement* option = static_cast<HTMLOptionElement*>(listItems()[listIndex]);
+ return !option->disabled() && !listIndex && option->value().isEmpty();
+}
+
+bool HTMLSelectElement::valueMissing() const
+{
+ if (!isRequiredFormControl())
+ return false;
+
+ int firstSelectionIndex = selectedIndex();
+
+ // If a non-placeholer label option is selected (firstSelectionIndex > 0), it's not value-missing.
+ return firstSelectionIndex < 0 || (!firstSelectionIndex && hasPlaceholderLabelOption());
+}
+
+void HTMLSelectElement::listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow)
+{
+ if (!multiple())
+ setSelectedIndexByUser(listToOptionIndex(listIndex), true, fireOnChangeNow);
+ else {
+ updateSelectedState(m_data, this, listIndex, allowMultiplySelections, shift);
+ setNeedsValidityCheck();
+ if (fireOnChangeNow)
+ listBoxOnChange();
+ }
+}
+
+int HTMLSelectElement::activeSelectionStartListIndex() const
+{
+ if (m_data.activeSelectionAnchorIndex() >= 0)
+ return m_data.activeSelectionAnchorIndex();
+ return optionToListIndex(selectedIndex());
+}
+
+int HTMLSelectElement::activeSelectionEndListIndex() const
+{
+ if (m_data.activeSelectionEndIndex() >= 0)
+ return m_data.activeSelectionEndIndex();
+ return SelectElement::lastSelectedListIndex(m_data, this);
+}
+
+unsigned HTMLSelectElement::length() const
+{
+ return SelectElement::optionCount(m_data, this);
+}
+
+void HTMLSelectElement::add(HTMLElement* element, HTMLElement* before, ExceptionCode& ec)
+{
+ RefPtr<HTMLElement> protectNewChild(element); // make sure the element is ref'd and deref'd so we don't leak it
+
+ if (!element || !(element->hasLocalName(optionTag) || element->hasLocalName(hrTag)))
+ return;
+
+ insertBefore(element, before, ec);
+ setNeedsValidityCheck();
+}
+
+void HTMLSelectElement::remove(int optionIndex)
+{
+ int listIndex = optionToListIndex(optionIndex);
+ if (listIndex < 0)
+ return;
+
+ ExceptionCode ec;
+ listItems()[listIndex]->remove(ec);
+}
+
+void HTMLSelectElement::remove(HTMLOptionElement* option)
+{
+ if (option->ownerSelectElement() != this)
+ return;
+
+ ExceptionCode ec;
+ option->remove(ec);
+}
+
+String HTMLSelectElement::value()
+{
+ const Vector<Element*>& items = listItems();
+ for (unsigned i = 0; i < items.size(); i++) {
+ if (items[i]->hasLocalName(optionTag) && static_cast<HTMLOptionElement*>(items[i])->selected())
+ return static_cast<HTMLOptionElement*>(items[i])->value();
+ }
+ return "";
+}
+
+void HTMLSelectElement::setValue(const String &value)
+{
+ if (value.isNull())
+ return;
+ // find the option with value() matching the given parameter
+ // and make it the current selection.
+ const Vector<Element*>& items = listItems();
+ unsigned optionIndex = 0;
+ for (unsigned i = 0; i < items.size(); i++) {
+ if (items[i]->hasLocalName(optionTag)) {
+ if (static_cast<HTMLOptionElement*>(items[i])->value() == value) {
+ setSelectedIndex(optionIndex, true);
+ return;
+ }
+ optionIndex++;
+ }
+ }
+}
+
+bool HTMLSelectElement::saveFormControlState(String& value) const
+{
+ return SelectElement::saveFormControlState(m_data, this, value);
+}
+
+void HTMLSelectElement::restoreFormControlState(const String& state)
+{
+ SelectElement::restoreFormControlState(m_data, this, state);
+ setNeedsValidityCheck();
+}
+
+void HTMLSelectElement::parseMappedAttribute(Attribute* attr)
+{
+ bool oldUsesMenuList = m_data.usesMenuList();
+ if (attr->name() == sizeAttr) {
+ int oldSize = m_data.size();
+ // Set the attribute value to a number.
+ // This is important since the style rules for this attribute can determine the appearance property.
+ int size = attr->value().toInt();
+ String attrSize = String::number(size);
+ if (attrSize != attr->value())
+ attr->setValue(attrSize);
+ size = max(size, 1);
+
+ // Ensure that we've determined selectedness of the items at least once prior to changing the size.
+ if (oldSize != size)
+ recalcListItemsIfNeeded();
+
+ m_data.setSize(size);
+ setNeedsValidityCheck();
+ if ((oldUsesMenuList != m_data.usesMenuList() || (!oldUsesMenuList && m_data.size() != oldSize)) && attached()) {
+ detach();
+ attach();
+ setRecalcListItems();
+ }
+ } else if (attr->name() == multipleAttr)
+ SelectElement::parseMultipleAttribute(m_data, this, attr);
+ else if (attr->name() == accesskeyAttr) {
+ // FIXME: ignore for the moment
+ } else if (attr->name() == alignAttr) {
+ // Don't map 'align' attribute. This matches what Firefox, Opera and IE do.
+ // See http://bugs.webkit.org/show_bug.cgi?id=12072
+ } else if (attr->name() == onchangeAttr) {
+ setAttributeEventListener(eventNames().changeEvent, createAttributeEventListener(this, attr));
+ } else
+ HTMLFormControlElementWithState::parseMappedAttribute(attr);
+}
+
+bool HTMLSelectElement::isKeyboardFocusable(KeyboardEvent* event) const
+{
+ if (renderer())
+ return isFocusable();
+ return HTMLFormControlElementWithState::isKeyboardFocusable(event);
+}
+
+bool HTMLSelectElement::isMouseFocusable() const
+{
+ if (renderer())
+ return isFocusable();
+ return HTMLFormControlElementWithState::isMouseFocusable();
+}
+
+bool HTMLSelectElement::canSelectAll() const
+{
+ return !m_data.usesMenuList();
+}
+
+void HTMLSelectElement::selectAll()
+{
+ SelectElement::selectAll(m_data, this);
+ setNeedsValidityCheck();
+}
+
+RenderObject* HTMLSelectElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ if (m_data.usesMenuList())
+ return new (arena) RenderMenuList(this);
+ return new (arena) RenderListBox(this);
+}
+
+bool HTMLSelectElement::appendFormData(FormDataList& list, bool)
+{
+ return SelectElement::appendFormData(m_data, this, list);
+}
+
+int HTMLSelectElement::optionToListIndex(int optionIndex) const
+{
+ return SelectElement::optionToListIndex(m_data, this, optionIndex);
+}
+
+int HTMLSelectElement::listToOptionIndex(int listIndex) const
+{
+ return SelectElement::listToOptionIndex(m_data, this, listIndex);
+}
+
+PassRefPtr<HTMLOptionsCollection> HTMLSelectElement::options()
+{
+ return HTMLOptionsCollection::create(this);
+}
+
+void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
+{
+ SelectElement::recalcListItems(const_cast<SelectElementData&>(m_data), this, updateSelectedStates);
+}
+
+void HTMLSelectElement::recalcListItemsIfNeeded()
+{
+ if (m_data.shouldRecalcListItems())
+ recalcListItems();
+}
+
+void HTMLSelectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ setRecalcListItems();
+ setNeedsValidityCheck();
+ HTMLFormControlElementWithState::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+
+ if (AXObjectCache::accessibilityEnabled() && renderer())
+ renderer()->document()->axObjectCache()->childrenChanged(renderer());
+}
+
+void HTMLSelectElement::setRecalcListItems()
+{
+ SelectElement::setRecalcListItems(m_data, this);
+
+ if (!inDocument())
+ m_collectionInfo.reset();
+}
+
+void HTMLSelectElement::reset()
+{
+ SelectElement::reset(m_data, this);
+ setNeedsValidityCheck();
+}
+
+void HTMLSelectElement::dispatchFocusEvent()
+{
+ SelectElement::dispatchFocusEvent(m_data, this);
+ HTMLFormControlElementWithState::dispatchFocusEvent();
+}
+
+void HTMLSelectElement::dispatchBlurEvent()
+{
+ SelectElement::dispatchBlurEvent(m_data, this);
+ HTMLFormControlElementWithState::dispatchBlurEvent();
+}
+
+void HTMLSelectElement::defaultEventHandler(Event* event)
+{
+ SelectElement::defaultEventHandler(m_data, this, event, form());
+ if (event->defaultHandled())
+ return;
+ HTMLFormControlElementWithState::defaultEventHandler(event);
+}
+
+void HTMLSelectElement::setActiveSelectionAnchorIndex(int index)
+{
+ SelectElement::setActiveSelectionAnchorIndex(m_data, this, index);
+}
+
+void HTMLSelectElement::setActiveSelectionEndIndex(int index)
+{
+ SelectElement::setActiveSelectionEndIndex(m_data, index);
+}
+
+void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions)
+{
+ SelectElement::updateListBoxSelection(m_data, this, deselectOtherOptions);
+ setNeedsValidityCheck();
+}
+
+void HTMLSelectElement::menuListOnChange()
+{
+ SelectElement::menuListOnChange(m_data, this);
+}
+
+void HTMLSelectElement::listBoxOnChange()
+{
+ SelectElement::listBoxOnChange(m_data, this);
+}
+
+void HTMLSelectElement::saveLastSelection()
+{
+ SelectElement::saveLastSelection(m_data, this);
+}
+
+void HTMLSelectElement::accessKeyAction(bool sendToAnyElement)
+{
+ focus();
+ dispatchSimulatedClick(0, sendToAnyElement);
+}
+
+void HTMLSelectElement::accessKeySetSelectedIndex(int index)
+{
+ SelectElement::accessKeySetSelectedIndex(m_data, this, index);
+}
+
+void HTMLSelectElement::setMultiple(bool multiple)
+{
+ setAttribute(multipleAttr, multiple ? "" : 0);
+}
+
+void HTMLSelectElement::setSize(int size)
+{
+ setAttribute(sizeAttr, String::number(size));
+}
+
+Node* HTMLSelectElement::namedItem(const AtomicString& name)
+{
+ return options()->namedItem(name);
+}
+
+Node* HTMLSelectElement::item(unsigned index)
+{
+ return options()->item(index);
+}
+
+void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, ExceptionCode& ec)
+{
+ ec = 0;
+ if (index > maxSelectItems - 1)
+ index = maxSelectItems - 1;
+ int diff = index - length();
+ HTMLElement* before = 0;
+ // out of array bounds ? first insert empty dummies
+ if (diff > 0) {
+ setLength(index, ec);
+ // replace an existing entry ?
+ } else if (diff < 0) {
+ before = static_cast<HTMLElement*>(options()->item(index+1));
+ remove(index);
+ }
+ // finally add the new element
+ if (!ec) {
+ add(option, before, ec);
+ if (diff >= 0 && option->selected())
+ setSelectedIndex(index, !m_data.multiple());
+ }
+}
+
+void HTMLSelectElement::setLength(unsigned newLen, ExceptionCode& ec)
+{
+ ec = 0;
+ if (newLen > maxSelectItems)
+ newLen = maxSelectItems;
+ int diff = length() - newLen;
+
+ if (diff < 0) { // add dummy elements
+ do {
+ RefPtr<Element> option = document()->createElement(optionTag, false);
+ ASSERT(option);
+ add(static_cast<HTMLElement*>(option.get()), 0, ec);
+ if (ec)
+ break;
+ } while (++diff);
+ } else {
+ const Vector<Element*>& items = listItems();
+
+ // Removing children fires mutation events, which might mutate the DOM further, so we first copy out a list
+ // 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 (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 (size_t i = 0; i < itemsToRemove.size(); ++i) {
+ Element* item = itemsToRemove[i].get();
+ if (item->parentNode()) {
+ item->parentNode()->removeChild(item, ec);
+ }
+ }
+ }
+ setNeedsValidityCheck();
+}
+
+void HTMLSelectElement::scrollToSelection()
+{
+ SelectElement::scrollToSelection(m_data, this);
+}
+
+void HTMLSelectElement::insertedIntoTree(bool deep)
+{
+ SelectElement::insertedIntoTree(m_data, this);
+ HTMLFormControlElementWithState::insertedIntoTree(deep);
+}
+
+bool HTMLSelectElement::isRequiredFormControl() const
+{
+ return required();
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLSelectElement.h b/Source/WebCore/html/HTMLSelectElement.h
new file mode 100644
index 0000000..a22df02
--- /dev/null
+++ b/Source/WebCore/html/HTMLSelectElement.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * 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, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLSelectElement_h
+#define HTMLSelectElement_h
+
+#include "CollectionCache.h"
+#include "HTMLFormControlElement.h"
+#include "SelectElement.h"
+
+namespace WebCore {
+
+class HTMLOptionElement;
+class HTMLOptionsCollection;
+
+class HTMLSelectElement : public HTMLFormControlElementWithState, public SelectElement {
+public:
+ static PassRefPtr<HTMLSelectElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+
+ virtual int selectedIndex() const;
+ virtual void setSelectedIndex(int index, bool deselect = true);
+ virtual void setSelectedIndexByUser(int index, bool deselect = true, bool fireOnChangeNow = false, bool allowMultipleSelection = false);
+
+ // For ValidityState
+ bool valueMissing() const;
+
+ unsigned length() const;
+
+ virtual int size() const { return m_data.size(); }
+ virtual bool multiple() const { return m_data.multiple(); }
+
+ void add(HTMLElement*, HTMLElement* beforeElement, ExceptionCode&);
+ void remove(int index);
+ void remove(HTMLOptionElement*);
+
+ String value();
+ void setValue(const String&);
+
+ PassRefPtr<HTMLOptionsCollection> options();
+
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+
+ void setRecalcListItems();
+ void recalcListItemsIfNeeded();
+
+ virtual const Vector<Element*>& listItems() const { return m_data.listItems(this); }
+
+ virtual void accessKeyAction(bool sendToAnyElement);
+ void accessKeySetSelectedIndex(int);
+
+ void setMultiple(bool);
+
+ void setSize(int);
+
+ void setOption(unsigned index, HTMLOptionElement*, ExceptionCode&);
+ void setLength(unsigned, ExceptionCode&);
+
+ Node* namedItem(const AtomicString& name);
+ Node* item(unsigned index);
+
+ CollectionCache* collectionInfo() { m_collectionInfo.checkConsistency(); return &m_collectionInfo; }
+
+ void scrollToSelection();
+
+ void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true);
+
+ virtual void updateValidity() { setNeedsValidityCheck(); }
+
+protected:
+ HTMLSelectElement(const QualifiedName&, Document*, HTMLFormElement*);
+
+private:
+ virtual const AtomicString& formControlType() const;
+
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const;
+ virtual bool isMouseFocusable() const;
+ virtual bool canSelectAll() const;
+ virtual void selectAll();
+
+ virtual void recalcStyle(StyleChange);
+
+ virtual void dispatchFocusEvent();
+ virtual void dispatchBlurEvent();
+
+ virtual bool canStartSelection() const { return false; }
+
+ virtual bool isEnumeratable() const { return true; }
+
+ virtual bool saveFormControlState(String& value) const;
+ virtual void restoreFormControlState(const String&);
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle *);
+ virtual bool appendFormData(FormDataList&, bool);
+
+ virtual int optionToListIndex(int optionIndex) const;
+ virtual int listToOptionIndex(int listIndex) const;
+
+ virtual void reset();
+
+ virtual void defaultEventHandler(Event*);
+
+ virtual void setActiveSelectionAnchorIndex(int index);
+ virtual void setActiveSelectionEndIndex(int index);
+ virtual void updateListBoxSelection(bool deselectOtherOptions);
+ virtual void listBoxOnChange();
+ virtual void menuListOnChange();
+
+ virtual int activeSelectionStartListIndex() const;
+ virtual int activeSelectionEndListIndex() const;
+
+ void recalcListItems(bool updateSelectedStates = true) const;
+
+ void deselectItems(HTMLOptionElement* excludeElement = 0);
+ void typeAheadFind(KeyboardEvent*);
+ void saveLastSelection();
+
+ virtual void insertedIntoTree(bool);
+
+ virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
+ virtual bool isRequiredFormControl() const;
+
+ bool hasPlaceholderLabelOption() const;
+
+ SelectElementData m_data;
+ CollectionCache m_collectionInfo;
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLSelectElement.idl b/Source/WebCore/html/HTMLSelectElement.idl
new file mode 100644
index 0000000..f5ac69b
--- /dev/null
+++ b/Source/WebCore/html/HTMLSelectElement.idl
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ HasIndexGetter,
+ HasCustomIndexSetter
+ ] HTMLSelectElement : HTMLElement {
+ readonly attribute DOMString type;
+ attribute long selectedIndex;
+ attribute [ConvertNullToNullString] DOMString value;
+
+ // Modified in DOM Level 2:
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+ readonly attribute long length;
+#else
+ attribute unsigned long length setter raises (DOMException);
+#endif
+
+ readonly attribute HTMLFormElement form;
+ readonly attribute ValidityState validity;
+ readonly attribute boolean willValidate;
+ readonly attribute DOMString validationMessage;
+ boolean checkValidity();
+ void setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error);
+
+ // Modified in DOM Level 2:
+ readonly attribute HTMLOptionsCollection options;
+
+ attribute [Reflect] boolean disabled;
+ attribute [Reflect] boolean autofocus;
+ attribute boolean multiple;
+ attribute [ConvertNullToNullString] DOMString name;
+ attribute [Reflect] boolean required;
+ attribute long size;
+
+ [OldStyleObjC] void add(in HTMLElement element, in HTMLElement before) raises(DOMException);
+
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ // In JavaScript, we support both option index and option object parameters.
+ // As of this writing this cannot be auto-generated.
+ [Custom] void remove(/* indexOrOption */);
+#else
+ void remove(in long index);
+#endif
+
+ // These methods are not in DOM Level 2 IDL, but are mentioned in the standard:
+ // "The contained options can be directly accessed through the select element as a collection."
+ Node item(in [IsIndex] unsigned long index);
+ Node namedItem(in DOMString name);
+ readonly attribute NodeList labels;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLSourceElement.cpp b/Source/WebCore/html/HTMLSourceElement.cpp
new file mode 100644
index 0000000..59b3882
--- /dev/null
+++ b/Source/WebCore/html/HTMLSourceElement.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 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
+ * 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 "HTMLSourceElement.h"
+
+#include "Event.h"
+#include "EventNames.h"
+#include "HTMLDocument.h"
+#include "HTMLMediaElement.h"
+#include "HTMLNames.h"
+#include "Logging.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLSourceElement::HTMLSourceElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , m_errorEventTimer(this, &HTMLSourceElement::errorEventTimerFired)
+{
+ LOG(Media, "HTMLSourceElement::HTMLSourceElement - %p", this);
+ ASSERT(hasTagName(sourceTag));
+}
+
+PassRefPtr<HTMLSourceElement> HTMLSourceElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLSourceElement(tagName, document));
+}
+
+void HTMLSourceElement::insertedIntoTree(bool deep)
+{
+ HTMLElement::insertedIntoTree(deep);
+ if (parentNode() && (parentNode()->hasTagName(audioTag) || parentNode()->hasTagName(videoTag)))
+ static_cast<HTMLMediaElement*>(parentNode())->sourceWasAdded(this);
+}
+
+void HTMLSourceElement::willRemove()
+{
+ if (parentNode() && (parentNode()->hasTagName(audioTag) || parentNode()->hasTagName(videoTag)))
+ static_cast<HTMLMediaElement*>(parentNode())->sourceWillBeRemoved(this);
+ HTMLElement::willRemove();
+}
+
+void HTMLSourceElement::setSrc(const String& url)
+{
+ setAttribute(srcAttr, url);
+}
+
+String HTMLSourceElement::media() const
+{
+ return getAttribute(mediaAttr);
+}
+
+void HTMLSourceElement::setMedia(const String& media)
+{
+ setAttribute(mediaAttr, media);
+}
+
+String HTMLSourceElement::type() const
+{
+ return getAttribute(typeAttr);
+}
+
+void HTMLSourceElement::setType(const String& type)
+{
+ setAttribute(typeAttr, type);
+}
+
+void HTMLSourceElement::scheduleErrorEvent()
+{
+ LOG(Media, "HTMLSourceElement::scheduleErrorEvent - %p", this);
+ if (m_errorEventTimer.isActive())
+ return;
+
+ m_errorEventTimer.startOneShot(0);
+}
+
+void HTMLSourceElement::cancelPendingErrorEvent()
+{
+ LOG(Media, "HTMLSourceElement::cancelPendingErrorEvent - %p", this);
+ m_errorEventTimer.stop();
+}
+
+void HTMLSourceElement::errorEventTimerFired(Timer<HTMLSourceElement>*)
+{
+ LOG(Media, "HTMLSourceElement::errorEventTimerFired - %p", this);
+ dispatchEvent(Event::create(eventNames().errorEvent, false, true));
+}
+
+bool HTMLSourceElement::isURLAttribute(Attribute* attribute) const
+{
+ return attribute->name() == srcAttr;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/html/HTMLSourceElement.h b/Source/WebCore/html/HTMLSourceElement.h
new file mode 100644
index 0000000..cc1e5d7
--- /dev/null
+++ b/Source/WebCore/html/HTMLSourceElement.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 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
+ * 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 HTMLSourceElement_h
+#define HTMLSourceElement_h
+
+#if ENABLE(VIDEO)
+
+#include "HTMLElement.h"
+#include "Timer.h"
+
+namespace WebCore {
+
+class HTMLSourceElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLSourceElement> create(const QualifiedName&, Document*);
+
+ String media() const;
+ String type() const;
+ void setSrc(const String&);
+ void setMedia(const String&);
+ void setType(const String&);
+
+ void scheduleErrorEvent();
+ void cancelPendingErrorEvent();
+
+private:
+ HTMLSourceElement(const QualifiedName&, Document*);
+
+ virtual void insertedIntoTree(bool);
+ virtual void willRemove();
+ virtual bool isURLAttribute(Attribute*) const;
+
+ void errorEventTimerFired(Timer<HTMLSourceElement>*);
+
+ Timer<HTMLSourceElement> m_errorEventTimer;
+};
+
+} //namespace
+
+#endif
+#endif
diff --git a/Source/WebCore/html/HTMLSourceElement.idl b/Source/WebCore/html/HTMLSourceElement.idl
new file mode 100644
index 0000000..dbd6d6a
--- /dev/null
+++ b/Source/WebCore/html/HTMLSourceElement.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007, 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,
+ * 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.
+ */
+
+module html {
+interface [Conditional=VIDEO] HTMLSourceElement : HTMLElement {
+ attribute [Reflect, URL] DOMString src;
+ attribute DOMString type;
+ attribute DOMString media;
+};
+}
diff --git a/Source/WebCore/html/HTMLStyleElement.cpp b/Source/WebCore/html/HTMLStyleElement.cpp
new file mode 100644
index 0000000..7c2512b
--- /dev/null
+++ b/Source/WebCore/html/HTMLStyleElement.cpp
@@ -0,0 +1,107 @@
+/*
+ * 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, 2010 Apple Inc. All rights reserved.
+ * (C) 2007 Rob Buis (buis@kde.org)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLStyleElement.h"
+
+#include "Attribute.h"
+#include "Document.h"
+#include "HTMLNames.h"
+#include "ScriptableDocumentParser.h"
+#include "ScriptEventListener.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLStyleElement::HTMLStyleElement(const QualifiedName& tagName, Document* document, bool createdByParser)
+ : HTMLElement(tagName, document)
+ , StyleElement(document, createdByParser)
+{
+ ASSERT(hasTagName(styleTag));
+}
+
+HTMLStyleElement::~HTMLStyleElement()
+{
+ if (m_sheet)
+ m_sheet->clearOwnerNode();
+}
+
+PassRefPtr<HTMLStyleElement> HTMLStyleElement::create(const QualifiedName& tagName, Document* document, bool createdByParser)
+{
+ return adoptRef(new HTMLStyleElement(tagName, document, createdByParser));
+}
+
+void HTMLStyleElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == titleAttr && m_sheet)
+ m_sheet->setTitle(attr->value());
+ else if (attr->name() == onbeforeprocessAttr)
+ setAttributeEventListener(eventNames().beforeprocessEvent, createAttributeEventListener(this, attr));
+ else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+void HTMLStyleElement::finishParsingChildren()
+{
+ StyleElement::finishParsingChildren(this);
+ HTMLElement::finishParsingChildren();
+}
+
+void HTMLStyleElement::insertedIntoDocument()
+{
+ HTMLElement::insertedIntoDocument();
+ StyleElement::insertedIntoDocument(document(), this);
+}
+
+void HTMLStyleElement::removedFromDocument()
+{
+ HTMLElement::removedFromDocument();
+ StyleElement::removedFromDocument(document(), this);
+}
+
+void HTMLStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ StyleElement::childrenChanged(this);
+ HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+}
+
+const AtomicString& HTMLStyleElement::media() const
+{
+ return getAttribute(mediaAttr);
+}
+
+const AtomicString& HTMLStyleElement::type() const
+{
+ return getAttribute(typeAttr);
+}
+
+void HTMLStyleElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+{
+ HTMLElement::addSubresourceAttributeURLs(urls);
+
+ if (StyleSheet* styleSheet = const_cast<HTMLStyleElement*>(this)->sheet())
+ styleSheet->addSubresourceStyleURLs(urls);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLStyleElement.h b/Source/WebCore/html/HTMLStyleElement.h
new file mode 100644
index 0000000..3d6958f
--- /dev/null
+++ b/Source/WebCore/html/HTMLStyleElement.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLStyleElement_h
+#define HTMLStyleElement_h
+
+#include "HTMLElement.h"
+#include "StyleElement.h"
+
+namespace WebCore {
+
+class StyleSheet;
+
+class HTMLStyleElement : public HTMLElement, private StyleElement {
+public:
+ static PassRefPtr<HTMLStyleElement> create(const QualifiedName&, Document*, bool createdByParser);
+ virtual ~HTMLStyleElement();
+
+ void setType(const AtomicString&);
+
+ using StyleElement::sheet;
+
+private:
+ HTMLStyleElement(const QualifiedName&, Document*, bool createdByParser);
+
+ // overload from HTMLElement
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+
+ virtual void finishParsingChildren();
+
+ virtual bool isLoading() const { return StyleElement::isLoading(); }
+ virtual bool sheetLoaded() { return StyleElement::sheetLoaded(document()); }
+
+ virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+
+ virtual const AtomicString& media() const;
+ virtual const AtomicString& type() const;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLStyleElement.idl b/Source/WebCore/html/HTMLStyleElement.idl
new file mode 100644
index 0000000..d78e9d3
--- /dev/null
+++ b/Source/WebCore/html/HTMLStyleElement.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [CustomMarkFunction] HTMLStyleElement : HTMLElement {
+ attribute [Reflect] boolean disabled;
+ attribute [Reflect] DOMString media;
+ attribute [Reflect] DOMString type;
+
+ // DOM Level 2 Style
+ readonly attribute StyleSheet sheet;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLTableCaptionElement.cpp b/Source/WebCore/html/HTMLTableCaptionElement.cpp
new file mode 100644
index 0000000..b726df6
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableCaptionElement.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLTableCaptionElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLTableCaptionElement::HTMLTableCaptionElement(const QualifiedName& tagName, Document* document)
+ : HTMLTablePartElement(tagName, document)
+{
+ ASSERT(hasTagName(captionTag));
+}
+
+PassRefPtr<HTMLTableCaptionElement> HTMLTableCaptionElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLTableCaptionElement(tagName, document));
+}
+
+bool HTMLTableCaptionElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == alignAttr) {
+ result = eCaption;
+ return false;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLTableCaptionElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == alignAttr) {
+ if (!attr->value().isEmpty())
+ addCSSProperty(attr, CSSPropertyCaptionSide, attr->value());
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLTableCaptionElement.h b/Source/WebCore/html/HTMLTableCaptionElement.h
new file mode 100644
index 0000000..a2dd2fa
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableCaptionElement.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLTableCaptionElement_h
+#define HTMLTableCaptionElement_h
+
+#include "HTMLTablePartElement.h"
+
+namespace WebCore {
+
+class HTMLTableCaptionElement : public HTMLTablePartElement {
+public:
+ static PassRefPtr<HTMLTableCaptionElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLTableCaptionElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLTableCaptionElement.idl b/Source/WebCore/html/HTMLTableCaptionElement.idl
new file mode 100644
index 0000000..c56c456
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableCaptionElement.idl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ GenerateNativeConverter
+ ] HTMLTableCaptionElement : HTMLElement {
+ attribute [Reflect] DOMString align;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLTableCellElement.cpp b/Source/WebCore/html/HTMLTableCellElement.cpp
new file mode 100644
index 0000000..850178a
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableCellElement.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLTableCellElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "HTMLNames.h"
+#include "HTMLTableElement.h"
+#include "RenderTableCell.h"
+#ifdef ANDROID_LAYOUT
+#include "Document.h"
+#include "Frame.h"
+#include "Settings.h"
+#endif
+
+using std::max;
+using std::min;
+
+namespace WebCore {
+
+// Clamp rowspan at 8k to match Firefox.
+static const int maxRowspan = 8190;
+
+using namespace HTMLNames;
+
+inline HTMLTableCellElement::HTMLTableCellElement(const QualifiedName& tagName, Document* document)
+ : HTMLTablePartElement(tagName, document)
+ , m_rowSpan(1)
+ , m_colSpan(1)
+{
+}
+
+PassRefPtr<HTMLTableCellElement> HTMLTableCellElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLTableCellElement(tagName, document));
+}
+
+int HTMLTableCellElement::cellIndex() const
+{
+ int index = 0;
+ for (const Node * node = previousSibling(); node; node = node->previousSibling()) {
+ if (node->hasTagName(tdTag) || node->hasTagName(thTag))
+ index++;
+ }
+
+ return index;
+}
+
+bool HTMLTableCellElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == nowrapAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ if (attrName == widthAttr ||
+ attrName == heightAttr) {
+ result = eCell; // Because of the quirky behavior of ignoring 0 values, cells are special.
+ return false;
+ }
+
+ return HTMLTablePartElement::mapToEntry(attrName, result);
+}
+
+void HTMLTableCellElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == rowspanAttr) {
+ m_rowSpan = max(1, min(attr->value().toInt(), maxRowspan));
+ if (renderer() && renderer()->isTableCell())
+ toRenderTableCell(renderer())->updateFromElement();
+ } else if (attr->name() == colspanAttr) {
+ m_colSpan = max(1, attr->value().toInt());
+ if (renderer() && renderer()->isTableCell())
+ toRenderTableCell(renderer())->updateFromElement();
+ } else if (attr->name() == nowrapAttr) {
+#ifdef ANDROID_LAYOUT
+ if (!(document()->frame()) || document()->frame()->settings()->layoutAlgorithm() != Settings::kLayoutSSR)
+#endif
+ if (!attr->isNull())
+ addCSSProperty(attr, CSSPropertyWhiteSpace, CSSValueWebkitNowrap);
+ } else if (attr->name() == widthAttr) {
+ if (!attr->value().isEmpty()) {
+ int widthInt = attr->value().toInt();
+ if (widthInt > 0) // width="0" is ignored for compatibility with WinIE.
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
+ }
+ } else if (attr->name() == heightAttr) {
+ if (!attr->value().isEmpty()) {
+ int heightInt = attr->value().toInt();
+ if (heightInt > 0) // height="0" is ignored for compatibility with WinIE.
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
+ }
+ } else
+ HTMLTablePartElement::parseMappedAttribute(attr);
+}
+
+// used by table cells to share style decls created by the enclosing table.
+void HTMLTableCellElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
+{
+ ContainerNode* p = parentNode();
+ while (p && !p->hasTagName(tableTag))
+ p = p->parentNode();
+ if (!p)
+ return;
+ static_cast<HTMLTableElement*>(p)->addSharedCellDecls(results);
+}
+
+bool HTMLTableCellElement::isURLAttribute(Attribute *attr) const
+{
+ return attr->name() == backgroundAttr;
+}
+
+String HTMLTableCellElement::abbr() const
+{
+ return getAttribute(abbrAttr);
+}
+
+String HTMLTableCellElement::axis() const
+{
+ return getAttribute(axisAttr);
+}
+
+void HTMLTableCellElement::setColSpan(int n)
+{
+ setAttribute(colspanAttr, String::number(n));
+}
+
+String HTMLTableCellElement::headers() const
+{
+ return getAttribute(headersAttr);
+}
+
+void HTMLTableCellElement::setRowSpan(int n)
+{
+ setAttribute(rowspanAttr, String::number(n));
+}
+
+String HTMLTableCellElement::scope() const
+{
+ return getAttribute(scopeAttr);
+}
+
+void HTMLTableCellElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+{
+ HTMLTablePartElement::addSubresourceAttributeURLs(urls);
+
+ addSubresourceURL(urls, document()->completeURL(getAttribute(backgroundAttr)));
+}
+
+HTMLTableCellElement* HTMLTableCellElement::cellAbove() const
+{
+ RenderObject* cellRenderer = renderer();
+ if (!cellRenderer)
+ return 0;
+ if (!cellRenderer->isTableCell())
+ return 0;
+
+ RenderTableCell* tableCellRenderer = toRenderTableCell(cellRenderer);
+ RenderTableCell* cellAboveRenderer = tableCellRenderer->table()->cellAbove(tableCellRenderer);
+ if (!cellAboveRenderer)
+ return 0;
+
+ return static_cast<HTMLTableCellElement*>(cellAboveRenderer->node());
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLTableCellElement.h b/Source/WebCore/html/HTMLTableCellElement.h
new file mode 100644
index 0000000..9a684f2
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableCellElement.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLTableCellElement_h
+#define HTMLTableCellElement_h
+
+#include "HTMLTablePartElement.h"
+
+namespace WebCore {
+
+class HTMLTableCellElement : public HTMLTablePartElement {
+public:
+ static PassRefPtr<HTMLTableCellElement> create(const QualifiedName&, Document*);
+
+ int cellIndex() const;
+
+ int colSpan() const { return m_colSpan; }
+ int rowSpan() const { return m_rowSpan; }
+
+ void setCellIndex(int);
+
+ String abbr() const;
+ String axis() const;
+ void setColSpan(int);
+ String headers() const;
+ void setRowSpan(int);
+ String scope() const;
+
+ HTMLTableCellElement* cellAbove() const;
+
+private:
+ HTMLTableCellElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ // used by table cells to share style decls created by the enclosing table.
+ virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
+ virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
+
+ virtual bool isURLAttribute(Attribute*) const;
+
+ virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+
+ int m_rowSpan;
+ int m_colSpan;
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLTableCellElement.idl b/Source/WebCore/html/HTMLTableCellElement.idl
new file mode 100644
index 0000000..ae286f4
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableCellElement.idl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLTableCellElement : HTMLElement {
+ readonly attribute long cellIndex;
+ attribute [Reflect] DOMString abbr;
+ attribute [Reflect] DOMString align;
+ attribute [Reflect] DOMString axis;
+ attribute [Reflect] DOMString bgColor;
+ attribute [Reflect=char] DOMString ch;
+ attribute [Reflect=charoff] DOMString chOff;
+ attribute long colSpan;
+ attribute [Reflect] DOMString headers;
+ attribute [Reflect] DOMString height;
+ attribute [Reflect] boolean noWrap;
+ attribute long rowSpan;
+ attribute [Reflect] DOMString scope;
+ attribute [Reflect] DOMString vAlign;
+ attribute [Reflect] DOMString width;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLTableColElement.cpp b/Source/WebCore/html/HTMLTableColElement.cpp
new file mode 100644
index 0000000..96af708
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableColElement.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLTableColElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "HTMLNames.h"
+#include "HTMLTableElement.h"
+#include "RenderTableCol.h"
+#include "Text.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLTableColElement::HTMLTableColElement(const QualifiedName& tagName, Document* document)
+ : HTMLTablePartElement(tagName, document)
+ , m_span(1)
+{
+}
+
+PassRefPtr<HTMLTableColElement> HTMLTableColElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLTableColElement(tagName, document));
+}
+
+bool HTMLTableColElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == widthAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ return HTMLTablePartElement::mapToEntry(attrName, result);
+}
+
+void HTMLTableColElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == spanAttr) {
+ m_span = !attr->isNull() ? attr->value().toInt() : 1;
+ if (renderer() && renderer()->isTableCol())
+ renderer()->updateFromElement();
+ } else if (attr->name() == widthAttr) {
+ if (!attr->value().isEmpty()) {
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
+ if (renderer() && renderer()->isTableCol()) {
+ RenderTableCol* col = toRenderTableCol(renderer());
+ int newWidth = width().toInt();
+ if (newWidth != col->width())
+ col->setNeedsLayoutAndPrefWidthsRecalc();
+ }
+ }
+ } else
+ HTMLTablePartElement::parseMappedAttribute(attr);
+}
+
+// used by table columns and column groups to share style decls created by the enclosing table.
+void HTMLTableColElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
+{
+ if (!hasLocalName(colgroupTag))
+ return;
+ ContainerNode* p = parentNode();
+ while (p && !p->hasTagName(tableTag))
+ p = p->parentNode();
+ if (!p)
+ return;
+ static_cast<HTMLTableElement*>(p)->addSharedGroupDecls(false, results);
+}
+
+void HTMLTableColElement::setSpan(int n)
+{
+ setAttribute(spanAttr, String::number(n));
+}
+
+String HTMLTableColElement::width() const
+{
+ return getAttribute(widthAttr);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLTableColElement.h b/Source/WebCore/html/HTMLTableColElement.h
new file mode 100644
index 0000000..c7517d1
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableColElement.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLTableColElement_h
+#define HTMLTableColElement_h
+
+#include "HTMLTablePartElement.h"
+
+namespace WebCore {
+
+class HTMLTableColElement : public HTMLTablePartElement {
+public:
+ static PassRefPtr<HTMLTableColElement> create(const QualifiedName& tagName, Document*);
+
+ int span() const { return m_span; }
+ void setSpan(int);
+
+ String width() const;
+
+private:
+ HTMLTableColElement(const QualifiedName& tagName, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+ virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
+ virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
+
+ int m_span;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLTableColElement.idl b/Source/WebCore/html/HTMLTableColElement.idl
new file mode 100644
index 0000000..a6e6654
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableColElement.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLTableColElement : HTMLElement {
+ attribute [Reflect] DOMString align;
+ attribute [Reflect=char] DOMString ch;
+ attribute [Reflect=charoff] DOMString chOff;
+ attribute long span;
+ attribute [Reflect] DOMString vAlign;
+ attribute [Reflect] DOMString width;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLTableElement.cpp b/Source/WebCore/html/HTMLTableElement.cpp
new file mode 100644
index 0000000..e554620
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableElement.cpp
@@ -0,0 +1,665 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 2008, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLTableElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSStyleSheet.h"
+#include "CSSValueKeywords.h"
+#include "ExceptionCode.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "HTMLTableCaptionElement.h"
+#include "HTMLTableRowElement.h"
+#include "HTMLTableRowsCollection.h"
+#include "HTMLTableSectionElement.h"
+#include "RenderTable.h"
+#include "Text.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLTableElement::HTMLTableElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , m_borderAttr(false)
+ , m_borderColorAttr(false)
+ , m_frameAttr(false)
+ , m_rulesAttr(UnsetRules)
+ , m_padding(1)
+{
+ ASSERT(hasTagName(tableTag));
+}
+
+PassRefPtr<HTMLTableElement> HTMLTableElement::create(Document* document)
+{
+ return adoptRef(new HTMLTableElement(tableTag, document));
+}
+
+PassRefPtr<HTMLTableElement> HTMLTableElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLTableElement(tagName, document));
+}
+
+HTMLTableCaptionElement* HTMLTableElement::caption() const
+{
+ for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->hasTagName(captionTag))
+ return static_cast<HTMLTableCaptionElement*>(child);
+ }
+ return 0;
+}
+
+void HTMLTableElement::setCaption(PassRefPtr<HTMLTableCaptionElement> newCaption, ExceptionCode& ec)
+{
+ deleteCaption();
+ insertBefore(newCaption, firstChild(), ec);
+}
+
+HTMLTableSectionElement* HTMLTableElement::tHead() const
+{
+ for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->hasTagName(theadTag))
+ return static_cast<HTMLTableSectionElement*>(child);
+ }
+ return 0;
+}
+
+void HTMLTableElement::setTHead(PassRefPtr<HTMLTableSectionElement> newHead, ExceptionCode& ec)
+{
+ deleteTHead();
+
+ Node* child;
+ for (child = firstChild(); child; child = child->nextSibling())
+ if (child->isElementNode() && !child->hasTagName(captionTag) && !child->hasTagName(colgroupTag))
+ break;
+
+ insertBefore(newHead, child, ec);
+}
+
+HTMLTableSectionElement* HTMLTableElement::tFoot() const
+{
+ for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->hasTagName(tfootTag))
+ return static_cast<HTMLTableSectionElement*>(child);
+ }
+ return 0;
+}
+
+void HTMLTableElement::setTFoot(PassRefPtr<HTMLTableSectionElement> newFoot, ExceptionCode& ec)
+{
+ deleteTFoot();
+
+ Node* child;
+ for (child = firstChild(); child; child = child->nextSibling())
+ if (child->isElementNode() && !child->hasTagName(captionTag) && !child->hasTagName(colgroupTag) && !child->hasTagName(theadTag))
+ break;
+
+ insertBefore(newFoot, child, ec);
+}
+
+PassRefPtr<HTMLElement> HTMLTableElement::createTHead()
+{
+ if (HTMLTableSectionElement* existingHead = tHead())
+ return existingHead;
+ RefPtr<HTMLTableSectionElement> head = HTMLTableSectionElement::create(theadTag, document());
+ ExceptionCode ec;
+ setTHead(head, ec);
+ return head.release();
+}
+
+void HTMLTableElement::deleteTHead()
+{
+ ExceptionCode ec;
+ removeChild(tHead(), ec);
+}
+
+PassRefPtr<HTMLElement> HTMLTableElement::createTFoot()
+{
+ if (HTMLTableSectionElement* existingFoot = tFoot())
+ return existingFoot;
+ RefPtr<HTMLTableSectionElement> foot = HTMLTableSectionElement::create(tfootTag, document());
+ ExceptionCode ec;
+ setTFoot(foot, ec);
+ return foot.release();
+}
+
+void HTMLTableElement::deleteTFoot()
+{
+ ExceptionCode ec;
+ removeChild(tFoot(), ec);
+}
+
+PassRefPtr<HTMLElement> HTMLTableElement::createCaption()
+{
+ if (HTMLTableCaptionElement* existingCaption = caption())
+ return existingCaption;
+ RefPtr<HTMLTableCaptionElement> caption = HTMLTableCaptionElement::create(captionTag, document());
+ ExceptionCode ec;
+ setCaption(caption, ec);
+ return caption.release();
+}
+
+void HTMLTableElement::deleteCaption()
+{
+ ExceptionCode ec;
+ removeChild(caption(), ec);
+}
+
+HTMLTableSectionElement* HTMLTableElement::lastBody() const
+{
+ for (Node* child = lastChild(); child; child = child->previousSibling()) {
+ if (child->hasTagName(tbodyTag))
+ return static_cast<HTMLTableSectionElement*>(child);
+ }
+ return 0;
+}
+
+PassRefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionCode& ec)
+{
+ if (index < -1) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+
+ HTMLTableRowElement* lastRow = 0;
+ HTMLTableRowElement* row = 0;
+ if (index == -1)
+ lastRow = HTMLTableRowsCollection::lastRow(this);
+ else {
+ for (int i = 0; i <= index; ++i) {
+ row = HTMLTableRowsCollection::rowAfter(this, lastRow);
+ if (!row) {
+ if (i != index) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+ break;
+ }
+ lastRow = row;
+ }
+ }
+
+ ContainerNode* parent;
+ if (lastRow)
+ parent = row ? row->parentNode() : lastRow->parentNode();
+ else {
+ parent = lastBody();
+ if (!parent) {
+ RefPtr<HTMLTableSectionElement> newBody = HTMLTableSectionElement::create(tbodyTag, document());
+ RefPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
+ newBody->appendChild(newRow, ec);
+ appendChild(newBody.release(), ec);
+ return newRow.release();
+ }
+ }
+
+ RefPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
+ parent->insertBefore(newRow, row, ec);
+ return newRow.release();
+}
+
+void HTMLTableElement::deleteRow(int index, ExceptionCode& ec)
+{
+ HTMLTableRowElement* row = 0;
+ if (index == -1)
+ row = HTMLTableRowsCollection::lastRow(this);
+ else {
+ for (int i = 0; i <= index; ++i) {
+ row = HTMLTableRowsCollection::rowAfter(this, row);
+ if (!row)
+ break;
+ }
+ }
+ if (!row) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+ row->remove(ec);
+}
+
+bool HTMLTableElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == backgroundAttr) {
+ result = (MappedAttributeEntry)(eLastEntry + document()->docID());
+ return false;
+ }
+
+ if (attrName == widthAttr ||
+ attrName == heightAttr ||
+ attrName == bgcolorAttr ||
+ attrName == cellspacingAttr ||
+ attrName == vspaceAttr ||
+ attrName == hspaceAttr ||
+ attrName == valignAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ if (attrName == bordercolorAttr || attrName == frameAttr || attrName == rulesAttr) {
+ result = eUniversal;
+ return true;
+ }
+
+ if (attrName == borderAttr) {
+ result = eTable;
+ return true;
+ }
+
+ if (attrName == alignAttr) {
+ result = eTable;
+ return false;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+static inline bool isTableCellAncestor(Node* n)
+{
+ return n->hasTagName(theadTag) || n->hasTagName(tbodyTag) ||
+ n->hasTagName(tfootTag) || n->hasTagName(trTag) ||
+ n->hasTagName(thTag);
+}
+
+static bool setTableCellsChanged(Node* n)
+{
+ ASSERT(n);
+ bool cellChanged = false;
+
+ if (n->hasTagName(tdTag))
+ cellChanged = true;
+ else if (isTableCellAncestor(n)) {
+ for (Node* child = n->firstChild(); child; child = child->nextSibling())
+ cellChanged |= setTableCellsChanged(child);
+ }
+
+ if (cellChanged)
+ n->setNeedsStyleRecalc();
+
+ return cellChanged;
+}
+
+void HTMLTableElement::parseMappedAttribute(Attribute* attr)
+{
+ CellBorders bordersBefore = cellBorders();
+ unsigned short oldPadding = m_padding;
+
+ if (attr->name() == widthAttr)
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
+ else if (attr->name() == heightAttr)
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
+ else if (attr->name() == borderAttr) {
+ m_borderAttr = true;
+ if (attr->decl()) {
+ RefPtr<CSSValue> val = attr->decl()->getPropertyCSSValue(CSSPropertyBorderLeftWidth);
+ if (val && val->isPrimitiveValue()) {
+ CSSPrimitiveValue* primVal = static_cast<CSSPrimitiveValue*>(val.get());
+ m_borderAttr = primVal->getDoubleValue(CSSPrimitiveValue::CSS_NUMBER);
+ }
+ } else if (!attr->isNull()) {
+ int border = 0;
+ if (attr->isEmpty())
+ border = 1;
+ else
+ border = attr->value().toInt();
+ m_borderAttr = border;
+ addCSSLength(attr, CSSPropertyBorderWidth, String::number(border));
+ }
+ } else if (attr->name() == bgcolorAttr)
+ addCSSColor(attr, CSSPropertyBackgroundColor, attr->value());
+ else if (attr->name() == bordercolorAttr) {
+ m_borderColorAttr = attr->decl();
+ if (!attr->decl() && !attr->isEmpty()) {
+ addCSSColor(attr, CSSPropertyBorderColor, attr->value());
+ m_borderColorAttr = true;
+ }
+ } else if (attr->name() == backgroundAttr) {
+ String url = stripLeadingAndTrailingHTMLSpaces(attr->value());
+ if (!url.isEmpty())
+ addCSSImageProperty(attr, CSSPropertyBackgroundImage, document()->completeURL(url).string());
+ } else if (attr->name() == frameAttr) {
+ // Cache the value of "frame" so that the table can examine it later.
+ m_frameAttr = false;
+
+ // Whether or not to hide the top/right/bottom/left borders.
+ const int cTop = 0;
+ const int cRight = 1;
+ const int cBottom = 2;
+ const int cLeft = 3;
+ bool borders[4] = { false, false, false, false };
+
+ // void, above, below, hsides, vsides, lhs, rhs, box, border
+ if (equalIgnoringCase(attr->value(), "void"))
+ m_frameAttr = true;
+ else if (equalIgnoringCase(attr->value(), "above")) {
+ m_frameAttr = true;
+ borders[cTop] = true;
+ } else if (equalIgnoringCase(attr->value(), "below")) {
+ m_frameAttr = true;
+ borders[cBottom] = true;
+ } else if (equalIgnoringCase(attr->value(), "hsides")) {
+ m_frameAttr = true;
+ borders[cTop] = borders[cBottom] = true;
+ } else if (equalIgnoringCase(attr->value(), "vsides")) {
+ m_frameAttr = true;
+ borders[cLeft] = borders[cRight] = true;
+ } else if (equalIgnoringCase(attr->value(), "lhs")) {
+ m_frameAttr = true;
+ borders[cLeft] = true;
+ } else if (equalIgnoringCase(attr->value(), "rhs")) {
+ m_frameAttr = true;
+ borders[cRight] = true;
+ } else if (equalIgnoringCase(attr->value(), "box") ||
+ equalIgnoringCase(attr->value(), "border")) {
+ m_frameAttr = true;
+ borders[cTop] = borders[cBottom] = borders[cLeft] = borders[cRight] = true;
+ }
+
+ // Now map in the border styles of solid and hidden respectively.
+ if (m_frameAttr) {
+ addCSSProperty(attr, CSSPropertyBorderTopWidth, CSSValueThin);
+ addCSSProperty(attr, CSSPropertyBorderBottomWidth, CSSValueThin);
+ addCSSProperty(attr, CSSPropertyBorderLeftWidth, CSSValueThin);
+ addCSSProperty(attr, CSSPropertyBorderRightWidth, CSSValueThin);
+ addCSSProperty(attr, CSSPropertyBorderTopStyle, borders[cTop] ? CSSValueSolid : CSSValueHidden);
+ addCSSProperty(attr, CSSPropertyBorderBottomStyle, borders[cBottom] ? CSSValueSolid : CSSValueHidden);
+ addCSSProperty(attr, CSSPropertyBorderLeftStyle, borders[cLeft] ? CSSValueSolid : CSSValueHidden);
+ addCSSProperty(attr, CSSPropertyBorderRightStyle, borders[cRight] ? CSSValueSolid : CSSValueHidden);
+ }
+ } else if (attr->name() == rulesAttr) {
+ m_rulesAttr = UnsetRules;
+ if (equalIgnoringCase(attr->value(), "none"))
+ m_rulesAttr = NoneRules;
+ else if (equalIgnoringCase(attr->value(), "groups"))
+ m_rulesAttr = GroupsRules;
+ else if (equalIgnoringCase(attr->value(), "rows"))
+ m_rulesAttr = RowsRules;
+ if (equalIgnoringCase(attr->value(), "cols"))
+ m_rulesAttr = ColsRules;
+ if (equalIgnoringCase(attr->value(), "all"))
+ m_rulesAttr = AllRules;
+
+ // The presence of a valid rules attribute causes border collapsing to be enabled.
+ if (m_rulesAttr != UnsetRules)
+ addCSSProperty(attr, CSSPropertyBorderCollapse, CSSValueCollapse);
+ } else if (attr->name() == cellspacingAttr) {
+ if (!attr->value().isEmpty())
+ addCSSLength(attr, CSSPropertyBorderSpacing, attr->value());
+ } else if (attr->name() == cellpaddingAttr) {
+ if (!attr->value().isEmpty())
+ m_padding = max(0, attr->value().toInt());
+ else
+ m_padding = 1;
+ } else if (attr->name() == colsAttr) {
+ // ###
+ } else if (attr->name() == vspaceAttr) {
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
+ } else if (attr->name() == hspaceAttr) {
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
+ } else if (attr->name() == alignAttr) {
+ if (!attr->value().isEmpty()) {
+ if (equalIgnoringCase(attr->value(), "center")) {
+ addCSSProperty(attr, CSSPropertyWebkitMarginStart, CSSValueAuto);
+ addCSSProperty(attr, CSSPropertyWebkitMarginEnd, CSSValueAuto);
+ } else
+ addCSSProperty(attr, CSSPropertyFloat, attr->value());
+ }
+ } else if (attr->name() == valignAttr) {
+ if (!attr->value().isEmpty())
+ addCSSProperty(attr, CSSPropertyVerticalAlign, attr->value());
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+
+ if (bordersBefore != cellBorders() || oldPadding != m_padding) {
+ if (oldPadding != m_padding)
+ m_paddingDecl = 0;
+ bool cellChanged = false;
+ for (Node* child = firstChild(); child; child = child->nextSibling())
+ cellChanged |= setTableCellsChanged(child);
+ if (cellChanged)
+ setNeedsStyleRecalc();
+ }
+}
+
+void HTMLTableElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
+{
+ if ((!m_borderAttr && !m_borderColorAttr) || m_frameAttr)
+ return;
+
+ AtomicString borderValue = m_borderColorAttr ? "solid" : "outset";
+ CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, tableborderAttr, borderValue);
+ if (!decl) {
+ decl = CSSMappedAttributeDeclaration::create().releaseRef(); // This single ref pins us in the table until the document dies.
+ decl->setParent(document()->elementSheet());
+ decl->setNode(this);
+ decl->setStrictParsing(false); // Mapped attributes are just always quirky.
+
+ int v = m_borderColorAttr ? CSSValueSolid : CSSValueOutset;
+ decl->setProperty(CSSPropertyBorderTopStyle, v, false);
+ decl->setProperty(CSSPropertyBorderBottomStyle, v, false);
+ decl->setProperty(CSSPropertyBorderLeftStyle, v, false);
+ decl->setProperty(CSSPropertyBorderRightStyle, v, false);
+
+ setMappedAttributeDecl(ePersistent, tableborderAttr, borderValue, decl);
+ decl->setParent(0);
+ decl->setNode(0);
+ decl->setMappedState(ePersistent, tableborderAttr, borderValue);
+ }
+
+
+ results.append(decl);
+}
+
+HTMLTableElement::CellBorders HTMLTableElement::cellBorders() const
+{
+ switch (m_rulesAttr) {
+ case NoneRules:
+ case GroupsRules:
+ return NoBorders;
+ case AllRules:
+ return SolidBorders;
+ case ColsRules:
+ return SolidBordersColsOnly;
+ case RowsRules:
+ return SolidBordersRowsOnly;
+ case UnsetRules:
+ if (!m_borderAttr)
+ return NoBorders;
+ if (m_borderColorAttr)
+ return SolidBorders;
+ return InsetBorders;
+ }
+ ASSERT_NOT_REACHED();
+ return NoBorders;
+}
+
+void HTMLTableElement::addSharedCellDecls(Vector<CSSMutableStyleDeclaration*>& results)
+{
+ addSharedCellBordersDecl(results);
+ addSharedCellPaddingDecl(results);
+}
+
+void HTMLTableElement::addSharedCellBordersDecl(Vector<CSSMutableStyleDeclaration*>& results)
+{
+ CellBorders borders = cellBorders();
+
+ static const AtomicString* cellBorderNames[] = { new AtomicString("none"), new AtomicString("solid"), new AtomicString("inset"), new AtomicString("solid-cols"), new AtomicString("solid-rows") };
+ const AtomicString& cellborderValue = *cellBorderNames[borders];
+ CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, cellborderAttr, cellborderValue);
+ if (!decl) {
+ decl = CSSMappedAttributeDeclaration::create().releaseRef(); // This single ref pins us in the table until the document dies.
+ decl->setParent(document()->elementSheet());
+ decl->setNode(this);
+ decl->setStrictParsing(false); // Mapped attributes are just always quirky.
+
+ switch (borders) {
+ case SolidBordersColsOnly:
+ decl->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderRightWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderColor, "inherit", false);
+ break;
+ case SolidBordersRowsOnly:
+ decl->setProperty(CSSPropertyBorderTopWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderColor, "inherit", false);
+ break;
+ case SolidBorders:
+ decl->setProperty(CSSPropertyBorderWidth, "1px", false);
+ decl->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderColor, "inherit", false);
+ break;
+ case InsetBorders:
+ decl->setProperty(CSSPropertyBorderWidth, "1px", false);
+ decl->setProperty(CSSPropertyBorderTopStyle, CSSValueInset, false);
+ decl->setProperty(CSSPropertyBorderBottomStyle, CSSValueInset, false);
+ decl->setProperty(CSSPropertyBorderLeftStyle, CSSValueInset, false);
+ decl->setProperty(CSSPropertyBorderRightStyle, CSSValueInset, false);
+ decl->setProperty(CSSPropertyBorderColor, "inherit", false);
+ break;
+ case NoBorders:
+ decl->setProperty(CSSPropertyBorderWidth, "0", false);
+ break;
+ }
+
+ setMappedAttributeDecl(ePersistent, cellborderAttr, *cellBorderNames[borders], decl);
+ decl->setParent(0);
+ decl->setNode(0);
+ decl->setMappedState(ePersistent, cellborderAttr, cellborderValue);
+ }
+
+ results.append(decl);
+}
+
+void HTMLTableElement::addSharedCellPaddingDecl(Vector<CSSMutableStyleDeclaration*>& results)
+{
+ if (m_padding == 0)
+ return;
+
+ if (!m_paddingDecl) {
+ String paddingValue = String::number(m_padding);
+ m_paddingDecl = getMappedAttributeDecl(eUniversal, cellpaddingAttr, paddingValue);
+ if (!m_paddingDecl) {
+ m_paddingDecl = CSSMappedAttributeDeclaration::create();
+ m_paddingDecl->setParent(document()->elementSheet());
+ m_paddingDecl->setNode(this);
+ m_paddingDecl->setStrictParsing(false); // Mapped attributes are just always quirky.
+
+ m_paddingDecl->setProperty(CSSPropertyPaddingTop, paddingValue, false);
+ m_paddingDecl->setProperty(CSSPropertyPaddingRight, paddingValue, false);
+ m_paddingDecl->setProperty(CSSPropertyPaddingBottom, paddingValue, false);
+ m_paddingDecl->setProperty(CSSPropertyPaddingLeft, paddingValue, false);
+ }
+ setMappedAttributeDecl(eUniversal, cellpaddingAttr, paddingValue, m_paddingDecl.get());
+ m_paddingDecl->setParent(0);
+ m_paddingDecl->setNode(0);
+ m_paddingDecl->setMappedState(eUniversal, cellpaddingAttr, paddingValue);
+ }
+
+ results.append(m_paddingDecl.get());
+}
+
+void HTMLTableElement::addSharedGroupDecls(bool rows, Vector<CSSMutableStyleDeclaration*>& results)
+{
+ if (m_rulesAttr != GroupsRules)
+ return;
+
+ AtomicString rulesValue = rows ? "rowgroups" : "colgroups";
+ CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, rulesAttr, rulesValue);
+ if (!decl) {
+ decl = CSSMappedAttributeDeclaration::create().releaseRef(); // This single ref pins us in the table until the document dies.
+ decl->setParent(document()->elementSheet());
+ decl->setNode(this);
+ decl->setStrictParsing(false); // Mapped attributes are just always quirky.
+
+ if (rows) {
+ decl->setProperty(CSSPropertyBorderTopWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid, false);
+ } else {
+ decl->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderRightWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid, false);
+ }
+
+ setMappedAttributeDecl(ePersistent, rulesAttr, rulesValue, decl);
+ decl->setParent(0);
+ decl->setNode(0);
+ decl->setMappedState(ePersistent, rulesAttr, rulesValue);
+ }
+
+ results.append(decl);
+}
+
+void HTMLTableElement::attach()
+{
+ ASSERT(!attached());
+ HTMLElement::attach();
+}
+
+bool HTMLTableElement::isURLAttribute(Attribute *attr) const
+{
+ return attr->name() == backgroundAttr;
+}
+
+PassRefPtr<HTMLCollection> HTMLTableElement::rows()
+{
+ return HTMLTableRowsCollection::create(this);
+}
+
+PassRefPtr<HTMLCollection> HTMLTableElement::tBodies()
+{
+ return HTMLCollection::create(this, TableTBodies);
+}
+
+String HTMLTableElement::rules() const
+{
+ return getAttribute(rulesAttr);
+}
+
+String HTMLTableElement::summary() const
+{
+ return getAttribute(summaryAttr);
+}
+
+void HTMLTableElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+{
+ HTMLElement::addSubresourceAttributeURLs(urls);
+
+ addSubresourceURL(urls, document()->completeURL(getAttribute(backgroundAttr)));
+}
+
+}
diff --git a/Source/WebCore/html/HTMLTableElement.h b/Source/WebCore/html/HTMLTableElement.h
new file mode 100644
index 0000000..da3dc30
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableElement.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 2008 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLTableElement_h
+#define HTMLTableElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLCollection;
+class HTMLTableCaptionElement;
+class HTMLTableSectionElement;
+
+class HTMLTableElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLTableElement> create(Document*);
+ static PassRefPtr<HTMLTableElement> create(const QualifiedName&, Document*);
+
+ HTMLTableCaptionElement* caption() const;
+ void setCaption(PassRefPtr<HTMLTableCaptionElement>, ExceptionCode&);
+
+ HTMLTableSectionElement* tHead() const;
+ void setTHead(PassRefPtr<HTMLTableSectionElement>, ExceptionCode&);
+
+ HTMLTableSectionElement* tFoot() const;
+ void setTFoot(PassRefPtr<HTMLTableSectionElement>, ExceptionCode&);
+
+ PassRefPtr<HTMLElement> createTHead();
+ void deleteTHead();
+ PassRefPtr<HTMLElement> createTFoot();
+ void deleteTFoot();
+ PassRefPtr<HTMLElement> createCaption();
+ void deleteCaption();
+ PassRefPtr<HTMLElement> insertRow(int index, ExceptionCode&);
+ void deleteRow(int index, ExceptionCode&);
+
+ PassRefPtr<HTMLCollection> rows();
+ PassRefPtr<HTMLCollection> tBodies();
+
+ String rules() const;
+ String summary() const;
+
+ virtual void attach();
+
+ void addSharedCellDecls(Vector<CSSMutableStyleDeclaration*>&);
+ void addSharedGroupDecls(bool rows, Vector<CSSMutableStyleDeclaration*>&);
+
+private:
+ HTMLTableElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+ virtual bool isURLAttribute(Attribute*) const;
+
+ // Used to obtain either a solid or outset border decl and to deal with the frame
+ // and rules attributes.
+ virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
+ virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
+
+ virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+
+ void addSharedCellBordersDecl(Vector<CSSMutableStyleDeclaration*>&);
+ void addSharedCellPaddingDecl(Vector<CSSMutableStyleDeclaration*>&);
+
+ enum TableRules { UnsetRules, NoneRules, GroupsRules, RowsRules, ColsRules, AllRules };
+ enum CellBorders { NoBorders, SolidBorders, InsetBorders, SolidBordersColsOnly, SolidBordersRowsOnly };
+
+ CellBorders cellBorders() const;
+
+ HTMLTableSectionElement* lastBody() const;
+
+ bool m_borderAttr; // Sets a precise border width and creates an outset border for the table and for its cells.
+ bool m_borderColorAttr; // Overrides the outset border and makes it solid for the table and cells instead.
+ bool m_frameAttr; // Implies a thin border width if no border is set and then a certain set of solid/hidden borders based off the value.
+ TableRules m_rulesAttr; // Implies a thin border width, a collapsing border model, and all borders on the table becoming set to hidden (if frame/border
+ // are present, to none otherwise).
+
+ unsigned short m_padding;
+ RefPtr<CSSMappedAttributeDeclaration> m_paddingDecl;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLTableElement.idl b/Source/WebCore/html/HTMLTableElement.idl
new file mode 100644
index 0000000..fddb27a
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableElement.idl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLTableElement : HTMLElement {
+ attribute HTMLTableCaptionElement caption setter raises(DOMException);
+ attribute HTMLTableSectionElement tHead setter raises(DOMException);
+ attribute HTMLTableSectionElement tFoot setter raises(DOMException);
+
+ readonly attribute HTMLCollection rows;
+ readonly attribute HTMLCollection tBodies;
+ attribute [Reflect] DOMString align;
+ attribute [Reflect] DOMString bgColor;
+ attribute [Reflect] DOMString border;
+ attribute [Reflect] DOMString cellPadding;
+ attribute [Reflect] DOMString cellSpacing;
+
+ attribute [Reflect] DOMString frame;
+
+ attribute [Reflect] DOMString rules;
+ attribute [Reflect] DOMString summary;
+ attribute [Reflect] DOMString width;
+
+ HTMLElement createTHead();
+ void deleteTHead();
+ HTMLElement createTFoot();
+ void deleteTFoot();
+ HTMLElement createCaption();
+ void deleteCaption();
+
+ HTMLElement insertRow(in long index) raises(DOMException);
+ void deleteRow(in long index) raises(DOMException);
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLTablePartElement.cpp b/Source/WebCore/html/HTMLTablePartElement.cpp
new file mode 100644
index 0000000..dfaecca
--- /dev/null
+++ b/Source/WebCore/html/HTMLTablePartElement.cpp
@@ -0,0 +1,100 @@
+/**
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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 Computer, 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLTablePartElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "Document.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+bool HTMLTablePartElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == backgroundAttr) {
+ result = (MappedAttributeEntry)(eLastEntry + document()->docID());
+ return false;
+ }
+
+ if (attrName == bgcolorAttr ||
+ attrName == bordercolorAttr ||
+ attrName == valignAttr ||
+ attrName == heightAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ if (attrName == alignAttr) {
+ result = eCell; // All table parts will just share in the TD space.
+ return false;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLTablePartElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == bgcolorAttr)
+ addCSSColor(attr, CSSPropertyBackgroundColor, attr->value());
+ else if (attr->name() == backgroundAttr) {
+ String url = stripLeadingAndTrailingHTMLSpaces(attr->value());
+ if (!url.isEmpty())
+ addCSSImageProperty(attr, CSSPropertyBackgroundImage, document()->completeURL(url).string());
+ } else if (attr->name() == bordercolorAttr) {
+ if (!attr->value().isEmpty()) {
+ addCSSColor(attr, CSSPropertyBorderColor, attr->value());
+ addCSSProperty(attr, CSSPropertyBorderTopStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderBottomStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderLeftStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderRightStyle, CSSValueSolid);
+ }
+ } else if (attr->name() == valignAttr) {
+ if (!attr->value().isEmpty())
+ addCSSProperty(attr, CSSPropertyVerticalAlign, attr->value());
+ } else if (attr->name() == alignAttr) {
+ const AtomicString& v = attr->value();
+ if (equalIgnoringCase(v, "middle") || equalIgnoringCase(v, "center"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitCenter);
+ else if (equalIgnoringCase(v, "absmiddle"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueCenter);
+ else if (equalIgnoringCase(v, "left"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitLeft);
+ else if (equalIgnoringCase(v, "right"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitRight);
+ else
+ addCSSProperty(attr, CSSPropertyTextAlign, v);
+ } else if (attr->name() == heightAttr) {
+ if (!attr->value().isEmpty())
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLTablePartElement.h b/Source/WebCore/html/HTMLTablePartElement.h
new file mode 100644
index 0000000..9df2f91
--- /dev/null
+++ b/Source/WebCore/html/HTMLTablePartElement.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLTablePartElement_h
+#define HTMLTablePartElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLTablePartElement : public HTMLElement {
+protected:
+ HTMLTablePartElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ {
+ }
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLTableRowElement.cpp b/Source/WebCore/html/HTMLTableRowElement.cpp
new file mode 100644
index 0000000..fbc253d
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableRowElement.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLTableRowElement.h"
+
+#include "ExceptionCode.h"
+#include "HTMLCollection.h"
+#include "HTMLNames.h"
+#include "HTMLTableCellElement.h"
+#include "HTMLTableElement.h"
+#include "HTMLTableSectionElement.h"
+#include "NodeList.h"
+#include "Text.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLTableRowElement::HTMLTableRowElement(const QualifiedName& tagName, Document* document)
+ : HTMLTablePartElement(tagName, document)
+{
+ ASSERT(hasTagName(trTag));
+}
+
+PassRefPtr<HTMLTableRowElement> HTMLTableRowElement::create(Document* document)
+{
+ return adoptRef(new HTMLTableRowElement(trTag, document));
+}
+
+PassRefPtr<HTMLTableRowElement> HTMLTableRowElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLTableRowElement(tagName, document));
+}
+
+int HTMLTableRowElement::rowIndex() const
+{
+ ContainerNode* table = parentNode();
+ if (!table)
+ return -1;
+ table = table->parentNode();
+ if (!table || !table->hasTagName(tableTag))
+ return -1;
+
+ // To match Firefox, the row indices work like this:
+ // Rows from the first <thead> are numbered before all <tbody> rows.
+ // Rows from the first <tfoot> are numbered after all <tbody> rows.
+ // Rows from other <thead> and <tfoot> elements don't get row indices at all.
+
+ int rIndex = 0;
+
+ if (HTMLTableSectionElement* head = static_cast<HTMLTableElement*>(table)->tHead()) {
+ for (Node *row = head->firstChild(); row; row = row->nextSibling()) {
+ if (row == this)
+ return rIndex;
+ if (row->hasTagName(trTag))
+ ++rIndex;
+ }
+ }
+
+ for (Node *node = table->firstChild(); node; node = node->nextSibling()) {
+ if (node->hasTagName(tbodyTag)) {
+ HTMLTableSectionElement* section = static_cast<HTMLTableSectionElement*>(node);
+ for (Node* row = section->firstChild(); row; row = row->nextSibling()) {
+ if (row == this)
+ return rIndex;
+ if (row->hasTagName(trTag))
+ ++rIndex;
+ }
+ }
+ }
+
+ if (HTMLTableSectionElement* foot = static_cast<HTMLTableElement*>(table)->tFoot()) {
+ for (Node *row = foot->firstChild(); row; row = row->nextSibling()) {
+ if (row == this)
+ return rIndex;
+ if (row->hasTagName(trTag))
+ ++rIndex;
+ }
+ }
+
+ // We get here for rows that are in <thead> or <tfoot> sections other than the main header and footer.
+ return -1;
+}
+
+int HTMLTableRowElement::sectionRowIndex() const
+{
+ int rIndex = 0;
+ const Node *n = this;
+ do {
+ n = n->previousSibling();
+ if (n && n->hasTagName(trTag))
+ rIndex++;
+ }
+ while (n);
+
+ return rIndex;
+}
+
+PassRefPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionCode& ec)
+{
+ RefPtr<HTMLCollection> children = cells();
+ int numCells = children ? children->length() : 0;
+ if (index < -1 || index > numCells) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+
+ RefPtr<HTMLTableCellElement> cell = HTMLTableCellElement::create(tdTag, document());
+ if (index < 0 || index >= numCells)
+ appendChild(cell, ec);
+ else {
+ Node* n;
+ if (index < 1)
+ n = firstChild();
+ else
+ n = children->item(index);
+ insertBefore(cell, n, ec);
+ }
+ return cell.release();
+}
+
+void HTMLTableRowElement::deleteCell(int index, ExceptionCode& ec)
+{
+ RefPtr<HTMLCollection> children = cells();
+ int numCells = children ? children->length() : 0;
+ if (index == -1)
+ index = numCells-1;
+ if (index >= 0 && index < numCells) {
+ RefPtr<Node> cell = children->item(index);
+ HTMLElement::removeChild(cell.get(), ec);
+ } else
+ ec = INDEX_SIZE_ERR;
+}
+
+PassRefPtr<HTMLCollection> HTMLTableRowElement::cells()
+{
+ return HTMLCollection::create(this, TRCells);
+}
+
+void HTMLTableRowElement::setCells(HTMLCollection*, ExceptionCode& ec)
+{
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+}
+
+}
diff --git a/Source/WebCore/html/HTMLTableRowElement.h b/Source/WebCore/html/HTMLTableRowElement.h
new file mode 100644
index 0000000..c433677
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableRowElement.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLTableRowElement_h
+#define HTMLTableRowElement_h
+
+#include "HTMLTablePartElement.h"
+
+namespace WebCore {
+
+class HTMLTableRowElement : public HTMLTablePartElement {
+public:
+ static PassRefPtr<HTMLTableRowElement> create(Document*);
+ static PassRefPtr<HTMLTableRowElement> create(const QualifiedName&, Document*);
+
+ int rowIndex() const;
+ void setRowIndex(int);
+
+ int sectionRowIndex() const;
+ void setSectionRowIndex(int);
+
+ PassRefPtr<HTMLElement> insertCell(int index, ExceptionCode&);
+ void deleteCell(int index, ExceptionCode&);
+
+ PassRefPtr<HTMLCollection> cells();
+ void setCells(HTMLCollection *, ExceptionCode&);
+
+private:
+ HTMLTableRowElement(const QualifiedName&, Document*);
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLTableRowElement.idl b/Source/WebCore/html/HTMLTableRowElement.idl
new file mode 100644
index 0000000..4eb348e
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableRowElement.idl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2006, 2007, 2010 Apple Inc. ALl rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLTableRowElement : HTMLElement {
+ readonly attribute long rowIndex;
+ readonly attribute long sectionRowIndex;
+ readonly attribute HTMLCollection cells;
+ attribute [Reflect] DOMString align;
+ attribute [Reflect] DOMString bgColor;
+ attribute [Reflect=char] DOMString ch;
+ attribute [Reflect=charoff] DOMString chOff;
+ attribute [Reflect] DOMString vAlign;
+ HTMLElement insertCell(in long index) raises(DOMException);
+ void deleteCell(in long index) raises(DOMException);
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLTableRowsCollection.cpp b/Source/WebCore/html/HTMLTableRowsCollection.cpp
new file mode 100644
index 0000000..20143d9
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableRowsCollection.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 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
+ * 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 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.
+ *
+ * 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"
+#include "HTMLTableRowsCollection.h"
+
+#include "HTMLNames.h"
+#include "HTMLTableElement.h"
+#include "HTMLTableRowElement.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static bool isInHead(Element* row)
+{
+ return row->parentNode() && static_cast<Element*>(row->parentNode())->hasLocalName(theadTag);
+}
+
+static bool isInBody(Element* row)
+{
+ return row->parentNode() && static_cast<Element*>(row->parentNode())->hasLocalName(tbodyTag);
+}
+
+static bool isInFoot(Element* row)
+{
+ return row->parentNode() && static_cast<Element*>(row->parentNode())->hasLocalName(tfootTag);
+}
+
+HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement* table, HTMLTableRowElement* previous)
+{
+ Node* child = 0;
+
+ // Start by looking for the next row in this section.
+ // Continue only if there is none.
+ if (previous && previous->parentNode() != table) {
+ for (child = previous->nextSibling(); child; child = child->nextSibling()) {
+ if (child->hasTagName(trTag))
+ return static_cast<HTMLTableRowElement*>(child);
+ }
+ }
+
+ // If still looking at head sections, find the first row in the next head section.
+ if (!previous)
+ child = table->firstChild();
+ else if (isInHead(previous))
+ child = previous->parentNode()->nextSibling();
+ for (; child; child = child->nextSibling()) {
+ if (child->hasTagName(theadTag)) {
+ for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) {
+ if (grandchild->hasTagName(trTag))
+ return static_cast<HTMLTableRowElement*>(grandchild);
+ }
+ }
+ }
+
+ // 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 || isInHead(previous))
+ child = table->firstChild();
+ else if (previous->parentNode() == table)
+ child = previous->nextSibling();
+ else if (isInBody(previous))
+ child = previous->parentNode()->nextSibling();
+ for (; child; child = child->nextSibling()) {
+ if (child->hasTagName(trTag))
+ return static_cast<HTMLTableRowElement*>(child);
+ if (child->hasTagName(tbodyTag)) {
+ for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) {
+ if (grandchild->hasTagName(trTag))
+ return static_cast<HTMLTableRowElement*>(grandchild);
+ }
+ }
+ }
+
+ // Find the first row in the next foot section.
+ if (!previous || !isInFoot(previous))
+ child = table->firstChild();
+ else
+ child = previous->parentNode()->nextSibling();
+ for (; child; child = child->nextSibling()) {
+ if (child->hasTagName(tfootTag)) {
+ for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) {
+ if (grandchild->hasTagName(trTag))
+ return static_cast<HTMLTableRowElement*>(grandchild);
+ }
+ }
+ }
+
+ return 0;
+}
+
+HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table)
+{
+ for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
+ if (child->hasTagName(tfootTag)) {
+ for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
+ if (grandchild->hasTagName(trTag))
+ return static_cast<HTMLTableRowElement*>(grandchild);
+ }
+ }
+ }
+
+ for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
+ if (child->hasTagName(trTag))
+ return static_cast<HTMLTableRowElement*>(child);
+ if (child->hasTagName(tbodyTag)) {
+ for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
+ if (grandchild->hasTagName(trTag))
+ return static_cast<HTMLTableRowElement*>(grandchild);
+ }
+ }
+ }
+
+ for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
+ if (child->hasTagName(theadTag)) {
+ for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
+ if (grandchild->hasTagName(trTag))
+ return static_cast<HTMLTableRowElement*>(grandchild);
+ }
+ }
+ }
+
+ return 0;
+}
+
+HTMLTableRowsCollection::HTMLTableRowsCollection(PassRefPtr<HTMLTableElement> table)
+ : HTMLCollection(table, OtherCollection, 0)
+{
+}
+
+PassRefPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(PassRefPtr<HTMLTableElement> table)
+{
+ return adoptRef(new HTMLTableRowsCollection(table));
+}
+
+Element* HTMLTableRowsCollection::itemAfter(Element* previous) const
+{
+ ASSERT(!previous || previous->hasLocalName(trTag));
+ return rowAfter(static_cast<HTMLTableElement*>(base()), static_cast<HTMLTableRowElement*>(previous));
+}
+
+}
diff --git a/Source/WebCore/html/HTMLTableRowsCollection.h b/Source/WebCore/html/HTMLTableRowsCollection.h
new file mode 100644
index 0000000..f997e3c
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableRowsCollection.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 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
+ * 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 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.
+ *
+ * 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 HTMLTableRowsCollection_h
+#define HTMLTableRowsCollection_h
+
+#include "HTMLCollection.h"
+
+namespace WebCore {
+
+class HTMLTableElement;
+class HTMLTableRowElement;
+
+class HTMLTableRowsCollection : public HTMLCollection {
+public:
+ static PassRefPtr<HTMLTableRowsCollection> create(PassRefPtr<HTMLTableElement>);
+
+ static HTMLTableRowElement* rowAfter(HTMLTableElement*, HTMLTableRowElement*);
+ static HTMLTableRowElement* lastRow(HTMLTableElement*);
+
+private:
+ HTMLTableRowsCollection(PassRefPtr<HTMLTableElement>);
+
+ virtual Element* itemAfter(Element*) const;
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLTableSectionElement.cpp b/Source/WebCore/html/HTMLTableSectionElement.cpp
new file mode 100644
index 0000000..5ef25f1
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableSectionElement.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLTableSectionElement.h"
+
+#include "ExceptionCode.h"
+#include "HTMLCollection.h"
+#include "HTMLNames.h"
+#include "HTMLTableRowElement.h"
+#include "HTMLTableElement.h"
+#include "NodeList.h"
+#include "Text.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLTableSectionElement::HTMLTableSectionElement(const QualifiedName& tagName, Document* document)
+ : HTMLTablePartElement(tagName, document)
+{
+}
+
+PassRefPtr<HTMLTableSectionElement> HTMLTableSectionElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLTableSectionElement(tagName, document));
+}
+
+// used by table row groups to share style decls created by the enclosing table.
+void HTMLTableSectionElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
+{
+ ContainerNode* p = parentNode();
+ while (p && !p->hasTagName(tableTag))
+ p = p->parentNode();
+ if (!p)
+ return;
+ static_cast<HTMLTableElement*>(p)->addSharedGroupDecls(true, results);
+}
+
+// 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
+PassRefPtr<HTMLElement> HTMLTableSectionElement::insertRow(int index, ExceptionCode& ec)
+{
+ RefPtr<HTMLTableRowElement> row;
+ RefPtr<HTMLCollection> children = rows();
+ int numRows = children ? (int)children->length() : 0;
+ if (index < -1 || index > numRows)
+ ec = INDEX_SIZE_ERR; // per the DOM
+ else {
+ row = HTMLTableRowElement::create(trTag, document());
+ if (numRows == index || index == -1)
+ appendChild(row, ec);
+ else {
+ Node* n;
+ if (index < 1)
+ n = firstChild();
+ else
+ n = children->item(index);
+ insertBefore(row, n, ec);
+ }
+ }
+ return row.release();
+}
+
+void HTMLTableSectionElement::deleteRow(int index, ExceptionCode& ec)
+{
+ RefPtr<HTMLCollection> children = rows();
+ int numRows = children ? (int)children->length() : 0;
+ if (index == -1)
+ index = numRows - 1;
+ if (index >= 0 && index < numRows) {
+ RefPtr<Node> row = children->item(index);
+ HTMLElement::removeChild(row.get(), ec);
+ } else
+ ec = INDEX_SIZE_ERR;
+}
+
+int HTMLTableSectionElement::numRows() const
+{
+ int rows = 0;
+ const Node *n = firstChild();
+ while (n) {
+ if (n->hasTagName(trTag))
+ rows++;
+ n = n->nextSibling();
+ }
+
+ return rows;
+}
+
+String HTMLTableSectionElement::align() const
+{
+ return getAttribute(alignAttr);
+}
+
+void HTMLTableSectionElement::setAlign(const String &value)
+{
+ setAttribute(alignAttr, value);
+}
+
+String HTMLTableSectionElement::ch() const
+{
+ return getAttribute(charAttr);
+}
+
+void HTMLTableSectionElement::setCh(const String &value)
+{
+ setAttribute(charAttr, value);
+}
+
+String HTMLTableSectionElement::chOff() const
+{
+ return getAttribute(charoffAttr);
+}
+
+void HTMLTableSectionElement::setChOff(const String &value)
+{
+ setAttribute(charoffAttr, value);
+}
+
+String HTMLTableSectionElement::vAlign() const
+{
+ return getAttribute(valignAttr);
+}
+
+void HTMLTableSectionElement::setVAlign(const String &value)
+{
+ setAttribute(valignAttr, value);
+}
+
+PassRefPtr<HTMLCollection> HTMLTableSectionElement::rows()
+{
+ return HTMLCollection::create(this, TSectionRows);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLTableSectionElement.h b/Source/WebCore/html/HTMLTableSectionElement.h
new file mode 100644
index 0000000..a84cbde
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableSectionElement.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ * (C) 1997 Torben Weis (weis@kde.org)
+ * (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, 2007 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLTableSectionElement_h
+#define HTMLTableSectionElement_h
+
+#include "HTMLTablePartElement.h"
+
+namespace WebCore {
+
+class HTMLTableSectionElement : public HTMLTablePartElement {
+public:
+ static PassRefPtr<HTMLTableSectionElement> create(const QualifiedName&, Document*);
+
+ PassRefPtr<HTMLElement> insertRow(int index, ExceptionCode&);
+ void deleteRow(int index, ExceptionCode&);
+
+ int numRows() const;
+
+ String align() const;
+ void setAlign(const String&);
+
+ String ch() const;
+ void setCh(const String&);
+
+ String chOff() const;
+ void setChOff(const String&);
+
+ String vAlign() const;
+ void setVAlign(const String&);
+
+ PassRefPtr<HTMLCollection> rows();
+
+private:
+ HTMLTableSectionElement(const QualifiedName& tagName, Document*);
+
+ virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
+ virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLTableSectionElement.idl b/Source/WebCore/html/HTMLTableSectionElement.idl
new file mode 100644
index 0000000..2065d6e
--- /dev/null
+++ b/Source/WebCore/html/HTMLTableSectionElement.idl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ GenerateNativeConverter
+ ] HTMLTableSectionElement : HTMLElement {
+ attribute [Reflect] DOMString align;
+ attribute [Reflect=char] DOMString ch;
+ attribute [Reflect=charoff] DOMString chOff;
+ attribute [Reflect] DOMString vAlign;
+ readonly attribute HTMLCollection rows;
+ HTMLElement insertRow(in long index) raises(DOMException);
+ void deleteRow(in long index) raises(DOMException);
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLTagNames.in b/Source/WebCore/html/HTMLTagNames.in
new file mode 100644
index 0000000..4153f5c
--- /dev/null
+++ b/Source/WebCore/html/HTMLTagNames.in
@@ -0,0 +1,143 @@
+namespace="HTML"
+namespacePrefix="xhtml"
+namespaceURI="http://www.w3.org/1999/xhtml"
+
+a interfaceName=HTMLAnchorElement
+abbr interfaceName=HTMLElement
+acronym interfaceName=HTMLElement
+address interfaceName=HTMLElement
+applet
+area
+article interfaceName=HTMLElement
+aside interfaceName=HTMLElement
+audio wrapperOnlyIfMediaIsAvailable, conditional=VIDEO
+b interfaceName=HTMLElement
+base
+basefont interfaceName=HTMLBaseFontElement
+bdo interfaceName=HTMLElement
+bgsound interfaceName=HTMLElement
+big interfaceName=HTMLElement
+blockquote
+body
+br interfaceName=HTMLBRElement
+button constructorNeedsFormElement
+canvas
+caption interfaceName=HTMLTableCaptionElement
+center interfaceName=HTMLElement
+cite interfaceName=HTMLElement
+code interfaceName=HTMLElement
+col interfaceName=HTMLTableColElement
+colgroup interfaceName=HTMLTableColElement
+command interfaceName=HTMLElement
+datagrid interfaceName=HTMLDataGridElement, conditional=DATAGRID
+datalist interfaceName=HTMLDataListElement, conditional=DATALIST
+dcell interfaceName=HTMLDataGridCellElement, conditional=DATAGRID
+dcol interfaceName=HTMLDataGridColElement, conditional=DATAGRID
+drow interfaceName=HTMLDataGridRowElement, conditional=DATAGRID
+dd interfaceName=HTMLElement
+del interfaceName=HTMLModElement
+details
+dfn interfaceName=HTMLElement
+dir interfaceName=HTMLDirectoryElement
+div
+dl interfaceName=HTMLDListElement
+dt interfaceName=HTMLElement
+em interfaceName=HTMLElement
+embed constructorNeedsCreatedByParser
+fieldset interfaceName=HTMLFieldSetElement, constructorNeedsFormElement
+figcaption interfaceName=HTMLElement
+figure interfaceName=HTMLElement
+font
+footer interfaceName=HTMLElement
+form
+frame
+frameset interfaceName=HTMLFrameSetElement
+h1 interfaceName=HTMLHeadingElement
+h2 interfaceName=HTMLHeadingElement
+h3 interfaceName=HTMLHeadingElement
+h4 interfaceName=HTMLHeadingElement
+h5 interfaceName=HTMLHeadingElement
+h6 interfaceName=HTMLHeadingElement
+head
+header interfaceName=HTMLElement
+hgroup interfaceName=HTMLElement
+hr interfaceName=HTMLHRElement
+html
+i interfaceName=HTMLElement
+iframe interfaceName=HTMLIFrameElement
+image mapToTagName=img
+img interfaceName=HTMLImageElement, constructorNeedsFormElement
+input constructorNeedsFormElement
+ins interfaceName=HTMLModElement
+isindex interfaceName=HTMLIsIndexElement, constructorNeedsFormElement
+kbd interfaceName=HTMLElement
+keygen JSInterfaceName=HTMLSelectElement, constructorNeedsFormElement
+label
+layer interfaceName=HTMLElement
+legend constructorNeedsFormElement
+li interfaceName=HTMLLIElement
+link constructorNeedsCreatedByParser
+listing interfaceName=HTMLPreElement
+map
+mark interfaceName=HTMLElement
+marquee
+menu
+meta
+meter interfaceName=HTMLMeterElement, constructorNeedsFormElement, conditional=METER_TAG
+nav interfaceName=HTMLElement
+nobr interfaceName=HTMLElement
+noembed interfaceName=HTMLElement
+noframes interfaceName=HTMLElement
+nolayer interfaceName=HTMLElement
+object constructorNeedsFormElement, constructorNeedsCreatedByParser
+ol interfaceName=HTMLOListElement
+optgroup interfaceName=HTMLOptGroupElement, constructorNeedsFormElement
+option constructorNeedsFormElement
+output constructorNeedsFormElement
+p interfaceName=HTMLParagraphElement
+param
+plaintext interfaceName=HTMLElement
+pre
+progress interfaceName=HTMLProgressElement, constructorNeedsFormElement, conditional=PROGRESS_TAG
+q interfaceName=HTMLQuoteElement
+rp interfaceName=HTMLElement
+rt interfaceName=HTMLElement
+ruby interfaceName=HTMLElement
+s interfaceName=HTMLElement
+samp interfaceName=HTMLElement
+script constructorNeedsCreatedByParser
+section interfaceName=HTMLElement
+select constructorNeedsFormElement
+small interfaceName=HTMLElement
+source wrapperOnlyIfMediaIsAvailable, conditional=VIDEO
+span interfaceName=HTMLElement
+strike interfaceName=HTMLElement
+strong interfaceName=HTMLElement
+style constructorNeedsCreatedByParser
+sub interfaceName=HTMLElement
+summary interfaceName=HTMLElement
+sup interfaceName=HTMLElement
+table
+tbody interfaceName=HTMLTableSectionElement
+td interfaceName=HTMLTableCellElement
+textarea interfaceName=HTMLTextAreaElement, constructorNeedsFormElement
+tfoot interfaceName=HTMLTableSectionElement
+th interfaceName=HTMLTableCellElement
+thead interfaceName=HTMLTableSectionElement
+title
+tr interfaceName=HTMLTableRowElement
+track interfaceName=HTMLElement
+tt interfaceName=HTMLElement
+u interfaceName=HTMLElement
+ul interfaceName=HTMLUListElement
+var interfaceName=HTMLElement
+video wrapperOnlyIfMediaIsAvailable, conditional=VIDEO
+wbr interfaceName=HTMLElement
+xmp interfaceName=HTMLPreElement
+
+#if ENABLE_XHTMLMP
+noscript interfaceName=HTMLNoScriptElement
+#else
+noscript interfaceName=HTMLElement
+#endif
+
diff --git a/Source/WebCore/html/HTMLTextAreaElement.cpp b/Source/WebCore/html/HTMLTextAreaElement.cpp
new file mode 100644
index 0000000..2741bfe
--- /dev/null
+++ b/Source/WebCore/html/HTMLTextAreaElement.cpp
@@ -0,0 +1,436 @@
+/*
+ * 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 Apple Inc. All rights reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLTextAreaElement.h"
+
+#include "Attribute.h"
+#include "BeforeTextInsertedEvent.h"
+#include "CSSValueKeywords.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "Document.h"
+#include "Event.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
+#include "FocusController.h"
+#include "FormDataList.h"
+#include "Frame.h"
+#include "HTMLNames.h"
+#include "InputElement.h"
+#include "Page.h"
+#include "RenderStyle.h"
+#include "RenderTextControlMultiLine.h"
+#include "ScriptEventListener.h"
+#include "Text.h"
+#include "TextIterator.h"
+#include "VisibleSelection.h"
+#include <wtf/StdLibExtras.h>
+
+#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
+#include "PlatformBridge.h"
+#endif
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static const int defaultRows = 2;
+static const int defaultCols = 20;
+
+static inline void notifyFormStateChanged(const HTMLTextAreaElement* element)
+{
+ Frame* frame = element->document()->frame();
+ if (!frame)
+ return;
+ frame->page()->chrome()->client()->formStateDidChange(element);
+}
+
+HTMLTextAreaElement::HTMLTextAreaElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLTextFormControlElement(tagName, document, form)
+ , m_rows(defaultRows)
+ , m_cols(defaultCols)
+ , m_wrap(SoftWrap)
+ , m_cachedSelectionStart(-1)
+ , m_cachedSelectionEnd(-1)
+ , m_isDirty(false)
+{
+ ASSERT(hasTagName(textareaTag));
+ setFormControlValueMatchesRenderer(true);
+}
+
+PassRefPtr<HTMLTextAreaElement> HTMLTextAreaElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLTextAreaElement(tagName, document, form));
+}
+
+const AtomicString& HTMLTextAreaElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, textarea, ("textarea"));
+ return textarea;
+}
+
+bool HTMLTextAreaElement::saveFormControlState(String& result) const
+{
+ String currentValue = value();
+ if (currentValue == defaultValue())
+ return false;
+ result = currentValue;
+ return true;
+}
+
+void HTMLTextAreaElement::restoreFormControlState(const String& state)
+{
+ setValue(state);
+}
+
+void HTMLTextAreaElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ setNonDirtyValue(defaultValue());
+ HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+}
+
+void HTMLTextAreaElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == rowsAttr) {
+ int rows = attr->value().toInt();
+ if (rows <= 0)
+ rows = defaultRows;
+ if (m_rows != rows) {
+ m_rows = rows;
+ if (renderer())
+ renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ }
+ } else if (attr->name() == colsAttr) {
+ int cols = attr->value().toInt();
+ if (cols <= 0)
+ cols = defaultCols;
+ if (m_cols != cols) {
+ m_cols = cols;
+ if (renderer())
+ renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ }
+ } else if (attr->name() == wrapAttr) {
+ // The virtual/physical values were a Netscape extension of HTML 3.0, now deprecated.
+ // The soft/hard /off values are a recommendation for HTML 4 extension by IE and NS 4.
+ WrapMethod wrap;
+ if (equalIgnoringCase(attr->value(), "physical") || equalIgnoringCase(attr->value(), "hard") || equalIgnoringCase(attr->value(), "on"))
+ wrap = HardWrap;
+ else if (equalIgnoringCase(attr->value(), "off"))
+ wrap = NoWrap;
+ else
+ wrap = SoftWrap;
+ if (wrap != m_wrap) {
+ m_wrap = wrap;
+
+ if (shouldWrapText()) {
+ addCSSProperty(attr, CSSPropertyWhiteSpace, CSSValuePreWrap);
+ addCSSProperty(attr, CSSPropertyWordWrap, CSSValueBreakWord);
+ } else {
+ addCSSProperty(attr, CSSPropertyWhiteSpace, CSSValuePre);
+ addCSSProperty(attr, CSSPropertyWordWrap, CSSValueNormal);
+ }
+
+ if (renderer())
+ renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ }
+ } else if (attr->name() == accesskeyAttr) {
+ // ignore for the moment
+ } else if (attr->name() == alignAttr) {
+ // Don't map 'align' attribute. This matches what Firefox, Opera and IE do.
+ // See http://bugs.webkit.org/show_bug.cgi?id=7075
+ } else if (attr->name() == maxlengthAttr)
+ setNeedsValidityCheck();
+ else
+ HTMLTextFormControlElement::parseMappedAttribute(attr);
+}
+
+RenderObject* HTMLTextAreaElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderTextControlMultiLine(this, placeholderShouldBeVisible());
+}
+
+bool HTMLTextAreaElement::appendFormData(FormDataList& encoding, bool)
+{
+ if (name().isEmpty())
+ return false;
+
+ document()->updateLayout();
+
+ // FIXME: It's not acceptable to ignore the HardWrap setting when there is no renderer.
+ // While we have no evidence this has ever been a practical problem, it would be best to fix it some day.
+ RenderTextControl* control = toRenderTextControl(renderer());
+ const String& text = (m_wrap == HardWrap && control) ? control->textWithHardLineBreaks() : value();
+ encoding.appendData(name(), text);
+ return true;
+}
+
+void HTMLTextAreaElement::reset()
+{
+ setNonDirtyValue(defaultValue());
+}
+
+bool HTMLTextAreaElement::isKeyboardFocusable(KeyboardEvent*) const
+{
+ // If a given text area can be focused at all, then it will always be keyboard focusable.
+ return isFocusable();
+}
+
+bool HTMLTextAreaElement::isMouseFocusable() const
+{
+ return isFocusable();
+}
+
+void HTMLTextAreaElement::updateFocusAppearance(bool restorePreviousSelection)
+{
+ ASSERT(renderer());
+ ASSERT(!document()->childNeedsAndNotInStyleRecalc());
+
+ if (!restorePreviousSelection || m_cachedSelectionStart < 0) {
+#if ENABLE(ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL)
+ // Devices with trackballs or d-pads may focus on a textarea in route
+ // to another focusable node. By selecting all text, the next movement
+ // can more readily be interpreted as moving to the next node.
+ select();
+#else
+ // 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);
+#endif
+ } else {
+ // Restore the cached selection. This matches other browsers' behavior.
+ setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd);
+ }
+
+ if (document()->frame())
+ document()->frame()->selection()->revealSelection();
+}
+
+void HTMLTextAreaElement::defaultEventHandler(Event* event)
+{
+ if (renderer() && (event->isMouseEvent() || event->isDragEvent() || event->isWheelEvent() || event->type() == eventNames().blurEvent))
+ toRenderTextControlMultiLine(renderer())->forwardEvent(event);
+ else if (renderer() && event->isBeforeTextInsertedEvent())
+ handleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(event));
+
+ HTMLFormControlElementWithState::defaultEventHandler(event);
+}
+
+void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event) const
+{
+ ASSERT(event);
+ ASSERT(renderer());
+ int signedMaxLength = maxLength();
+ if (signedMaxLength < 0)
+ return;
+ unsigned unsignedMaxLength = static_cast<unsigned>(signedMaxLength);
+
+ unsigned currentLength = numGraphemeClusters(toRenderTextControl(renderer())->text());
+ // 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 = focused() ? numGraphemeClusters(plainText(document()->frame()->selection()->selection().toNormalizedRange().get())) : 0;
+ ASSERT(currentLength >= selectionLength);
+ unsigned baseLength = currentLength - selectionLength;
+ unsigned appendableLength = unsignedMaxLength > baseLength ? unsignedMaxLength - baseLength : 0;
+ event->setText(sanitizeUserInputValue(event->text(), appendableLength));
+}
+
+String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue, unsigned maxLength)
+{
+ return proposedValue.left(numCharactersInGraphemeClusters(proposedValue, maxLength));
+}
+
+void HTMLTextAreaElement::rendererWillBeDestroyed()
+{
+ updateValue();
+}
+
+void HTMLTextAreaElement::updateValue() const
+{
+ if (formControlValueMatchesRenderer())
+ return;
+
+ ASSERT(renderer());
+ m_value = toRenderTextControl(renderer())->text();
+ const_cast<HTMLTextAreaElement*>(this)->setFormControlValueMatchesRenderer(true);
+ notifyFormStateChanged(this);
+ m_isDirty = true;
+}
+
+String HTMLTextAreaElement::value() const
+{
+ updateValue();
+ return m_value;
+}
+
+void HTMLTextAreaElement::setValue(const String& value)
+{
+ setValueCommon(value);
+ m_isDirty = true;
+ setNeedsValidityCheck();
+}
+
+void HTMLTextAreaElement::setNonDirtyValue(const String& value)
+{
+ setValueCommon(value);
+ m_isDirty = false;
+ setNeedsValidityCheck();
+}
+
+void HTMLTextAreaElement::setValueCommon(const String& value)
+{
+ // Code elsewhere normalizes line endings added by the user via the keyboard or pasting.
+ // We normalize line endings coming from JavaScript here.
+ String normalizedValue = value.isNull() ? "" : value;
+ normalizedValue.replace("\r\n", "\n");
+ normalizedValue.replace('\r', '\n');
+
+ // Return early because we don't want to move the caret or trigger other side effects
+ // when the value isn't changing. This matches Firefox behavior, at least.
+ if (normalizedValue == this->value())
+ return;
+
+ m_value = normalizedValue;
+ updatePlaceholderVisibility(false);
+ setNeedsStyleRecalc();
+ setFormControlValueMatchesRenderer(true);
+
+ // Set the caret to the end of the text value.
+ if (document()->focusedNode() == this) {
+#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
+ // Make sure our UI side textfield changes to match the RenderTextControl
+ PlatformBridge::updateTextfield(document()->view(), this, false, value);
+#endif
+ unsigned endOfString = m_value.length();
+ setSelectionRange(endOfString, endOfString);
+ }
+
+ notifyFormStateChanged(this);
+}
+
+String HTMLTextAreaElement::defaultValue() const
+{
+ String value = "";
+
+ // Since there may be comments, ignore nodes other than text nodes.
+ for (Node* n = firstChild(); n; n = n->nextSibling()) {
+ if (n->isTextNode())
+ value += static_cast<Text*>(n)->data();
+ }
+
+ UChar firstCharacter = value[0];
+ if (firstCharacter == '\r' && value[1] == '\n')
+ value.remove(0, 2);
+ else if (firstCharacter == '\r' || firstCharacter == '\n')
+ value.remove(0, 1);
+
+ return value;
+}
+
+void HTMLTextAreaElement::setDefaultValue(const String& defaultValue)
+{
+ // To preserve comments, remove only the text nodes, then add a single text node.
+
+ Vector<RefPtr<Node> > textNodes;
+ for (Node* n = firstChild(); n; n = n->nextSibling()) {
+ if (n->isTextNode())
+ textNodes.append(n);
+ }
+ ExceptionCode ec;
+ size_t size = textNodes.size();
+ for (size_t i = 0; i < size; ++i)
+ removeChild(textNodes[i].get(), ec);
+
+ // Normalize line endings.
+ // Add an extra line break if the string starts with one, since
+ // the code to read default values from the DOM strips the leading one.
+ String value = defaultValue;
+ value.replace("\r\n", "\n");
+ value.replace('\r', '\n');
+ if (value[0] == '\n')
+ value = "\n" + value;
+
+ insertBefore(document()->createTextNode(value), firstChild(), ec);
+
+ setNonDirtyValue(value);
+}
+
+int HTMLTextAreaElement::maxLength() const
+{
+ bool ok;
+ int value = getAttribute(maxlengthAttr).string().toInt(&ok);
+ return ok && value >= 0 ? value : -1;
+}
+
+void HTMLTextAreaElement::setMaxLength(int newValue, ExceptionCode& ec)
+{
+ if (newValue < 0)
+ ec = INDEX_SIZE_ERR;
+ else
+ setAttribute(maxlengthAttr, String::number(newValue));
+}
+
+bool HTMLTextAreaElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
+{
+ // Return false for the default value even if it is longer than maxLength.
+ if (check == CheckDirtyFlag && !m_isDirty)
+ return false;
+
+ int max = maxLength();
+ if (max < 0)
+ return false;
+ return numGraphemeClusters(value) > static_cast<unsigned>(max);
+}
+
+bool HTMLTextAreaElement::isValidValue(const String& candidate) const
+{
+ return !valueMissing(candidate) && !tooLong(candidate, IgnoreDirtyFlag);
+}
+
+void HTMLTextAreaElement::accessKeyAction(bool)
+{
+ focus();
+}
+
+void HTMLTextAreaElement::setCols(int cols)
+{
+ setAttribute(colsAttr, String::number(cols));
+}
+
+void HTMLTextAreaElement::setRows(int rows)
+{
+ setAttribute(rowsAttr, String::number(rows));
+}
+
+bool HTMLTextAreaElement::shouldUseInputMethod() const
+{
+ return true;
+}
+
+} // namespace
diff --git a/Source/WebCore/html/HTMLTextAreaElement.h b/Source/WebCore/html/HTMLTextAreaElement.h
new file mode 100644
index 0000000..669fcd8
--- /dev/null
+++ b/Source/WebCore/html/HTMLTextAreaElement.h
@@ -0,0 +1,115 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLTextAreaElement_h
+#define HTMLTextAreaElement_h
+
+#include "HTMLFormControlElement.h"
+
+namespace WebCore {
+
+class BeforeTextInsertedEvent;
+class VisibleSelection;
+
+class HTMLTextAreaElement : public HTMLTextFormControlElement {
+public:
+ 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; }
+
+ virtual String value() const;
+ void setValue(const String&);
+ String defaultValue() const;
+ void setDefaultValue(const String&);
+ int textLength() const { return value().length(); }
+ virtual int maxLength() const;
+ void setMaxLength(int, ExceptionCode&);
+ bool valueMissing(const String& value) const { return isRequiredFormControl() && !disabled() && !readOnly() && value.isEmpty(); }
+ bool tooLong(const String&, NeedsToCheckDirtyFlag) const;
+ bool isValidValue(const String&) const;
+
+ void rendererWillBeDestroyed();
+
+ void setCols(int);
+ void setRows(int);
+
+ void cacheSelection(int s, int e) { m_cachedSelectionStart = s; m_cachedSelectionEnd = e; };
+
+private:
+ HTMLTextAreaElement(const QualifiedName&, Document*, HTMLFormElement*);
+
+ enum WrapMethod { NoWrap, SoftWrap, HardWrap };
+
+ void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) const;
+ static String sanitizeUserInputValue(const String&, unsigned maxLength);
+ void updateValue() const;
+ void setNonDirtyValue(const String&);
+ void setValueCommon(const String&);
+
+ virtual bool supportsPlaceholder() const { return true; }
+ virtual bool isEmptyValue() const { return value().isEmpty(); }
+ virtual int cachedSelectionStart() const { return m_cachedSelectionStart; }
+ virtual int cachedSelectionEnd() const { return m_cachedSelectionEnd; }
+
+ virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
+ virtual bool isRequiredFormControl() const { return required(); }
+
+ virtual void defaultEventHandler(Event*);
+
+ virtual bool isEnumeratable() const { return true; }
+
+ virtual const AtomicString& formControlType() const;
+
+ virtual bool saveFormControlState(String& value) const;
+ virtual void restoreFormControlState(const String&);
+
+ virtual bool isTextFormControl() const { return true; }
+
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void parseMappedAttribute(Attribute*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+ virtual bool appendFormData(FormDataList&, bool);
+ virtual void reset();
+ virtual bool isMouseFocusable() const;
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const;
+ virtual void updateFocusAppearance(bool restorePreviousSelection);
+
+ virtual void accessKeyAction(bool sendToAnyElement);
+
+ virtual bool shouldUseInputMethod() const;
+
+ int m_rows;
+ int m_cols;
+ WrapMethod m_wrap;
+ mutable String m_value;
+ int m_cachedSelectionStart;
+ int m_cachedSelectionEnd;
+ mutable bool m_isDirty;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLTextAreaElement.idl b/Source/WebCore/html/HTMLTextAreaElement.idl
new file mode 100644
index 0000000..0f0c9fc
--- /dev/null
+++ b/Source/WebCore/html/HTMLTextAreaElement.idl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLTextAreaElement : HTMLElement {
+ attribute [ConvertNullToNullString] DOMString defaultValue;
+ readonly attribute HTMLFormElement form;
+ readonly attribute ValidityState validity;
+ attribute [Reflect] DOMString accessKey;
+ attribute long cols;
+ attribute [Reflect] boolean disabled;
+ attribute [Reflect] boolean autofocus;
+ attribute long maxLength setter raises(DOMException);
+ attribute [ConvertNullToNullString] DOMString name;
+ attribute [Reflect] DOMString placeholder;
+ attribute [Reflect] boolean readOnly;
+ attribute [Reflect] boolean required;
+ attribute long rows;
+ readonly attribute DOMString type;
+ attribute [ConvertNullToNullString] DOMString value;
+ readonly attribute unsigned long textLength;
+
+ void select();
+
+ readonly attribute boolean willValidate;
+ readonly attribute DOMString validationMessage;
+ boolean checkValidity();
+ void setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error);
+
+ // WinIE & FireFox extension:
+ attribute long selectionStart;
+ attribute long selectionEnd;
+ void setSelectionRange(in long start, in long end);
+ readonly attribute NodeList labels;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLTitleElement.cpp b/Source/WebCore/html/HTMLTitleElement.cpp
new file mode 100644
index 0000000..776c37c
--- /dev/null
+++ b/Source/WebCore/html/HTMLTitleElement.cpp
@@ -0,0 +1,101 @@
+/*
+ * 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, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HTMLTitleElement.h"
+
+#include "Document.h"
+#include "HTMLNames.h"
+#include "Text.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLTitleElement::HTMLTitleElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , m_title("")
+{
+ ASSERT(hasTagName(titleTag));
+}
+
+PassRefPtr<HTMLTitleElement> HTMLTitleElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLTitleElement(tagName, document));
+}
+
+void HTMLTitleElement::insertedIntoDocument()
+{
+ HTMLElement::insertedIntoDocument();
+ document()->setTitle(m_title, this);
+}
+
+void HTMLTitleElement::removedFromDocument()
+{
+ HTMLElement::removedFromDocument();
+ document()->removeTitle(this);
+}
+
+void HTMLTitleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ m_title = "";
+ for (Node* c = firstChild(); c != 0; c = c->nextSibling())
+ if (c->nodeType() == TEXT_NODE || c->nodeType() == CDATA_SECTION_NODE)
+ m_title += c->nodeValue();
+ if (inDocument())
+ document()->setTitle(m_title, this);
+ HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+}
+
+String HTMLTitleElement::text() const
+{
+ String val = "";
+
+ for (Node *n = firstChild(); n; n = n->nextSibling()) {
+ if (n->isTextNode())
+ val += static_cast<Text*>(n)->data();
+ }
+
+ return val;
+}
+
+void HTMLTitleElement::setText(const String &value)
+{
+ ExceptionCode ec = 0;
+ int numChildren = childNodeCount();
+
+ if (numChildren == 1 && firstChild()->isTextNode())
+ static_cast<Text*>(firstChild())->setData(value, ec);
+ 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 (numChildren > 0)
+ removeChildren();
+
+ appendChild(document()->createTextNode(valueCopy.impl()), ec);
+ }
+}
+
+}
diff --git a/Source/WebCore/html/HTMLTitleElement.h b/Source/WebCore/html/HTMLTitleElement.h
new file mode 100644
index 0000000..8b90f56
--- /dev/null
+++ b/Source/WebCore/html/HTMLTitleElement.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+#ifndef HTMLTitleElement_h
+#define HTMLTitleElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLTitleElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLTitleElement> create(const QualifiedName&, Document*);
+
+ String text() const;
+ void setText(const String&);
+
+private:
+ HTMLTitleElement(const QualifiedName&, Document*);
+
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+
+ String m_title;
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLTitleElement.idl b/Source/WebCore/html/HTMLTitleElement.idl
new file mode 100644
index 0000000..de857e8
--- /dev/null
+++ b/Source/WebCore/html/HTMLTitleElement.idl
@@ -0,0 +1,26 @@
+/*
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLTitleElement : HTMLElement {
+ attribute [ConvertNullToNullString] DOMString text;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLUListElement.cpp b/Source/WebCore/html/HTMLUListElement.cpp
new file mode 100644
index 0000000..4b121aa
--- /dev/null
+++ b/Source/WebCore/html/HTMLUListElement.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "HTMLUListElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLUListElement::HTMLUListElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(ulTag));
+}
+
+PassRefPtr<HTMLUListElement> HTMLUListElement::create(Document* document)
+{
+ return adoptRef(new HTMLUListElement(ulTag, document));
+}
+
+PassRefPtr<HTMLUListElement> HTMLUListElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLUListElement(tagName, document));
+}
+
+bool HTMLUListElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == typeAttr) {
+ result = eUnorderedList;
+ return false;
+ }
+
+ return HTMLElement::mapToEntry(attrName, result);
+}
+
+void HTMLUListElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == typeAttr)
+ addCSSProperty(attr, CSSPropertyListStyleType, attr->value());
+ else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLUListElement.h b/Source/WebCore/html/HTMLUListElement.h
new file mode 100644
index 0000000..f91bf1c
--- /dev/null
+++ b/Source/WebCore/html/HTMLUListElement.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef HTMLUListElement_h
+#define HTMLUListElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLUListElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLUListElement> create(Document*);
+ static PassRefPtr<HTMLUListElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLUListElement(const QualifiedName&, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+};
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/HTMLUListElement.idl b/Source/WebCore/html/HTMLUListElement.idl
new file mode 100644
index 0000000..221dcca
--- /dev/null
+++ b/Source/WebCore/html/HTMLUListElement.idl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface HTMLUListElement : HTMLElement {
+ attribute [Reflect] boolean compact;
+ attribute [Reflect] DOMString type;
+ };
+
+}
diff --git a/Source/WebCore/html/HTMLVideoElement.cpp b/Source/WebCore/html/HTMLVideoElement.cpp
new file mode 100644
index 0000000..bbda53a
--- /dev/null
+++ b/Source/WebCore/html/HTMLVideoElement.cpp
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2007, 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,
+ * 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 "HTMLVideoElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "Document.h"
+#include "ExceptionCode.h"
+#include "HTMLImageLoader.h"
+#include "HTMLNames.h"
+#include "Page.h"
+#include "RenderImage.h"
+#include "RenderVideo.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLVideoElement::HTMLVideoElement(const QualifiedName& tagName, Document* document)
+ : HTMLMediaElement(tagName, document)
+{
+ ASSERT(hasTagName(videoTag));
+}
+
+PassRefPtr<HTMLVideoElement> HTMLVideoElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLVideoElement(tagName, document));
+}
+
+bool HTMLVideoElement::rendererIsNeeded(RenderStyle* style)
+{
+ return HTMLElement::rendererIsNeeded(style);
+}
+
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+RenderObject* HTMLVideoElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderVideo(this);
+}
+#endif
+
+void HTMLVideoElement::attach()
+{
+ HTMLMediaElement::attach();
+
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ updateDisplayState();
+ if (shouldDisplayPosterImage()) {
+ if (!m_imageLoader)
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader->updateFromElement();
+ if (renderer())
+ toRenderImage(renderer())->imageResource()->setCachedImage(m_imageLoader->image());
+ }
+#endif
+}
+
+void HTMLVideoElement::detach()
+{
+ HTMLMediaElement::detach();
+
+ if (!shouldDisplayPosterImage() && m_imageLoader)
+ m_imageLoader.clear();
+}
+
+void HTMLVideoElement::parseMappedAttribute(Attribute* attr)
+{
+ const QualifiedName& attrName = attr->name();
+
+ if (attrName == posterAttr) {
+ // 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 (shouldDisplayPosterImage()) {
+ if (!m_imageLoader)
+ m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader->updateFromElementIgnoringPreviousError();
+ } else {
+ if (m_imageLoader)
+ m_imageLoader.clear();
+ if (renderer())
+ toRenderImage(renderer())->imageResource()->setCachedImage(0);
+ }
+#endif
+ } else if (attrName == widthAttr)
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
+ else if (attrName == heightAttr)
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
+ else
+ HTMLMediaElement::parseMappedAttribute(attr);
+}
+
+bool HTMLVideoElement::supportsFullscreen() const
+{
+ Page* page = document() ? document()->page() : 0;
+ if (!page)
+ return false;
+
+ if (!player() || !player()->supportsFullscreen() || !player()->hasVideo())
+ return false;
+
+ // Check with the platform client.
+ return page->chrome()->client()->supportsFullscreenForNode(this);
+}
+
+unsigned HTMLVideoElement::videoWidth() const
+{
+ if (!player())
+ return 0;
+ return player()->naturalSize().width();
+}
+
+unsigned HTMLVideoElement::videoHeight() const
+{
+ if (!player())
+ return 0;
+ return player()->naturalSize().height();
+}
+
+unsigned HTMLVideoElement::width() const
+{
+ bool ok;
+ unsigned w = getAttribute(widthAttr).string().toUInt(&ok);
+ return ok ? w : 0;
+}
+
+unsigned HTMLVideoElement::height() const
+{
+ bool ok;
+ unsigned h = getAttribute(heightAttr).string().toUInt(&ok);
+ return ok ? h : 0;
+}
+
+bool HTMLVideoElement::isURLAttribute(Attribute* attribute) const
+{
+ return HTMLMediaElement::isURLAttribute(attribute)
+ || attribute->name() == posterAttr;
+}
+
+const QualifiedName& HTMLVideoElement::imageSourceAttributeName() const
+{
+ return posterAttr;
+}
+
+void HTMLVideoElement::setDisplayMode(DisplayMode mode)
+{
+ DisplayMode oldMode = displayMode();
+ KURL poster = getNonEmptyURLAttribute(posterAttr);
+
+ if (!poster.isEmpty()) {
+ // We have a poster path, but only show it until the user triggers display by playing or seeking and the
+ // media engine has something to display.
+ if (mode == Video) {
+ if (oldMode != Video && player())
+ player()->prepareForRendering();
+ if (!hasAvailableVideoFrame())
+ mode = Poster;
+ }
+ } else if (oldMode != Video && player())
+ player()->prepareForRendering();
+
+ HTMLMediaElement::setDisplayMode(mode);
+
+ if (player() && player()->canLoadPoster())
+ player()->setPoster(poster);
+
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (renderer() && displayMode() != oldMode)
+ renderer()->updateFromElement();
+#endif
+}
+
+void HTMLVideoElement::updateDisplayState()
+{
+ if (getNonEmptyURLAttribute(posterAttr).isEmpty())
+ setDisplayMode(Video);
+ else if (displayMode() < Poster)
+ setDisplayMode(Poster);
+}
+
+void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
+{
+ MediaPlayer* player = HTMLMediaElement::player();
+ if (!player)
+ return;
+
+ player->setVisible(true); // Make player visible or it won't draw.
+ player->paintCurrentFrameInContext(context, destRect);
+}
+
+bool HTMLVideoElement::hasAvailableVideoFrame() const
+{
+ if (!player())
+ return false;
+
+ return player()->hasAvailableVideoFrame();
+}
+
+void HTMLVideoElement::webkitEnterFullscreen(bool isUserGesture, ExceptionCode& ec)
+{
+ if (isFullscreen())
+ return;
+
+ // Generate an exception if this isn't called in response to a user gesture, or if the
+ // element does not support fullscreen.
+ if (!isUserGesture || !supportsFullscreen()) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+
+ enterFullscreen();
+}
+
+void HTMLVideoElement::webkitExitFullscreen()
+{
+ if (isFullscreen())
+ exitFullscreen();
+}
+
+bool HTMLVideoElement::webkitSupportsFullscreen()
+{
+ return supportsFullscreen();
+}
+
+bool HTMLVideoElement::webkitDisplayingFullscreen()
+{
+ return isFullscreen();
+}
+
+void HTMLVideoElement::willMoveToNewOwnerDocument()
+{
+ if (m_imageLoader)
+ m_imageLoader->elementWillMoveToNewOwnerDocument();
+ HTMLMediaElement::willMoveToNewOwnerDocument();
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/html/HTMLVideoElement.h b/Source/WebCore/html/HTMLVideoElement.h
new file mode 100644
index 0000000..d893411
--- /dev/null
+++ b/Source/WebCore/html/HTMLVideoElement.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2007, 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,
+ * 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 HTMLVideoElement_h
+#define HTMLVideoElement_h
+
+#if ENABLE(VIDEO)
+
+#include "HTMLMediaElement.h"
+
+namespace WebCore {
+
+class HTMLImageLoader;
+
+class HTMLVideoElement : public HTMLMediaElement {
+public:
+ static PassRefPtr<HTMLVideoElement> create(const QualifiedName&, Document*);
+
+ unsigned width() const;
+ unsigned height() const;
+
+ unsigned videoWidth() const;
+ unsigned videoHeight() const;
+
+ // Fullscreen
+ void webkitEnterFullscreen(bool isUserGesture, ExceptionCode&);
+ void webkitExitFullscreen();
+ bool webkitSupportsFullscreen();
+ bool webkitDisplayingFullscreen();
+
+ // FIXME: Maintain "FullScreen" capitalization scheme for backwards compatibility.
+ // https://bugs.webkit.org/show_bug.cgi?id=36081
+ void webkitEnterFullScreen(bool isUserGesture, ExceptionCode& ec) { webkitEnterFullscreen(isUserGesture, ec); }
+ void webkitExitFullScreen() { webkitExitFullscreen(); }
+
+ // Used by canvas to gain raw pixel access
+ void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
+
+ bool shouldDisplayPosterImage() const { return displayMode() == Poster; }
+
+private:
+ HTMLVideoElement(const QualifiedName&, Document*);
+
+ virtual bool rendererIsNeeded(RenderStyle*);
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+#endif
+ virtual void attach();
+ virtual void detach();
+ virtual void parseMappedAttribute(Attribute*);
+ virtual bool isVideo() const { return true; }
+ virtual bool hasVideo() const { return player() && player()->hasVideo(); }
+ virtual bool supportsFullscreen() const;
+ virtual bool isURLAttribute(Attribute*) const;
+ virtual const QualifiedName& imageSourceAttributeName() const;
+
+ virtual bool hasAvailableVideoFrame() const;
+ virtual void updateDisplayState();
+
+ virtual void willMoveToNewOwnerDocument();
+
+ virtual void setDisplayMode(DisplayMode);
+
+ OwnPtr<HTMLImageLoader> m_imageLoader;
+
+};
+
+} //namespace
+
+#endif
+#endif
diff --git a/Source/WebCore/html/HTMLVideoElement.idl b/Source/WebCore/html/HTMLVideoElement.idl
new file mode 100644
index 0000000..770e4b2
--- /dev/null
+++ b/Source/WebCore/html/HTMLVideoElement.idl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007, 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,
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=VIDEO,
+ GenerateNativeConverter
+ ] HTMLVideoElement : HTMLMediaElement {
+ attribute [Reflect] unsigned long width;
+ attribute [Reflect] unsigned long height;
+ readonly attribute unsigned long videoWidth;
+ readonly attribute unsigned long videoHeight;
+ attribute [Reflect, URL] DOMString poster;
+
+ readonly attribute boolean webkitSupportsFullscreen;
+ readonly attribute boolean webkitDisplayingFullscreen;
+
+ [NeedsUserGestureCheck] void webkitEnterFullscreen() raises (DOMException);
+ void webkitExitFullscreen();
+
+ [NeedsUserGestureCheck] void webkitEnterFullScreen() raises (DOMException);
+ void webkitExitFullScreen();
+ };
+}
diff --git a/Source/WebCore/html/HTMLViewSourceDocument.cpp b/Source/WebCore/html/HTMLViewSourceDocument.cpp
new file mode 100644
index 0000000..27eaf51
--- /dev/null
+++ b/Source/WebCore/html/HTMLViewSourceDocument.cpp
@@ -0,0 +1,317 @@
+/*
+ * 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 "Attribute.h"
+#include "DOMImplementation.h"
+#include "HTMLAnchorElement.h"
+#include "HTMLBaseElement.h"
+#include "HTMLBodyElement.h"
+#include "HTMLDivElement.h"
+#include "HTMLHtmlElement.h"
+#include "HTMLNames.h"
+#include "HTMLTableCellElement.h"
+#include "HTMLTableElement.h"
+#include "HTMLTableRowElement.h"
+#include "HTMLTableSectionElement.h"
+#include "HTMLToken.h"
+#include "HTMLViewSourceParser.h"
+#include "SegmentedString.h"
+#include "Text.h"
+#include "TextViewSourceParser.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLViewSourceDocument::HTMLViewSourceDocument(Frame* frame, const KURL& url, const String& mimeType)
+ : HTMLDocument(frame, url)
+ , m_type(mimeType)
+{
+ setUsesBeforeAfterRules(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)
+#if ENABLE(XHTMLMP)
+ || m_type == "application/vnd.wap.xhtml+xml"
+#endif
+ )
+ return HTMLViewSourceParser::create(this);
+
+ return TextViewSourceParser::create(this);
+}
+
+void HTMLViewSourceDocument::createContainingTable()
+{
+ RefPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(this);
+ parserAddChild(html);
+ html->attach();
+ RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(this);
+ html->parserAddChild(body);
+ body->attach();
+
+ // 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);
+ RefPtr<NamedNodeMap> attrs = NamedNodeMap::create();
+ attrs->addAttribute(Attribute::createMapped(classAttr, "webkit-line-gutter-backdrop"));
+ div->setAttributeMap(attrs.release());
+ body->parserAddChild(div);
+ div->attach();
+
+ RefPtr<HTMLTableElement> table = HTMLTableElement::create(this);
+ body->parserAddChild(table);
+ table->attach();
+ m_tbody = HTMLTableSectionElement::create(tbodyTag, this);
+ table->parserAddChild(m_tbody);
+ m_tbody->attach();
+ 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:
+ 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().data(), token.name().size());
+
+ 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->m_name.data(), iter->m_name.size());
+ String value(iter->m_value.data(), iter->m_value.size());
+
+ index = addRange(source, index, iter->m_nameRange.m_start - token.startIndex(), "");
+ index = addRange(source, index, iter->m_nameRange.m_end - token.startIndex(), "webkit-html-attribute-name");
+
+ if (tagName == baseTag && name == hrefAttr)
+ m_current = addBase(value);
+
+ index = addRange(source, index, iter->m_valueRange.m_start - token.startIndex(), "");
+
+ bool isLink = name == srcAttr || name == hrefAttr;
+ index = addRange(source, index, iter->m_valueRange.m_end - token.startIndex(), "webkit-html-attribute-value", isLink, tagName == aTag);
+
+ ++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);
+ RefPtr<NamedNodeMap> attrs = NamedNodeMap::create();
+ attrs->addAttribute(Attribute::createMapped(classAttr, className));
+ span->setAttributeMap(attrs.release());
+ m_current->parserAddChild(span);
+ span->attach();
+ return span.release();
+}
+
+void HTMLViewSourceDocument::addLine(const AtomicString& className)
+{
+ // Create a table row.
+ RefPtr<HTMLTableRowElement> trow = HTMLTableRowElement::create(this);
+ m_tbody->parserAddChild(trow);
+ trow->attach();
+
+ // Create a cell that will hold the line number (it is generated in the stylesheet using counters).
+ RefPtr<HTMLTableCellElement> td = HTMLTableCellElement::create(tdTag, this);
+ RefPtr<NamedNodeMap> attrs = NamedNodeMap::create();
+ attrs->addAttribute(Attribute::createMapped(classAttr, "webkit-line-number"));
+ td->setAttributeMap(attrs.release());
+ trow->parserAddChild(td);
+ td->attach();
+
+ // Create a second cell for the line contents
+ td = HTMLTableCellElement::create(tdTag, this);
+ attrs = NamedNodeMap::create();
+ attrs->addAttribute(Attribute::createMapped(classAttr, "webkit-line-content"));
+ td->setAttributeMap(attrs.release());
+ trow->parserAddChild(td);
+ td->attach();
+ m_current = m_td = td;
+
+#ifdef DEBUG_LINE_NUMBERS
+ RefPtr<Text> lineNumberText = Text::create(this, String::number(parser()->lineNumber() + 1) + " ");
+ td->addChild(lineNumberText);
+ lineNumberText->attach();
+#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::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 (substring.isEmpty()) {
+ if (i == size - 1)
+ break;
+ substring = " ";
+ }
+ if (m_current == m_tbody)
+ addLine(className);
+ RefPtr<Text> t = Text::create(this, substring);
+ m_current->parserAddChild(t);
+ t->attach();
+ if (i < size - 1)
+ m_current = m_tbody;
+ }
+
+ // Set current to m_tbody if the last character was a newline.
+ if (text[text.length() - 1] == '\n')
+ m_current = m_tbody;
+}
+
+int HTMLViewSourceDocument::addRange(const String& source, int start, int end, const String& className, bool isLink, bool isAnchor)
+{
+ ASSERT(start <= end);
+ if (start == end)
+ return start;
+
+ String text = source.substring(start, end - start);
+ if (!className.isEmpty()) {
+ if (isLink)
+ m_current = addLink(text, isAnchor);
+ else
+ m_current = addSpanWithClassName(className);
+ }
+ addText(text, className);
+ if (!className.isEmpty() && m_current != m_tbody)
+ m_current = static_cast<Element*>(m_current->parentNode());
+ return end;
+}
+
+PassRefPtr<Element> HTMLViewSourceDocument::addBase(const AtomicString& href)
+{
+ RefPtr<HTMLBaseElement> base = HTMLBaseElement::create(baseTag, this);
+ RefPtr<NamedNodeMap> attributeMap = NamedNodeMap::create();
+ attributeMap->addAttribute(Attribute::createMapped(hrefAttr, href));
+ base->setAttributeMap(attributeMap.release());
+ m_current->parserAddChild(base);
+ base->attach();
+ 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);
+ RefPtr<NamedNodeMap> attrs = NamedNodeMap::create();
+ const char* classValue;
+ if (isAnchor)
+ classValue = "webkit-html-attribute-value webkit-html-external-link";
+ else
+ classValue = "webkit-html-attribute-value webkit-html-resource-link";
+ attrs->addAttribute(Attribute::createMapped(classAttr, classValue));
+ attrs->addAttribute(Attribute::createMapped(targetAttr, "_blank"));
+ attrs->addAttribute(Attribute::createMapped(hrefAttr, url));
+ anchor->setAttributeMap(attrs.release());
+ m_current->parserAddChild(anchor);
+ anchor->attach();
+ return anchor.release();
+}
+
+}
diff --git a/Source/WebCore/html/HTMLViewSourceDocument.h b/Source/WebCore/html/HTMLViewSourceDocument.h
new file mode 100644
index 0000000..30e4df3
--- /dev/null
+++ b/Source/WebCore/html/HTMLViewSourceDocument.h
@@ -0,0 +1,72 @@
+/*
+ * 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 : public HTMLDocument {
+public:
+ static PassRefPtr<HTMLViewSourceDocument> create(Frame* frame, const KURL& url, const String& mimeType)
+ {
+ return adoptRef(new HTMLViewSourceDocument(frame, url, mimeType));
+ }
+
+ void addSource(const String&, HTMLToken&);
+
+private:
+ HTMLViewSourceDocument(Frame*, const KURL&, const String& mimeType);
+
+ // Returns HTMLViewSourceParser or TextDocumentParser based on m_type.
+ virtual PassRefPtr<DocumentParser> createParser();
+
+ 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 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);
+ 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/HiddenInputType.cpp b/Source/WebCore/html/HiddenInputType.cpp
new file mode 100644
index 0000000..3aed1db
--- /dev/null
+++ b/Source/WebCore/html/HiddenInputType.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 "HiddenInputType.h"
+
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<InputType> HiddenInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new HiddenInputType(element));
+}
+
+const AtomicString& HiddenInputType::formControlType() const {
+ return InputTypeNames::hidden();
+}
+
+bool HiddenInputType::supportsValidation() const
+{
+ return false;
+}
+
+RenderObject* HiddenInputType::createRenderer(RenderArena*, RenderStyle*) const
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+void HiddenInputType::accessKeyAction(bool)
+{
+}
+
+bool HiddenInputType::rendererIsNeeded()
+{
+ return false;
+}
+
+bool HiddenInputType::storesValueSeparateFromAttribute()
+{
+ return false;
+}
+
+bool HiddenInputType::isHiddenType() const
+{
+ return true;
+}
+
+bool HiddenInputType::shouldRespectHeightAndWidthAttributes()
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/HiddenInputType.h b/Source/WebCore/html/HiddenInputType.h
new file mode 100644
index 0000000..e232a36
--- /dev/null
+++ b/Source/WebCore/html/HiddenInputType.h
@@ -0,0 +1,56 @@
+/*
+ * 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:
+ *
+ * * 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 HiddenInputType_h
+#define HiddenInputType_h
+
+#include "InputType.h"
+
+namespace WebCore {
+
+class HiddenInputType : public InputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ HiddenInputType(HTMLInputElement* element) : InputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool supportsValidation() const;
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
+ virtual void accessKeyAction(bool sendToAnyElement);
+ virtual bool rendererIsNeeded();
+ virtual bool storesValueSeparateFromAttribute();
+ virtual bool isHiddenType() const;
+ virtual bool shouldRespectHeightAndWidthAttributes();
+};
+
+} // namespace WebCore
+
+#endif // HiddenInputType_h
diff --git a/Source/WebCore/html/ImageData.cpp b/Source/WebCore/html/ImageData.cpp
new file mode 100644
index 0000000..ad24136
--- /dev/null
+++ b/Source/WebCore/html/ImageData.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 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
+ * 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 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.
+ *
+ * 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"
+#include "ImageData.h"
+
+namespace WebCore {
+
+PassRefPtr<ImageData> ImageData::create(const IntSize& size)
+{
+ return adoptRef(new ImageData(size));
+}
+
+PassRefPtr<ImageData> ImageData::create(const IntSize& size, PassRefPtr<ByteArray> byteArray)
+{
+ return adoptRef(new ImageData(size, byteArray));
+}
+
+ImageData::ImageData(const IntSize& size)
+ : m_size(size)
+ , m_data(CanvasPixelArray::create(size.width() * size.height() * 4))
+{
+}
+
+ImageData::ImageData(const IntSize& size, PassRefPtr<ByteArray> byteArray)
+ : m_size(size)
+ , m_data(CanvasPixelArray::create(byteArray))
+{
+}
+
+}
+
diff --git a/Source/WebCore/html/ImageData.h b/Source/WebCore/html/ImageData.h
new file mode 100644
index 0000000..35d08e7
--- /dev/null
+++ b/Source/WebCore/html/ImageData.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 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.
+ * 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.
+ *
+ * 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 ImageData_h
+#define ImageData_h
+
+#include "CanvasPixelArray.h"
+#include "IntSize.h"
+#include <wtf/ByteArray.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class ImageData : public RefCounted<ImageData> {
+public:
+ static PassRefPtr<ImageData> create(const IntSize&);
+ static PassRefPtr<ImageData> create(const IntSize&, PassRefPtr<ByteArray>);
+
+ IntSize size() const { return m_size; }
+ int width() const { return m_size.width(); }
+ int height() const { return m_size.height(); }
+ CanvasPixelArray* data() const { return m_data.get(); }
+
+private:
+ ImageData(const IntSize&);
+ ImageData(const IntSize&, PassRefPtr<ByteArray>);
+
+ IntSize m_size;
+ RefPtr<CanvasPixelArray> m_data;
+};
+
+} // namespace WebCore
+
+#endif // ImageData_h
diff --git a/Source/WebCore/html/ImageData.idl b/Source/WebCore/html/ImageData.idl
new file mode 100644
index 0000000..6050205
--- /dev/null
+++ b/Source/WebCore/html/ImageData.idl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 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.
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+
+ interface [
+ CustomToJS
+ ] ImageData {
+ readonly attribute long width;
+ readonly attribute long height;
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
+ readonly attribute CanvasPixelArray data;
+#endif
+ };
+
+}
diff --git a/Source/WebCore/html/ImageDocument.cpp b/Source/WebCore/html/ImageDocument.cpp
new file mode 100644
index 0000000..a42ccc8
--- /dev/null
+++ b/Source/WebCore/html/ImageDocument.cpp
@@ -0,0 +1,420 @@
+/*
+ * 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
+ * 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 "ImageDocument.h"
+
+#include "CachedImage.h"
+#include "DocumentLoader.h"
+#include "EventListener.h"
+#include "EventNames.h"
+#include "Frame.h"
+#include "FrameLoaderClient.h"
+#include "FrameView.h"
+#include "HTMLHtmlElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLNames.h"
+#include "LocalizedStrings.h"
+#include "MouseEvent.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "RawDataDocumentParser.h"
+#include "Settings.h"
+
+using std::min;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+class ImageEventListener : public EventListener {
+public:
+ 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);
+
+private:
+ ImageEventListener(ImageDocument* document)
+ : EventListener(ImageEventListenerType)
+ , m_doc(document)
+ {
+ }
+
+ virtual void handleEvent(ScriptExecutionContext*, Event*);
+
+ ImageDocument* m_doc;
+};
+
+class ImageDocumentParser : public RawDataDocumentParser {
+public:
+ static PassRefPtr<ImageDocumentParser> create(ImageDocument* document)
+ {
+ return adoptRef(new ImageDocumentParser(document));
+ }
+
+ ImageDocument* document() const
+ {
+ return static_cast<ImageDocument*>(RawDataDocumentParser::document());
+ }
+
+private:
+ ImageDocumentParser(ImageDocument* document)
+ : RawDataDocumentParser(document)
+ {
+ }
+
+ virtual void appendBytes(DocumentWriter*, const char*, int, bool);
+ virtual void finish();
+};
+
+class ImageDocumentElement : public HTMLImageElement {
+public:
+ static PassRefPtr<ImageDocumentElement> create(ImageDocument*);
+
+private:
+ ImageDocumentElement(ImageDocument* document)
+ : HTMLImageElement(imgTag, document)
+ , m_imageDocument(document)
+ {
+ }
+
+ virtual ~ImageDocumentElement();
+ virtual void willMoveToNewOwnerDocument();
+
+ ImageDocument* m_imageDocument;
+};
+
+inline PassRefPtr<ImageDocumentElement> ImageDocumentElement::create(ImageDocument* document)
+{
+ return adoptRef(new ImageDocumentElement(document));
+}
+
+// --------
+
+static float pageZoomFactor(const Document* document)
+{
+ Frame* frame = document->frame();
+ return frame ? frame->pageZoomFactor() : 1;
+}
+
+void ImageDocumentParser::appendBytes(DocumentWriter*, const char*, int, bool)
+{
+ Frame* frame = document()->frame();
+ Settings* settings = frame->settings();
+ if (!frame->loader()->client()->allowImages(!settings || settings->areImagesEnabled()))
+ return;
+
+ CachedImage* cachedImage = document()->cachedImage();
+ cachedImage->data(frame->loader()->documentLoader()->mainResourceData(), false);
+
+ document()->imageChanged();
+}
+
+void ImageDocumentParser::finish()
+{
+ if (!isStopped() && document()->imageElement()) {
+ CachedImage* cachedImage = document()->cachedImage();
+ RefPtr<SharedBuffer> 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 (document()->frame()->loader()->documentLoader()->isLoadingMultipartContent())
+ data = data->copy();
+
+ cachedImage->data(data.release(), true);
+ cachedImage->finish();
+
+ cachedImage->setResponse(document()->frame()->loader()->documentLoader()->response());
+
+ // Report the natural image size in the page title, regardless of zoom
+ // level.
+ IntSize size = cachedImage->imageSize(1.0f);
+ if (size.width()) {
+ // 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));
+ }
+
+ document()->imageChanged();
+ }
+
+ document()->finishedParsing();
+}
+
+// --------
+
+ImageDocument::ImageDocument(Frame* frame, const KURL& url)
+ : HTMLDocument(frame, url)
+ , m_imageElement(0)
+ , m_imageSizeIsKnown(false)
+ , m_didShrinkImage(false)
+ , m_shouldShrinkImage(shouldShrinkToFit())
+{
+ setCompatibilityMode(QuirksMode);
+ lockCompatibilityMode();
+}
+
+PassRefPtr<DocumentParser> ImageDocument::createParser()
+{
+ return ImageDocumentParser::create(this);
+}
+
+void ImageDocument::createDocumentStructure()
+{
+ ExceptionCode ec;
+
+ RefPtr<Element> rootElement = Document::createElement(htmlTag, false);
+ appendChild(rootElement, ec);
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ static_cast<HTMLHtmlElement*>(rootElement.get())->insertedByParser();
+#endif
+
+ if (frame() && frame()->loader())
+ frame()->loader()->dispatchDocumentElementAvailable();
+
+ RefPtr<Element> body = Document::createElement(bodyTag, false);
+ body->setAttribute(styleAttr, "margin: 0px;");
+
+ rootElement->appendChild(body, ec);
+
+ RefPtr<ImageDocumentElement> imageElement = ImageDocumentElement::create(this);
+
+ imageElement->setAttribute(styleAttr, "-webkit-user-select: none");
+ imageElement->setLoadManually(true);
+ imageElement->setSrc(url().string());
+
+ body->appendChild(imageElement, ec);
+
+ 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);
+ }
+
+ m_imageElement = imageElement.get();
+}
+
+float ImageDocument::scale() const
+{
+ if (!m_imageElement)
+ return 1.0f;
+
+ FrameView* view = frame()->view();
+ if (!view)
+ return 1;
+
+ IntSize imageSize = m_imageElement->cachedImage()->imageSize(pageZoomFactor(this));
+ IntSize windowSize = IntSize(view->width(), view->height());
+
+ float widthScale = (float)windowSize.width() / imageSize.width();
+ float heightScale = (float)windowSize.height() / imageSize.height();
+
+ return min(widthScale, heightScale);
+}
+
+void ImageDocument::resizeImageToFit()
+{
+ if (!m_imageElement)
+ return;
+
+ IntSize imageSize = m_imageElement->cachedImage()->imageSize(pageZoomFactor(this));
+
+ float scale = this->scale();
+ m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale));
+ m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale));
+
+ ExceptionCode ec;
+ m_imageElement->style()->setProperty("cursor", "-webkit-zoom-in", ec);
+}
+
+void ImageDocument::imageClicked(int x, int y)
+{
+ 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));
+ }
+}
+
+void ImageDocument::imageChanged()
+{
+ ASSERT(m_imageElement);
+
+ if (m_imageSizeIsKnown)
+ return;
+
+ if (m_imageElement->cachedImage()->imageSize(pageZoomFactor(this)).isEmpty())
+ return;
+
+ m_imageSizeIsKnown = true;
+
+ if (shouldShrinkToFit()) {
+ // Force resizing of the image
+ windowSizeChanged();
+ }
+}
+
+void ImageDocument::restoreImageSize()
+{
+ if (!m_imageElement || !m_imageSizeIsKnown)
+ return;
+
+ m_imageElement->setWidth(m_imageElement->cachedImage()->imageSize(pageZoomFactor(this)).width());
+ m_imageElement->setHeight(m_imageElement->cachedImage()->imageSize(pageZoomFactor(this)).height());
+
+ ExceptionCode ec;
+ if (imageFitsInWindow())
+ m_imageElement->style()->removeProperty("cursor", ec);
+ else
+ m_imageElement->style()->setProperty("cursor", "-webkit-zoom-out", ec);
+
+ m_didShrinkImage = false;
+}
+
+bool ImageDocument::imageFitsInWindow() const
+{
+ if (!m_imageElement)
+ return true;
+
+ FrameView* view = frame()->view();
+ if (!view)
+ return true;
+
+ IntSize imageSize = m_imageElement->cachedImage()->imageSize(pageZoomFactor(this));
+ IntSize windowSize = IntSize(view->width(), view->height());
+
+ return imageSize.width() <= windowSize.width() && imageSize.height() <= windowSize.height();
+}
+
+void ImageDocument::windowSizeChanged()
+{
+ if (!m_imageElement || !m_imageSizeIsKnown)
+ return;
+
+ bool fitsInWindow = imageFitsInWindow();
+
+ // 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) {
+ ExceptionCode ec;
+
+ if (fitsInWindow)
+ m_imageElement->style()->removeProperty("cursor", ec);
+ else
+ m_imageElement->style()->setProperty("cursor", "-webkit-zoom-out", ec);
+ return;
+ }
+
+ if (m_didShrinkImage) {
+ // If the window has been resized so that the image fits, restore the image size
+ // otherwise update the restored image size.
+ if (fitsInWindow)
+ restoreImageSize();
+ else
+ resizeImageToFit();
+ } else {
+ // If the image isn't resized but needs to be, then resize it.
+ if (!fitsInWindow) {
+ resizeImageToFit();
+ m_didShrinkImage = true;
+ }
+ }
+}
+
+CachedImage* ImageDocument::cachedImage()
+{
+ if (!m_imageElement)
+ createDocumentStructure();
+
+ return m_imageElement->cachedImage();
+}
+
+bool ImageDocument::shouldShrinkToFit() const
+{
+ return frame()->page()->settings()->shrinksStandaloneImagesToFit() &&
+ frame()->page()->mainFrame() == frame();
+}
+
+// --------
+
+void ImageEventListener::handleEvent(ScriptExecutionContext*, Event* event)
+{
+ if (event->type() == eventNames().resizeEvent)
+ 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& listener)
+{
+ if (const ImageEventListener* imageEventListener = ImageEventListener::cast(&listener))
+ return m_doc == imageEventListener->m_doc;
+ return false;
+}
+
+// --------
+
+ImageDocumentElement::~ImageDocumentElement()
+{
+ if (m_imageDocument)
+ m_imageDocument->disconnectImageElement();
+}
+
+void ImageDocumentElement::willMoveToNewOwnerDocument()
+{
+ if (m_imageDocument) {
+ m_imageDocument->disconnectImageElement();
+ m_imageDocument = 0;
+ }
+ HTMLImageElement::willMoveToNewOwnerDocument();
+}
+
+}
diff --git a/Source/WebCore/html/ImageDocument.h b/Source/WebCore/html/ImageDocument.h
new file mode 100644
index 0000000..5d00bd6
--- /dev/null
+++ b/Source/WebCore/html/ImageDocument.h
@@ -0,0 +1,76 @@
+/*
+ * 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
+ * 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 ImageDocument_h
+#define ImageDocument_h
+
+#include "HTMLDocument.h"
+
+namespace WebCore {
+
+class ImageDocumentElement;
+
+class ImageDocument : public HTMLDocument {
+public:
+ static PassRefPtr<ImageDocument> create(Frame* frame, const KURL& url)
+ {
+ return adoptRef(new ImageDocument(frame, url));
+ }
+
+ CachedImage* cachedImage();
+ ImageDocumentElement* imageElement() const { return m_imageElement; }
+ void disconnectImageElement() { m_imageElement = 0; }
+
+ void windowSizeChanged();
+ void imageChanged();
+ void imageClicked(int x, int y);
+
+private:
+ ImageDocument(Frame*, const KURL&);
+
+ virtual PassRefPtr<DocumentParser> createParser();
+ virtual bool isImageDocument() const { return true; }
+
+ void createDocumentStructure();
+ void resizeImageToFit();
+ void restoreImageSize();
+ bool imageFitsInWindow() const;
+ bool shouldShrinkToFit() const;
+ float scale() const;
+
+ ImageDocumentElement* m_imageElement;
+
+ // Whether enough of the image has been loaded to determine its size
+ bool m_imageSizeIsKnown;
+
+ // Whether the image is shrunk to fit or not
+ bool m_didShrinkImage;
+
+ // Whether the image should be shrunk or not
+ bool m_shouldShrinkImage;
+};
+
+}
+
+#endif // ImageDocument_h
diff --git a/Source/WebCore/html/ImageInputType.cpp b/Source/WebCore/html/ImageInputType.cpp
new file mode 100644
index 0000000..85b3329
--- /dev/null
+++ b/Source/WebCore/html/ImageInputType.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "ImageInputType.h"
+
+#include "FormDataList.h"
+#include "HTMLFormElement.h"
+#include "HTMLImageLoader.h"
+#include "HTMLInputElement.h"
+#include "MouseEvent.h"
+#include "RenderImage.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+inline ImageInputType::ImageInputType(HTMLInputElement* element)
+ : BaseButtonInputType(element)
+{
+}
+
+PassOwnPtr<InputType> ImageInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new ImageInputType(element));
+}
+
+const AtomicString& ImageInputType::formControlType() const
+{
+ return InputTypeNames::image();
+}
+
+bool ImageInputType::isFormDataAppendable() const
+{
+ return true;
+}
+
+bool ImageInputType::appendFormData(FormDataList& encoding, bool) const
+{
+ if (!element()->isActivatedSubmit())
+ return false;
+ const AtomicString& name = element()->name();
+ encoding.appendData(name.isEmpty() ? "x" : (name + ".x"), m_clickLocation.x());
+ encoding.appendData(name.isEmpty() ? "y" : (name + ".y"), m_clickLocation.y());
+ if (!name.isEmpty() && !element()->value().isEmpty())
+ encoding.appendData(name, element()->value());
+ return true;
+}
+
+bool ImageInputType::supportsValidation() const
+{
+ return false;
+}
+
+void ImageInputType::handleDOMActivateEvent(Event* event)
+{
+ RefPtr<HTMLInputElement> element = this->element();
+ if (element->disabled() || !element->form())
+ return;
+ element->setActivatedSubmit(true);
+ if (event->underlyingEvent() && event->underlyingEvent()->isMouseEvent()) {
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event->underlyingEvent());
+ m_clickLocation = IntPoint(mouseEvent->offsetX(), mouseEvent->offsetY());
+ } else
+ m_clickLocation = IntPoint();
+ element->form()->prepareForSubmission(event); // Event handlers can run.
+ element->setActivatedSubmit(false);
+ event->setDefaultHandled();
+}
+
+RenderObject* ImageInputType::createRenderer(RenderArena* arena, RenderStyle*) const
+{
+ RenderImage* image = new (arena) RenderImage(element());
+ image->setImageResource(RenderImageResource::create());
+ return image;
+}
+
+void ImageInputType::altAttributeChanged()
+{
+ RenderImage* image = toRenderImage(element()->renderer());
+ if (!image)
+ return;
+ image->updateAltText();
+}
+
+void ImageInputType::srcAttributeChanged()
+{
+ if (!element()->renderer())
+ return;
+ if (!m_imageLoader)
+ m_imageLoader = adoptPtr(new HTMLImageLoader(element()));
+ m_imageLoader->updateFromElementIgnoringPreviousError();
+}
+
+void ImageInputType::attach()
+{
+ BaseButtonInputType::attach();
+
+ if (!m_imageLoader)
+ m_imageLoader = adoptPtr(new HTMLImageLoader(element()));
+ m_imageLoader->updateFromElement();
+
+ RenderImage* renderer = toRenderImage(element()->renderer());
+ if (!renderer)
+ return;
+
+ if (!m_imageLoader->haveFiredBeforeLoadEvent())
+ return;
+
+ RenderImageResource* imageResource = renderer->imageResource();
+ imageResource->setCachedImage(m_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 (!m_imageLoader->image() && !imageResource->cachedImage())
+ renderer->setImageSizeForAltText();
+}
+
+void ImageInputType::willMoveToNewOwnerDocument()
+{
+ BaseButtonInputType::willMoveToNewOwnerDocument();
+ if (m_imageLoader)
+ m_imageLoader->elementWillMoveToNewOwnerDocument();
+}
+
+bool ImageInputType::shouldRespectAlignAttribute()
+{
+ return true;
+}
+
+bool ImageInputType::canBeSuccessfulSubmitButton()
+{
+ return true;
+}
+
+bool ImageInputType::isImageButton() const
+{
+ return true;
+}
+
+bool ImageInputType::isEnumeratable()
+{
+ return false;
+}
+
+bool ImageInputType::shouldRespectHeightAndWidthAttributes()
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/ImageInputType.h b/Source/WebCore/html/ImageInputType.h
new file mode 100644
index 0000000..9cb6021
--- /dev/null
+++ b/Source/WebCore/html/ImageInputType.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 ImageInputType_h
+#define ImageInputType_h
+
+#include "BaseButtonInputType.h"
+#include "IntPoint.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class HTMLImageLoader;
+
+class ImageInputType : public BaseButtonInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ ImageInputType(HTMLInputElement*);
+ virtual const AtomicString& formControlType() const;
+ virtual bool isFormDataAppendable() const;
+ virtual bool appendFormData(FormDataList&, bool) const;
+ virtual bool supportsValidation() const;
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
+ virtual void handleDOMActivateEvent(Event*);
+ virtual void altAttributeChanged();
+ virtual void srcAttributeChanged();
+ virtual void attach();
+ virtual void willMoveToNewOwnerDocument();
+ virtual bool shouldRespectAlignAttribute();
+ virtual bool canBeSuccessfulSubmitButton();
+ virtual bool isImageButton() const;
+ virtual bool isEnumeratable();
+ virtual bool shouldRespectHeightAndWidthAttributes();
+
+ OwnPtr<HTMLImageLoader> m_imageLoader;
+ IntPoint m_clickLocation; // Valid only during HTMLFormElement::prepareForSubmission().
+};
+
+} // namespace WebCore
+
+#endif // ImageInputType_h
diff --git a/Source/WebCore/html/ImageResizerThread.cpp b/Source/WebCore/html/ImageResizerThread.cpp
new file mode 100644
index 0000000..1bae6a0
--- /dev/null
+++ b/Source/WebCore/html/ImageResizerThread.cpp
@@ -0,0 +1,97 @@
+/*
+ * 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:
+ *
+ * * 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(IMAGE_RESIZER)
+
+#include "ImageResizerThread.h"
+
+#include "BitmapImage.h"
+#include "Image.h"
+#include "SharedBuffer.h"
+#include <utility>
+
+namespace WebCore {
+
+static void returnBlobOrError(void* callbackInformation)
+{
+ AsyncImageResizer::CallbackInfo* callbackInfo = static_cast<AsyncImageResizer::CallbackInfo*>(callbackInformation);
+ if (!callbackInfo->blob)
+ callbackInfo->asyncImageResizer->resizeError();
+ else
+ callbackInfo->asyncImageResizer->resizeComplete(callbackInfo->blob);
+ delete callbackInfo;
+}
+
+bool ImageResizerThread::start(PassRefPtr<SharedBuffer> imageData, AsyncImageResizer::CallbackInfo* callbackInfo, AsyncImageResizer::OutputType outputType, IntSize desiredBounds, float quality, AsyncImageResizer::AspectRatioOption aspectRatioOption, AsyncImageResizer::OrientationOption orientationOption)
+{
+ ImageResizerThread* imageResizerThread = new ImageResizerThread(callbackInfo, outputType, desiredBounds, quality, aspectRatioOption, orientationOption);
+
+ RefPtr<SharedBuffer> copiedImageData = imageData->copy();
+ imageResizerThread->m_image = BitmapImage::create();
+ imageResizerThread->m_image->setData(copiedImageData, true);
+
+ imageResizerThread->m_threadID = createThread(ImageResizerThread::imageResizerThreadStart, imageResizerThread, "ImageResizerThread");
+ return imageResizerThread->m_threadID;
+}
+
+ImageResizerThread::ImageResizerThread(AsyncImageResizer::CallbackInfo* callbackInfo, AsyncImageResizer::OutputType outputType, IntSize desiredBounds, float quality, AsyncImageResizer::AspectRatioOption aspectRatioOption, AsyncImageResizer::OrientationOption orientationOption)
+ : m_threadID(0)
+ , m_callbackInfo(callbackInfo)
+ , m_outputType(outputType)
+ , m_desiredBounds(desiredBounds)
+ , m_quality(quality)
+ , m_aspectRatioOption(aspectRatioOption)
+ , m_orientationOption(orientationOption)
+{
+}
+
+ImageResizerThread::~ImageResizerThread()
+{
+}
+
+void* ImageResizerThread::imageResizerThreadStart(void* thread)
+{
+ return static_cast<ImageResizerThread*>(thread)->imageResizerThread();
+}
+
+void* ImageResizerThread::imageResizerThread()
+{
+ // FIXME: Do resizing, create blob, and catch any errors.
+
+ callOnMainThread(returnBlobOrError, static_cast<void*>(m_callbackInfo));
+ detachThread(m_threadID);
+ delete this;
+ return 0;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(IMAGE_RESIZER)
diff --git a/Source/WebCore/html/ImageResizerThread.h b/Source/WebCore/html/ImageResizerThread.h
new file mode 100644
index 0000000..ae5ade5
--- /dev/null
+++ b/Source/WebCore/html/ImageResizerThread.h
@@ -0,0 +1,70 @@
+/*
+ * 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:
+ *
+ * * 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 ImageResizerThread_h
+#define ImageResizerThread_h
+
+#if ENABLE(IMAGE_RESIZER)
+
+#include "AsyncImageResizer.h"
+
+namespace WebCore {
+
+class BitmapImage;
+class SharedBuffer;
+
+class ImageResizerThread {
+public:
+ static bool start(PassRefPtr<SharedBuffer> imageData, AsyncImageResizer::CallbackInfo*, AsyncImageResizer::OutputType, IntSize desiredBounds, float quality, AsyncImageResizer::AspectRatioOption, AsyncImageResizer::OrientationOption);
+ ~ImageResizerThread();
+
+private:
+ ImageResizerThread(AsyncImageResizer::CallbackInfo*, AsyncImageResizer::OutputType, IntSize desiredBounds, float quality, AsyncImageResizer::AspectRatioOption, AsyncImageResizer::OrientationOption);
+ static void* imageResizerThreadStart(void*);
+ void* imageResizerThread();
+
+ // Threading attributes.
+ ThreadIdentifier m_threadID;
+
+ // Image attributes.
+ AsyncImageResizer::CallbackInfo* m_callbackInfo;
+ RefPtr<BitmapImage> m_image;
+ AsyncImageResizer::OutputType m_outputType;
+ IntSize m_desiredBounds;
+ float m_quality;
+ AsyncImageResizer::AspectRatioOption m_aspectRatioOption;
+ AsyncImageResizer::OrientationOption m_orientationOption;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(IMAGE_RESIZER)
+
+#endif // ImageResizerThread_h
diff --git a/Source/WebCore/html/InputType.cpp b/Source/WebCore/html/InputType.cpp
new file mode 100644
index 0000000..be86399
--- /dev/null
+++ b/Source/WebCore/html/InputType.cpp
@@ -0,0 +1,767 @@
+/*
+ * 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 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "InputType.h"
+
+#include "BeforeTextInsertedEvent.h"
+#include "ButtonInputType.h"
+#include "CheckboxInputType.h"
+#include "ColorInputType.h"
+#include "DateComponents.h"
+#include "DateInputType.h"
+#include "DateTimeInputType.h"
+#include "DateTimeLocalInputType.h"
+#include "EmailInputType.h"
+#include "ExceptionCode.h"
+#include "FileInputType.h"
+#include "FormDataList.h"
+#include "HTMLFormElement.h"
+#include "HTMLInputElement.h"
+#include "HiddenInputType.h"
+#include "ImageInputType.h"
+#include "IsIndexInputType.h"
+#include "KeyboardEvent.h"
+#include "LocalizedStrings.h"
+#include "MonthInputType.h"
+#include "NumberInputType.h"
+#include "PasswordInputType.h"
+#include "RadioInputType.h"
+#include "RangeInputType.h"
+#include "RegularExpression.h"
+#include "RenderObject.h"
+#include "ResetInputType.h"
+#include "SearchInputType.h"
+#include "SubmitInputType.h"
+#include "TelephoneInputType.h"
+#include "TextInputType.h"
+#include "TimeInputType.h"
+#include "URLInputType.h"
+#include "WeekInputType.h"
+#include <limits>
+#include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+using namespace std;
+
+typedef PassOwnPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement*);
+typedef HashMap<String, InputTypeFactoryFunction, CaseFoldingHash> InputTypeFactoryMap;
+
+static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap()
+{
+ OwnPtr<InputTypeFactoryMap> map = adoptPtr(new InputTypeFactoryMap);
+ map->add(InputTypeNames::button(), ButtonInputType::create);
+ map->add(InputTypeNames::checkbox(), CheckboxInputType::create);
+ map->add(InputTypeNames::color(), ColorInputType::create);
+ map->add(InputTypeNames::date(), DateInputType::create);
+ map->add(InputTypeNames::datetime(), DateTimeInputType::create);
+ map->add(InputTypeNames::datetimelocal(), DateTimeLocalInputType::create);
+ map->add(InputTypeNames::email(), EmailInputType::create);
+ map->add(InputTypeNames::file(), FileInputType::create);
+ map->add(InputTypeNames::hidden(), HiddenInputType::create);
+ map->add(InputTypeNames::image(), ImageInputType::create);
+ map->add(InputTypeNames::isindex(), IsIndexInputType::create);
+ map->add(InputTypeNames::month(), MonthInputType::create);
+ map->add(InputTypeNames::number(), NumberInputType::create);
+ map->add(InputTypeNames::password(), PasswordInputType::create);
+ map->add(InputTypeNames::radio(), RadioInputType::create);
+ map->add(InputTypeNames::range(), RangeInputType::create);
+ map->add(InputTypeNames::reset(), ResetInputType::create);
+ map->add(InputTypeNames::search(), SearchInputType::create);
+ map->add(InputTypeNames::submit(), SubmitInputType::create);
+ map->add(InputTypeNames::telephone(), TelephoneInputType::create);
+ map->add(InputTypeNames::time(), TimeInputType::create);
+ map->add(InputTypeNames::url(), URLInputType::create);
+ map->add(InputTypeNames::week(), WeekInputType::create);
+ // No need to register "text" because it is the default type.
+ return map.release();
+}
+
+PassOwnPtr<InputType> InputType::create(HTMLInputElement* element, const String& typeName)
+{
+ static const InputTypeFactoryMap* factoryMap = createInputTypeFactoryMap().leakPtr();
+ PassOwnPtr<InputType> (*factory)(HTMLInputElement*) = typeName.isEmpty() ? 0 : factoryMap->get(typeName);
+ if (!factory)
+ factory = TextInputType::create;
+ return factory(element);
+}
+
+PassOwnPtr<InputType> InputType::createText(HTMLInputElement* element)
+{
+ return TextInputType::create(element);
+}
+
+InputType::~InputType()
+{
+}
+
+bool InputType::isTextField() const
+{
+ return false;
+}
+
+bool InputType::isTextType() const
+{
+ return false;
+}
+
+bool InputType::isRangeControl() const
+{
+ return false;
+}
+
+bool InputType::saveFormControlState(String& result) const
+{
+ String currentValue = element()->value();
+ if (currentValue == element()->defaultValue())
+ return false;
+ result = currentValue;
+ return true;
+}
+
+void InputType::restoreFormControlState(const String& state) const
+{
+ element()->setValue(state);
+}
+
+bool InputType::isFormDataAppendable() const
+{
+ // There is no form data unless there's a name for non-image types.
+ return !element()->name().isEmpty();
+}
+
+bool InputType::appendFormData(FormDataList& encoding, bool) const
+{
+ // Always successful.
+ encoding.appendData(element()->name(), element()->value());
+ return true;
+}
+
+double InputType::valueAsDate() const
+{
+ return DateComponents::invalidMilliseconds();
+}
+
+void InputType::setValueAsDate(double, ExceptionCode& ec) const
+{
+ ec = INVALID_STATE_ERR;
+}
+
+double InputType::valueAsNumber() const
+{
+ return numeric_limits<double>::quiet_NaN();
+}
+
+void InputType::setValueAsNumber(double, ExceptionCode& ec) const
+{
+ ec = INVALID_STATE_ERR;
+}
+
+bool InputType::supportsValidation() const
+{
+ return true;
+}
+
+bool InputType::typeMismatchFor(const String&) const
+{
+ return false;
+}
+
+bool InputType::typeMismatch() const
+{
+ return false;
+}
+
+bool InputType::supportsRequired() const
+{
+ // Almost all validatable types support @required.
+ return supportsValidation();
+}
+
+bool InputType::valueMissing(const String&) const
+{
+ return false;
+}
+
+bool InputType::patternMismatch(const String&) const
+{
+ return false;
+}
+
+bool InputType::rangeUnderflow(const String&) const
+{
+ return false;
+}
+
+bool InputType::rangeOverflow(const String&) const
+{
+ return false;
+}
+
+bool InputType::supportsRangeLimitation() const
+{
+ return false;
+}
+
+double InputType::defaultValueForStepUp() const
+{
+ return 0;
+}
+
+double InputType::minimum() const
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+double InputType::maximum() const
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+bool InputType::stepMismatch(const String&, double) const
+{
+ // Non-supported types should be rejected by HTMLInputElement::getAllowedValueStep().
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+double InputType::stepBase() const
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+double InputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const
+{
+ if (decimalPlaces)
+ *decimalPlaces = 0;
+ return stepBase();
+}
+
+double InputType::defaultStep() const
+{
+ return numeric_limits<double>::quiet_NaN();
+}
+
+double InputType::stepScaleFactor() const
+{
+ return numeric_limits<double>::quiet_NaN();
+}
+
+bool InputType::parsedStepValueShouldBeInteger() const
+{
+ return false;
+}
+
+bool InputType::scaledStepValueShouldBeInteger() const
+{
+ return false;
+}
+
+double InputType::acceptableError(double) const
+{
+ return 0;
+}
+
+String InputType::typeMismatchText() const
+{
+ return validationMessageTypeMismatchText();
+}
+
+String InputType::valueMissingText() const
+{
+ return validationMessageValueMissingText();
+}
+
+void InputType::handleClickEvent(MouseEvent*)
+{
+}
+
+void InputType::handleDOMActivateEvent(Event*)
+{
+}
+
+void InputType::handleKeydownEvent(KeyboardEvent*)
+{
+}
+
+void InputType::handleKeypressEvent(KeyboardEvent*)
+{
+}
+
+void InputType::handleKeyupEvent(KeyboardEvent*)
+{
+}
+
+void InputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event)
+{
+ element()->handleBeforeTextInsertedEvent(event);
+}
+
+void InputType::handleWheelEvent(WheelEvent*)
+{
+}
+
+void InputType::forwardEvent(Event*)
+{
+}
+
+bool InputType::shouldSubmitImplicitly(Event* event)
+{
+ return event->isKeyboardEvent() && event->type() == eventNames().keypressEvent && static_cast<KeyboardEvent*>(event)->charCode() == '\r';
+}
+
+PassRefPtr<HTMLFormElement> InputType::formForSubmission() const
+{
+ return element()->form();
+}
+
+RenderObject* InputType::createRenderer(RenderArena*, RenderStyle* style) const
+{
+ return RenderObject::createObject(element(), style);
+}
+
+double InputType::parseToDouble(const String&, double defaultValue) const
+{
+ return defaultValue;
+}
+
+double InputType::parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const
+{
+ if (decimalPlaces)
+ *decimalPlaces = 0;
+ return parseToDouble(src, defaultValue);
+}
+
+bool InputType::parseToDateComponents(const String&, DateComponents*) const
+{
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+String InputType::serialize(double) const
+{
+ ASSERT_NOT_REACHED();
+ return String();
+}
+
+void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const
+{
+ if (element()->active())
+ element()->dispatchSimulatedClick(event);
+ event->setDefaultHandled();
+}
+
+bool InputType::canSetStringValue() const
+{
+ return true;
+}
+
+bool InputType::isKeyboardFocusable() const
+{
+ return true;
+}
+
+bool InputType::shouldUseInputMethod() const
+{
+ return false;
+}
+
+void InputType::handleBlurEvent()
+{
+}
+
+void InputType::accessKeyAction(bool)
+{
+ element()->focus(false);
+}
+
+void InputType::attach()
+{
+}
+
+void InputType::altAttributeChanged()
+{
+}
+
+void InputType::srcAttributeChanged()
+{
+}
+
+void InputType::willMoveToNewOwnerDocument()
+{
+}
+
+bool InputType::shouldRespectAlignAttribute()
+{
+ return false;
+}
+
+bool InputType::canChangeFromAnotherType() const
+{
+ return true;
+}
+
+void InputType::minOrMaxAttributeChanged()
+{
+}
+
+bool InputType::canBeSuccessfulSubmitButton()
+{
+ return false;
+}
+
+bool InputType::rendererIsNeeded()
+{
+ return true;
+}
+
+FileList* InputType::files()
+{
+ return 0;
+}
+
+bool InputType::getTypeSpecificValue(String&)
+{
+ return false;
+}
+
+String InputType::fallbackValue()
+{
+ return String();
+}
+
+String InputType::defaultValue()
+{
+ return String();
+}
+
+bool InputType::canSetSuggestedValue()
+{
+ return false;
+}
+
+bool InputType::shouldSendChangeEventAfterCheckedChanged()
+{
+ return true;
+}
+
+bool InputType::storesValueSeparateFromAttribute()
+{
+ return true;
+}
+
+bool InputType::canSetValue(const String&)
+{
+ return true;
+}
+
+PassOwnPtr<ClickHandlingState> InputType::willDispatchClick()
+{
+ return PassOwnPtr<ClickHandlingState>();
+}
+
+void InputType::didDispatchClick(Event*, const ClickHandlingState&)
+{
+}
+
+bool InputType::isAcceptableValue(const String&)
+{
+ return true;
+}
+
+String InputType::sanitizeValue(const String& proposedValue)
+{
+ return proposedValue;
+}
+
+bool InputType::hasUnacceptableValue()
+{
+ return false;
+}
+
+void InputType::setFileList(const Vector<String>&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+bool InputType::shouldResetOnDocumentActivation()
+{
+ return false;
+}
+
+bool InputType::shouldRespectListAttribute()
+{
+ return false;
+}
+
+bool InputType::shouldRespectSpeechAttribute()
+{
+ return false;
+}
+
+bool InputType::isTextButton() const
+{
+ return false;
+}
+
+bool InputType::isRadioButton() const
+{
+ return false;
+}
+
+bool InputType::isSearchField() const
+{
+ return false;
+}
+
+bool InputType::isHiddenType() const
+{
+ return false;
+}
+
+bool InputType::isPasswordField() const
+{
+ return false;
+}
+
+bool InputType::isCheckbox() const
+{
+ return false;
+}
+
+bool InputType::isEmailField() const
+{
+ return false;
+}
+
+bool InputType::isFileUpload() const
+{
+ return false;
+}
+
+bool InputType::isImageButton() const
+{
+ return false;
+}
+
+bool InputType::isNumberField() const
+{
+ return false;
+}
+
+bool InputType::isSubmitButton() const
+{
+ return false;
+}
+
+bool InputType::isTelephoneField() const
+{
+ return false;
+}
+
+bool InputType::isURLField() const
+{
+ return false;
+}
+
+bool InputType::isEnumeratable()
+{
+ return true;
+}
+
+bool InputType::isCheckable()
+{
+ return false;
+}
+
+bool InputType::hasSpinButton()
+{
+ return false;
+}
+
+bool InputType::shouldRespectHeightAndWidthAttributes()
+{
+ return false;
+}
+
+namespace InputTypeNames {
+
+// The type names must be lowercased because they will be the return values of
+// input.type and input.type must be lowercase according to DOM Level 2.
+
+const AtomicString& button()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("button"));
+ return name;
+}
+
+const AtomicString& checkbox()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("checkbox"));
+ return name;
+}
+
+const AtomicString& color()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("color"));
+ return name;
+}
+
+const AtomicString& date()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("date"));
+ return name;
+}
+
+const AtomicString& datetime()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime"));
+ return name;
+}
+
+const AtomicString& datetimelocal()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("datetime-local"));
+ return name;
+}
+
+const AtomicString& email()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("email"));
+ return name;
+}
+
+const AtomicString& file()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("file"));
+ return name;
+}
+
+const AtomicString& hidden()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("hidden"));
+ return name;
+}
+
+const AtomicString& image()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("image"));
+ return name;
+}
+
+const AtomicString& isindex()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("khtml_isindex"));
+ return name;
+}
+
+const AtomicString& month()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("month"));
+ return name;
+}
+
+const AtomicString& number()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("number"));
+ return name;
+}
+
+const AtomicString& password()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("password"));
+ return name;
+}
+
+const AtomicString& radio()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("radio"));
+ return name;
+}
+
+const AtomicString& range()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("range"));
+ return name;
+}
+
+const AtomicString& reset()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("reset"));
+ return name;
+}
+
+const AtomicString& search()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("search"));
+ return name;
+}
+
+const AtomicString& submit()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("submit"));
+ return name;
+}
+
+const AtomicString& telephone()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("tel"));
+ return name;
+}
+
+const AtomicString& text()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("text"));
+ return name;
+}
+
+const AtomicString& time()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("time"));
+ return name;
+}
+
+const AtomicString& url()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("url"));
+ return name;
+}
+
+const AtomicString& week()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("week"));
+ return name;
+}
+
+} // namespace WebCore::InputTypeNames
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/InputType.h b/Source/WebCore/html/InputType.h
new file mode 100644
index 0000000..4d25a97
--- /dev/null
+++ b/Source/WebCore/html/InputType.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 InputType_h
+#define InputType_h
+
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class BeforeTextInsertedEvent;
+class DateComponents;
+class Event;
+class FileList;
+class FormDataList;
+class HTMLFormElement;
+class HTMLInputElement;
+class KeyboardEvent;
+class MouseEvent;
+class RenderArena;
+class RenderObject;
+class RenderStyle;
+class WheelEvent;
+
+typedef int ExceptionCode;
+
+struct ClickHandlingState {
+ bool checked;
+ bool indeterminate;
+ RefPtr<HTMLInputElement> checkedRadioButton;
+
+ WTF_MAKE_FAST_ALLOCATED
+};
+
+// An InputType object represents the type-specific part of an HTMLInputElement.
+// Do not expose instances of InputType and classes derived from it to classes
+// other than HTMLInputElement.
+class InputType : public Noncopyable {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*, const String&);
+ static PassOwnPtr<InputType> createText(HTMLInputElement*);
+ virtual ~InputType();
+
+ virtual const AtomicString& formControlType() const = 0;
+ virtual bool canChangeFromAnotherType() const;
+
+ // Type query functions
+
+ // Any time we are using one of these functions it's best to refactor
+ // to add a virtual function to allow the input type object to do the
+ // work instead, or at least make a query function that asks a higher
+ // level question. These functions make the HTMLInputElement class
+ // inflexible because it's harder to add new input types if there is
+ // scattered code with special cases for various types.
+
+ virtual bool isCheckbox() const;
+ virtual bool isEmailField() const;
+ virtual bool isFileUpload() const;
+ virtual bool isHiddenType() const;
+ virtual bool isImageButton() const;
+ virtual bool isNumberField() const;
+ virtual bool isPasswordField() const;
+ virtual bool isRadioButton() const;
+ virtual bool isRangeControl() const;
+ virtual bool isSearchField() const;
+ virtual bool isSubmitButton() const;
+ virtual bool isTelephoneField() const;
+ virtual bool isTextButton() const;
+ virtual bool isTextField() const;
+ virtual bool isTextType() const;
+ virtual bool isURLField() const;
+
+ // Form value functions
+
+ virtual bool saveFormControlState(String&) const;
+ virtual void restoreFormControlState(const String&) const;
+ virtual bool isFormDataAppendable() const;
+ virtual bool appendFormData(FormDataList&, bool multipart) const;
+
+ // DOM property functions
+
+ virtual bool getTypeSpecificValue(String&); // Checked first, before internal storage or the value attribute.
+ virtual String fallbackValue(); // Checked last, if both internal storage and value attribute are missing.
+ virtual String defaultValue(); // Checked after even fallbackValue, only when the valueWithDefault function is called.
+ virtual double valueAsDate() const;
+ virtual void setValueAsDate(double, ExceptionCode&) const;
+ virtual double valueAsNumber() const;
+ virtual void setValueAsNumber(double, ExceptionCode&) const;
+
+ // Validation functions
+
+ virtual bool supportsValidation() const;
+ virtual bool typeMismatchFor(const String&) const;
+ // Type check for the current input value. We do nothing for some types
+ // though typeMismatchFor() does something for them because of value
+ // sanitization.
+ virtual bool typeMismatch() const;
+ virtual bool supportsRequired() const;
+ virtual bool valueMissing(const String&) const;
+ virtual bool patternMismatch(const String&) const;
+ virtual bool rangeUnderflow(const String&) const;
+ virtual bool rangeOverflow(const String&) const;
+ virtual bool supportsRangeLimitation() const;
+ virtual double defaultValueForStepUp() const;
+ virtual double minimum() const;
+ virtual double maximum() const;
+ virtual bool stepMismatch(const String&, double step) const;
+ virtual double stepBase() const;
+ virtual double stepBaseWithDecimalPlaces(unsigned*) const;
+ virtual double defaultStep() const;
+ virtual double stepScaleFactor() const;
+ virtual bool parsedStepValueShouldBeInteger() const;
+ virtual bool scaledStepValueShouldBeInteger() const;
+ virtual double acceptableError(double) const;
+ virtual String typeMismatchText() const;
+ virtual String valueMissingText() const;
+ virtual bool canSetStringValue() const;
+ virtual bool isAcceptableValue(const String&);
+ virtual String sanitizeValue(const String&);
+ virtual bool hasUnacceptableValue();
+
+ // Event handlers
+
+ virtual void handleClickEvent(MouseEvent*);
+ virtual PassOwnPtr<ClickHandlingState> willDispatchClick();
+ virtual void didDispatchClick(Event*, const ClickHandlingState&);
+ virtual void handleDOMActivateEvent(Event*);
+ virtual void handleKeydownEvent(KeyboardEvent*);
+ virtual void handleKeypressEvent(KeyboardEvent*);
+ virtual void handleKeyupEvent(KeyboardEvent*);
+ virtual void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*);
+ virtual void handleWheelEvent(WheelEvent*);
+ virtual void forwardEvent(Event*);
+ // Helpers for event handlers.
+ virtual bool shouldSubmitImplicitly(Event*);
+ virtual PassRefPtr<HTMLFormElement> formForSubmission() const;
+ virtual bool isKeyboardFocusable() const;
+ virtual bool shouldUseInputMethod() const;
+ virtual void handleBlurEvent();
+ virtual void accessKeyAction(bool sendToAnyElement);
+ virtual bool canBeSuccessfulSubmitButton();
+
+ // Miscellaneous functions
+
+ virtual bool rendererIsNeeded();
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
+ virtual void attach();
+ virtual void minOrMaxAttributeChanged();
+ virtual void altAttributeChanged();
+ virtual void srcAttributeChanged();
+ virtual void willMoveToNewOwnerDocument();
+ virtual bool shouldRespectAlignAttribute();
+ virtual FileList* files();
+ virtual bool canSetSuggestedValue();
+ virtual bool shouldSendChangeEventAfterCheckedChanged();
+ virtual bool canSetValue(const String&);
+ virtual bool storesValueSeparateFromAttribute();
+ virtual void setFileList(const Vector<String>& paths);
+ virtual bool shouldResetOnDocumentActivation();
+ virtual bool shouldRespectListAttribute();
+ virtual bool shouldRespectSpeechAttribute();
+ virtual bool isEnumeratable();
+ virtual bool isCheckable();
+ virtual bool hasSpinButton();
+ virtual bool shouldRespectHeightAndWidthAttributes();
+
+ // Parses the specified string for the type, and return
+ // the double value for the parsing result if the parsing
+ // succeeds; Returns defaultValue otherwise. This function can
+ // return NaN or Infinity only if defaultValue is NaN or Infinity.
+ virtual double parseToDouble(const String&, double defaultValue) const;
+
+ // Parses the specified string for the type as parseToDouble() does.
+ // In addition, it stores the number of digits after the decimal point
+ // into *decimalPlaces.
+ virtual double parseToDoubleWithDecimalPlaces(const String&, double defaultValue, unsigned* decimalPlaces) const;
+
+ // Parses the specified string for this InputType, and returns true if it
+ // is successfully parsed. An instance pointed by the DateComponents*
+ // parameter will have parsed values and be modified even if the parsing
+ // fails. The DateComponents* parameter may be 0.
+ virtual bool parseToDateComponents(const String&, DateComponents*) const;
+
+ // Create a string representation of the specified double value for the
+ // input type. If NaN or Infinity is specified, this returns an empty
+ // string. This should not be called for types without valueAsNumber.
+ virtual String serialize(double) const;
+
+protected:
+ InputType(HTMLInputElement* element) : m_element(element) { }
+ HTMLInputElement* element() const { return m_element; }
+ void dispatchSimulatedClickIfActive(KeyboardEvent*) const;
+ // We can't make this a static const data member because VC++ doesn't like it.
+ static double defaultStepBase() { return 0.0; }
+
+private:
+ // Raw pointer because the HTMLInputElement object owns this InputType object.
+ HTMLInputElement* m_element;
+};
+
+namespace InputTypeNames {
+
+const AtomicString& button();
+const AtomicString& checkbox();
+const AtomicString& color();
+const AtomicString& date();
+const AtomicString& datetime();
+const AtomicString& datetimelocal();
+const AtomicString& email();
+const AtomicString& file();
+const AtomicString& hidden();
+const AtomicString& image();
+const AtomicString& isindex();
+const AtomicString& month();
+const AtomicString& number();
+const AtomicString& password();
+const AtomicString& radio();
+const AtomicString& range();
+const AtomicString& reset();
+const AtomicString& search();
+const AtomicString& submit();
+const AtomicString& telephone();
+const AtomicString& text();
+const AtomicString& time();
+const AtomicString& url();
+const AtomicString& week();
+
+} // namespace WebCore::InputTypeNames
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/IsIndexInputType.cpp b/Source/WebCore/html/IsIndexInputType.cpp
new file mode 100644
index 0000000..a275f28
--- /dev/null
+++ b/Source/WebCore/html/IsIndexInputType.cpp
@@ -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:
+ *
+ * * 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 "IsIndexInputType.h"
+
+#include "Document.h"
+#include "HTMLFormElement.h"
+#include "HTMLInputElement.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<InputType> IsIndexInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new IsIndexInputType(element));
+}
+
+const AtomicString& IsIndexInputType::formControlType() const
+{
+ return emptyAtom;
+}
+
+bool IsIndexInputType::supportsRequired() const
+{
+ return false;
+}
+
+PassRefPtr<HTMLFormElement> IsIndexInputType::formForSubmission() const
+{
+ RefPtr<HTMLFormElement> form = InputType::formForSubmission();
+ if (form)
+ return form.release();
+ // If there is no form, then create a temporary form just to be used for submission.
+ Document* document = element()->document();
+ form = HTMLFormElement::create(document);
+ form->registerFormElement(element());
+ form->setMethod("GET");
+ if (!document->baseURL().isEmpty()) {
+ // We treat the href property of the <base> element as the form action, as per section 7.5
+ // "Queries and Indexes" of the HTML 2.0 spec. <http://www.w3.org/MarkUp/html-spec/html-spec_7.html#SEC7.5>.
+ form->setAction(document->baseURL().string());
+ }
+ return form.release();
+}
+
+bool IsIndexInputType::shouldRespectListAttribute()
+{
+ return false;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/IsIndexInputType.h b/Source/WebCore/html/IsIndexInputType.h
new file mode 100644
index 0000000..64b06e7
--- /dev/null
+++ b/Source/WebCore/html/IsIndexInputType.h
@@ -0,0 +1,53 @@
+/*
+ * 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:
+ *
+ * * 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 IsIndexInputType_h
+#define IsIndexInputType_h
+
+#include "TextFieldInputType.h"
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+class IsIndexInputType : public TextFieldInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ IsIndexInputType(HTMLInputElement* element) : TextFieldInputType(element) { };
+ virtual const AtomicString& formControlType() const;
+ virtual bool supportsRequired() const;
+ virtual PassRefPtr<HTMLFormElement> formForSubmission() const;
+ virtual bool shouldRespectListAttribute();
+};
+
+} // namespace WebCore
+
+#endif // IsIndexInputType_h
diff --git a/Source/WebCore/html/LabelsNodeList.cpp b/Source/WebCore/html/LabelsNodeList.cpp
new file mode 100644
index 0000000..f2bda17
--- /dev/null
+++ b/Source/WebCore/html/LabelsNodeList.cpp
@@ -0,0 +1,50 @@
+/**
+ * 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 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "LabelsNodeList.h"
+
+#include "Element.h"
+#include "HTMLLabelElement.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+LabelsNodeList::LabelsNodeList(PassRefPtr<Node> forNode )
+ : DynamicNodeList(forNode->document()) , m_forNode(forNode)
+{
+}
+
+LabelsNodeList::~LabelsNodeList()
+{
+ m_forNode->removeCachedLabelsNodeList(this);
+}
+
+bool LabelsNodeList::nodeMatches(Element* testNode) const
+{
+ return testNode->hasTagName(labelTag) && static_cast<HTMLLabelElement*>(testNode)->control() == m_forNode;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/LabelsNodeList.h b/Source/WebCore/html/LabelsNodeList.h
new file mode 100644
index 0000000..c22a532
--- /dev/null
+++ b/Source/WebCore/html/LabelsNodeList.h
@@ -0,0 +1,52 @@
+/*
+ * 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 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef LabelsNodeList_h
+#define LabelsNodeList_h
+
+#include "DynamicNodeList.h"
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class LabelsNodeList : public DynamicNodeList {
+public:
+ static PassRefPtr<LabelsNodeList> create(PassRefPtr<Node> forNode)
+ {
+ return adoptRef(new LabelsNodeList(forNode));
+ }
+ ~LabelsNodeList();
+
+protected:
+ LabelsNodeList(PassRefPtr<Node> forNode);
+
+ virtual bool nodeMatches(Element*) const;
+
+private:
+ RefPtr<Node> m_forNode;
+};
+
+} // namespace WebCore
+
+#endif // LabelsNodeList_h
diff --git a/Source/WebCore/html/MediaDocument.cpp b/Source/WebCore/html/MediaDocument.cpp
new file mode 100644
index 0000000..d6fe6dd
--- /dev/null
+++ b/Source/WebCore/html/MediaDocument.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 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
+ * 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 "MediaDocument.h"
+
+#include "DocumentLoader.h"
+#include "EventNames.h"
+#include "Frame.h"
+#include "FrameLoaderClient.h"
+#include "HTMLEmbedElement.h"
+#include "HTMLHtmlElement.h"
+#include "HTMLNames.h"
+#include "HTMLVideoElement.h"
+#include "KeyboardEvent.h"
+#include "MainResourceLoader.h"
+#include "NodeList.h"
+#include "RawDataDocumentParser.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+// FIXME: Share more code with PluginDocumentParser.
+class MediaDocumentParser : public RawDataDocumentParser {
+public:
+ static PassRefPtr<MediaDocumentParser> create(MediaDocument* document)
+ {
+ return adoptRef(new MediaDocumentParser(document));
+ }
+
+private:
+ MediaDocumentParser(Document* document)
+ : RawDataDocumentParser(document)
+ , m_mediaElement(0)
+ {
+ }
+
+ virtual void appendBytes(DocumentWriter*, const char*, int, bool);
+
+ void createDocumentStructure();
+
+ HTMLMediaElement* m_mediaElement;
+};
+
+void MediaDocumentParser::createDocumentStructure()
+{
+ ExceptionCode ec;
+ RefPtr<Element> rootElement = document()->createElement(htmlTag, false);
+ document()->appendChild(rootElement, ec);
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ static_cast<HTMLHtmlElement*>(rootElement.get())->insertedByParser();
+#endif
+
+ if (document()->frame())
+ document()->frame()->loader()->dispatchDocumentElementAvailable();
+
+ RefPtr<Element> body = document()->createElement(bodyTag, false);
+ body->setAttribute(styleAttr, "background-color: rgb(38,38,38);");
+
+ rootElement->appendChild(body, ec);
+
+ RefPtr<Element> mediaElement = document()->createElement(videoTag, false);
+
+ m_mediaElement = static_cast<HTMLVideoElement*>(mediaElement.get());
+ m_mediaElement->setAttribute(controlsAttr, "");
+ m_mediaElement->setAttribute(autoplayAttr, "");
+ m_mediaElement->setAttribute(styleAttr, "margin: auto; position: absolute; top: 0; right: 0; bottom: 0; left: 0;");
+
+ m_mediaElement->setAttribute(nameAttr, "media");
+ m_mediaElement->setSrc(document()->url());
+
+ body->appendChild(mediaElement, ec);
+
+ Frame* frame = document()->frame();
+ if (!frame)
+ return;
+
+ frame->loader()->activeDocumentLoader()->mainResourceLoader()->setShouldBufferData(false);
+}
+
+void MediaDocumentParser::appendBytes(DocumentWriter*, const char*, int, bool)
+{
+ ASSERT(!m_mediaElement);
+ if (m_mediaElement)
+ return;
+
+ createDocumentStructure();
+ finish();
+}
+
+MediaDocument::MediaDocument(Frame* frame, const KURL& url)
+ : HTMLDocument(frame, url)
+ , m_replaceMediaElementTimer(this, &MediaDocument::replaceMediaElementTimerFired)
+{
+ setCompatibilityMode(QuirksMode);
+ lockCompatibilityMode();
+}
+
+MediaDocument::~MediaDocument()
+{
+ ASSERT(!m_replaceMediaElementTimer.isActive());
+}
+
+PassRefPtr<DocumentParser> MediaDocument::createParser()
+{
+ return MediaDocumentParser::create(this);
+}
+
+static inline HTMLVideoElement* descendentVideoElement(Node* node)
+{
+ ASSERT(node);
+
+ if (node->hasTagName(videoTag))
+ return static_cast<HTMLVideoElement*>(node);
+
+ RefPtr<NodeList> nodeList = node->getElementsByTagNameNS(videoTag.namespaceURI(), videoTag.localName());
+
+ if (nodeList.get()->length() > 0)
+ return static_cast<HTMLVideoElement*>(nodeList.get()->item(0));
+
+ return 0;
+}
+
+void MediaDocument::defaultEventHandler(Event* event)
+{
+ // Match the default Quicktime plugin behavior to allow
+ // clicking and double-clicking to pause and play the media.
+ Node* targetNode = event->target()->toNode();
+ if (!targetNode)
+ return;
+
+ HTMLVideoElement* video = descendentVideoElement(targetNode);
+ if (!video)
+ return;
+
+ if (event->type() == eventNames().clickEvent) {
+ if (!video->canPlay()) {
+ video->pause(event->fromUserGesture());
+ event->setDefaultHandled();
+ }
+ } else if (event->type() == eventNames().dblclickEvent) {
+ if (video->canPlay()) {
+ video->play(event->fromUserGesture());
+ event->setDefaultHandled();
+ }
+ } else if (event->type() == eventNames().keydownEvent && event->isKeyboardEvent()) {
+ KeyboardEvent* keyboardEvent = static_cast<KeyboardEvent*>(event);
+ if (keyboardEvent->keyIdentifier() == "U+0020") { // space
+ if (video->paused()) {
+ if (video->canPlay())
+ video->play(event->fromUserGesture());
+ } else
+ video->pause(event->fromUserGesture());
+ event->setDefaultHandled();
+ }
+ }
+}
+
+void MediaDocument::mediaElementSawUnsupportedTracks()
+{
+ // The HTMLMediaElement was told it has something that the underlying
+ // MediaPlayer cannot handle so we should switch from <video> to <embed>
+ // and let the plugin handle this. Don't do it immediately as this
+ // function may be called directly from a media engine callback, and
+ // replaceChild will destroy the element, media player, and media engine.
+ m_replaceMediaElementTimer.startOneShot(0);
+}
+
+void MediaDocument::replaceMediaElementTimerFired(Timer<MediaDocument>*)
+{
+ HTMLElement* htmlBody = body();
+ if (!htmlBody)
+ return;
+
+ // Set body margin width and height to 0 as that is what a PluginDocument uses.
+ htmlBody->setAttribute(marginwidthAttr, "0");
+ htmlBody->setAttribute(marginheightAttr, "0");
+
+ if (HTMLVideoElement* videoElement = descendentVideoElement(htmlBody)) {
+ RefPtr<Element> element = Document::createElement(embedTag, false);
+ HTMLEmbedElement* embedElement = static_cast<HTMLEmbedElement*>(element.get());
+
+ embedElement->setAttribute(widthAttr, "100%");
+ embedElement->setAttribute(heightAttr, "100%");
+ embedElement->setAttribute(nameAttr, "plugin");
+ embedElement->setAttribute(srcAttr, url().string());
+ embedElement->setAttribute(typeAttr, frame()->loader()->writer()->mimeType());
+
+ ExceptionCode ec;
+ videoElement->parentNode()->replaceChild(embedElement, videoElement, ec);
+ }
+}
+
+}
+#endif
diff --git a/Source/WebCore/html/MediaDocument.h b/Source/WebCore/html/MediaDocument.h
new file mode 100644
index 0000000..2d81296
--- /dev/null
+++ b/Source/WebCore/html/MediaDocument.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 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 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 MediaDocument_h
+#define MediaDocument_h
+
+#if ENABLE(VIDEO)
+
+#include "HTMLDocument.h"
+
+namespace WebCore {
+
+class MediaDocument : public HTMLDocument {
+public:
+ static PassRefPtr<MediaDocument> create(Frame* frame, const KURL& url)
+ {
+ return adoptRef(new MediaDocument(frame, url));
+ }
+ virtual ~MediaDocument();
+
+ void mediaElementSawUnsupportedTracks();
+
+private:
+ MediaDocument(Frame*, const KURL&);
+
+ virtual bool isMediaDocument() const { return true; }
+ virtual PassRefPtr<DocumentParser> createParser();
+
+ virtual void defaultEventHandler(Event*);
+
+ void replaceMediaElementTimerFired(Timer<MediaDocument>*);
+
+ Timer<MediaDocument> m_replaceMediaElementTimer;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/html/MediaError.h b/Source/WebCore/html/MediaError.h
new file mode 100644
index 0000000..b68c370
--- /dev/null
+++ b/Source/WebCore/html/MediaError.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007 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 MediaError_h
+#define MediaError_h
+
+#if ENABLE(VIDEO)
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class MediaError : public RefCounted<MediaError> {
+public:
+ enum Code { MEDIA_ERR_ABORTED = 1, MEDIA_ERR_NETWORK, MEDIA_ERR_DECODE, MEDIA_ERR_SRC_NOT_SUPPORTED };
+
+ static PassRefPtr<MediaError> create(Code code) { return adoptRef(new MediaError(code)); }
+
+ Code code() const { return m_code; }
+
+private:
+ MediaError(Code code) : m_code(code) { }
+
+ Code m_code;
+};
+
+} // namespace WebCore
+
+#endif
+#endif
diff --git a/Source/WebCore/html/MediaError.idl b/Source/WebCore/html/MediaError.idl
new file mode 100644
index 0000000..9d6f3bd
--- /dev/null
+++ b/Source/WebCore/html/MediaError.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+module html {
+ interface [Conditional=VIDEO] MediaError {
+ const unsigned short MEDIA_ERR_ABORTED = 1;
+ const unsigned short MEDIA_ERR_NETWORK = 2;
+ const unsigned short MEDIA_ERR_DECODE = 3;
+ const unsigned short MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
+ readonly attribute unsigned short code;
+ };
+}
diff --git a/Source/WebCore/html/MonthInputType.cpp b/Source/WebCore/html/MonthInputType.cpp
new file mode 100644
index 0000000..38f9d00
--- /dev/null
+++ b/Source/WebCore/html/MonthInputType.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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:
+ *
+ * * 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 "MonthInputType.h"
+
+#include "DateComponents.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/DateMath.h>
+#include <wtf/MathExtras.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static const double monthDefaultStep = 1.0;
+static const double monthStepScaleFactor = 1.0;
+
+PassOwnPtr<InputType> MonthInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new MonthInputType(element));
+}
+
+const AtomicString& MonthInputType::formControlType() const
+{
+ return InputTypeNames::month();
+}
+
+double MonthInputType::valueAsDate() const
+{
+ DateComponents date;
+ if (!parseToDateComponents(element()->value(), &date))
+ return DateComponents::invalidMilliseconds();
+ double msec = date.millisecondsSinceEpoch();
+ ASSERT(isfinite(msec));
+ return msec;
+}
+
+void MonthInputType::setValueAsDate(double value, ExceptionCode&) const
+{
+ DateComponents date;
+ if (!date.setMillisecondsSinceEpochForMonth(value)) {
+ element()->setValue(String());
+ return;
+ }
+ element()->setValue(date.toString());
+}
+
+double MonthInputType::defaultValueForStepUp() const
+{
+ double current = currentTimeMS();
+ double utcOffset = calculateUTCOffset();
+ double dstOffset = calculateDSTOffset(current, utcOffset);
+ int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
+ current += offset * msPerMinute;
+
+ DateComponents date;
+ date.setMillisecondsSinceEpochForMonth(current);
+ double months = date.monthsSinceEpoch();
+ ASSERT(isfinite(months));
+ return months;
+}
+
+double MonthInputType::minimum() const
+{
+ return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumMonth());
+}
+
+double MonthInputType::maximum() const
+{
+ return parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumMonth());
+}
+
+double MonthInputType::defaultStep() const
+{
+ return monthDefaultStep;
+}
+
+double MonthInputType::stepScaleFactor() const
+{
+ return monthStepScaleFactor;
+}
+
+bool MonthInputType::parsedStepValueShouldBeInteger() const
+{
+ return true;
+}
+
+double MonthInputType::parseToDouble(const String& src, double defaultValue) const
+{
+ DateComponents date;
+ if (!parseToDateComponents(src, &date))
+ return defaultValue;
+ double months = date.monthsSinceEpoch();
+ ASSERT(isfinite(months));
+ return months;
+}
+
+bool MonthInputType::parseToDateComponentsInternal(const UChar* characters, unsigned length, DateComponents* out) const
+{
+ ASSERT(out);
+ unsigned end;
+ return out->parseMonth(characters, length, 0, end) && end == length;
+}
+
+bool MonthInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+{
+ ASSERT(date);
+ return date->setMonthsSinceEpoch(value);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/MonthInputType.h b/Source/WebCore/html/MonthInputType.h
new file mode 100644
index 0000000..23536e2
--- /dev/null
+++ b/Source/WebCore/html/MonthInputType.h
@@ -0,0 +1,60 @@
+/*
+ * 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:
+ *
+ * * 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 MonthInputType_h
+#define MonthInputType_h
+
+#include "BaseDateAndTimeInputType.h"
+
+namespace WebCore {
+
+class MonthInputType : public BaseDateAndTimeInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ MonthInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual double valueAsDate() const;
+ virtual void setValueAsDate(double, ExceptionCode&) const;
+ virtual double parseToDouble(const String&, double) const;
+ virtual double defaultValueForStepUp() const;
+ virtual double minimum() const;
+ virtual double maximum() const;
+ virtual double defaultStep() const;
+ virtual double stepScaleFactor() const;
+ virtual bool parsedStepValueShouldBeInteger() const;
+ virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const;
+ virtual bool setMillisecondToDateComponents(double, DateComponents*) const;
+};
+
+} // namespace WebCore
+
+#endif // MonthInputType_h
diff --git a/Source/WebCore/html/NumberInputType.cpp b/Source/WebCore/html/NumberInputType.cpp
new file mode 100644
index 0000000..3916527
--- /dev/null
+++ b/Source/WebCore/html/NumberInputType.cpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 "NumberInputType.h"
+
+#include "BeforeTextInsertedEvent.h"
+#include "ExceptionCode.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "KeyboardEvent.h"
+#include "RenderTextControl.h"
+#include <limits>
+#include <wtf/ASCIICType.h>
+#include <wtf/MathExtras.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+using namespace std;
+
+static const double numberDefaultMinimum = -FLT_MAX;
+static const double numberDefaultMaximum = FLT_MAX;
+
+static const double numberDefaultStep = 1.0;
+static const double numberStepScaleFactor = 1.0;
+
+static bool isNumberCharacter(UChar ch)
+{
+ return ch == '+' || ch == '-' || ch == '.' || ch == 'e' || ch == 'E' || isASCIIDigit(ch);
+}
+
+PassOwnPtr<InputType> NumberInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new NumberInputType(element));
+}
+
+const AtomicString& NumberInputType::formControlType() const
+{
+ return InputTypeNames::number();
+}
+
+double NumberInputType::valueAsNumber() const
+{
+ return parseToDouble(element()->value(), numeric_limits<double>::quiet_NaN());
+}
+
+void NumberInputType::setValueAsNumber(double newValue, ExceptionCode& ec) const
+{
+ if (newValue < numberDefaultMinimum) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+ if (newValue > numberDefaultMaximum) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+ element()->setValue(serialize(newValue));
+}
+
+bool NumberInputType::typeMismatchFor(const String& value) const
+{
+ return !value.isEmpty() && !parseToDoubleForNumberType(value, 0);
+}
+
+bool NumberInputType::typeMismatch() const
+{
+ ASSERT(!typeMismatchFor(element()->value()));
+ return false;
+}
+
+bool NumberInputType::rangeUnderflow(const String& value) const
+{
+ const double nan = numeric_limits<double>::quiet_NaN();
+ double doubleValue = parseToDouble(value, nan);
+ return isfinite(doubleValue) && doubleValue < minimum();
+}
+
+bool NumberInputType::rangeOverflow(const String& value) const
+{
+ const double nan = numeric_limits<double>::quiet_NaN();
+ double doubleValue = parseToDouble(value, nan);
+ return isfinite(doubleValue) && doubleValue > maximum();
+}
+
+bool NumberInputType::supportsRangeLimitation() const
+{
+ return true;
+}
+
+double NumberInputType::minimum() const
+{
+ return parseToDouble(element()->fastGetAttribute(minAttr), numberDefaultMinimum);
+}
+
+double NumberInputType::maximum() const
+{
+ return parseToDouble(element()->fastGetAttribute(maxAttr), numberDefaultMaximum);
+}
+
+bool NumberInputType::stepMismatch(const String& value, double step) const
+{
+ double doubleValue;
+ if (!parseToDoubleForNumberType(value, &doubleValue))
+ return false;
+ doubleValue = fabs(doubleValue - stepBase());
+ if (isinf(doubleValue))
+ return false;
+ // double'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.
+ if (doubleValue / pow(2.0, DBL_MANT_DIG) > step)
+ return false;
+ // The computation follows HTML5 4.10.7.2.10 `The step attribute' :
+ // ... that number subtracted from the step base is not an integral multiple
+ // of the allowed value step, the element is suffering from a step mismatch.
+ double remainder = fabs(doubleValue - step * round(doubleValue / step));
+ // Accepts erros in lower fractional part which IEEE 754 single-precision
+ // can't represent.
+ double computedAcceptableError = acceptableError(step);
+ return computedAcceptableError < remainder && remainder < (step - computedAcceptableError);
+}
+
+double NumberInputType::stepBase() const
+{
+ return parseToDouble(element()->fastGetAttribute(minAttr), defaultStepBase());
+}
+
+double NumberInputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const
+{
+ return parseToDoubleWithDecimalPlaces(element()->fastGetAttribute(minAttr), defaultStepBase(), decimalPlaces);
+}
+
+double NumberInputType::defaultStep() const
+{
+ return numberDefaultStep;
+}
+
+double NumberInputType::stepScaleFactor() const
+{
+ return numberStepScaleFactor;
+}
+
+void NumberInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+ handleKeydownEventForSpinButton(event);
+ if (!event->defaultHandled())
+ TextFieldInputType::handleKeydownEvent(event);
+}
+
+void NumberInputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event)
+{
+ unsigned length = event->text().length();
+ bool hasInvalidChar = false;
+ for (unsigned i = 0; i < length; ++i) {
+ if (!isNumberCharacter(event->text()[i])) {
+ hasInvalidChar = true;
+ break;
+ }
+ }
+ if (hasInvalidChar) {
+ Vector<UChar> stripped;
+ stripped.reserveCapacity(length);
+ for (unsigned i = 0; i < length; ++i) {
+ UChar ch = event->text()[i];
+ if (!isNumberCharacter(ch))
+ continue;
+ stripped.append(ch);
+ }
+ event->setText(String::adopt(stripped));
+ }
+ TextFieldInputType::handleBeforeTextInsertedEvent(event);
+}
+
+void NumberInputType::handleWheelEvent(WheelEvent* event)
+{
+ handleWheelEventForSpinButton(event);
+}
+
+double NumberInputType::parseToDouble(const String& src, double defaultValue) const
+{
+ double numberValue;
+ if (!parseToDoubleForNumberType(src, &numberValue))
+ return defaultValue;
+ ASSERT(isfinite(numberValue));
+ return numberValue;
+}
+
+double NumberInputType::parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const
+{
+ double numberValue;
+ if (!parseToDoubleForNumberTypeWithDecimalPlaces(src, &numberValue, decimalPlaces))
+ return defaultValue;
+ ASSERT(isfinite(numberValue));
+ return numberValue;
+}
+
+String NumberInputType::serialize(double value) const
+{
+ if (!isfinite(value))
+ return String();
+ return serializeForNumberType(value);
+}
+
+double NumberInputType::acceptableError(double step) const
+{
+ return step / pow(2.0, FLT_MANT_DIG);
+}
+
+void NumberInputType::handleBlurEvent()
+{
+ // Reset the renderer value, which might be unmatched with the element value.
+ element()->setFormControlValueMatchesRenderer(false);
+
+ // We need to reset the renderer value explicitly because an unacceptable
+ // renderer value should be purged before style calculation.
+ if (element()->renderer())
+ element()->renderer()->updateFromElement();
+}
+
+bool NumberInputType::isAcceptableValue(const String& proposedValue)
+{
+ return proposedValue.isEmpty() || parseToDoubleForNumberType(proposedValue, 0);
+}
+
+String NumberInputType::sanitizeValue(const String& proposedValue)
+{
+ return parseToDoubleForNumberType(proposedValue, 0) ? proposedValue : String();
+}
+
+bool NumberInputType::hasUnacceptableValue()
+{
+ return element()->renderer() && !isAcceptableValue(toRenderTextControl(element()->renderer())->text());
+}
+
+bool NumberInputType::shouldRespectSpeechAttribute()
+{
+ return true;
+}
+
+bool NumberInputType::isNumberField() const
+{
+ return true;
+}
+
+bool NumberInputType::hasSpinButton()
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/NumberInputType.h b/Source/WebCore/html/NumberInputType.h
new file mode 100644
index 0000000..0b23d34
--- /dev/null
+++ b/Source/WebCore/html/NumberInputType.h
@@ -0,0 +1,77 @@
+/*
+ * 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:
+ *
+ * * 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 NumberInputType_h
+#define NumberInputType_h
+
+#include "TextFieldInputType.h"
+
+namespace WebCore {
+
+class NumberInputType : public TextFieldInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ NumberInputType(HTMLInputElement* element) : TextFieldInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual double valueAsNumber() const;
+ virtual void setValueAsNumber(double, ExceptionCode&) const;
+ virtual bool typeMismatchFor(const String&) const;
+ virtual bool typeMismatch() const;
+ virtual bool rangeUnderflow(const String&) const;
+ virtual bool rangeOverflow(const String&) const;
+ virtual bool supportsRangeLimitation() const;
+ virtual double minimum() const;
+ virtual double maximum() const;
+ virtual bool stepMismatch(const String&, double) const;
+ virtual double stepBase() const;
+ virtual double stepBaseWithDecimalPlaces(unsigned*) const;
+ virtual double defaultStep() const;
+ virtual double stepScaleFactor() const;
+ virtual void handleKeydownEvent(KeyboardEvent*);
+ virtual void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*);
+ virtual void handleWheelEvent(WheelEvent*);
+ virtual double parseToDouble(const String&, double) const;
+ virtual double parseToDoubleWithDecimalPlaces(const String&, double, unsigned*) const;
+ virtual String serialize(double) const;
+ virtual double acceptableError(double) const;
+ virtual void handleBlurEvent();
+ virtual bool isAcceptableValue(const String&);
+ virtual String sanitizeValue(const String&);
+ virtual bool hasUnacceptableValue();
+ virtual bool shouldRespectSpeechAttribute();
+ virtual bool isNumberField() const;
+ virtual bool hasSpinButton();
+};
+
+} // namespace WebCore
+
+#endif // NumberInputType_h
diff --git a/Source/WebCore/html/PasswordInputType.cpp b/Source/WebCore/html/PasswordInputType.cpp
new file mode 100644
index 0000000..2a9ad02
--- /dev/null
+++ b/Source/WebCore/html/PasswordInputType.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 "PasswordInputType.h"
+
+#include <wtf/Assertions.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<InputType> PasswordInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new PasswordInputType(element));
+}
+
+const AtomicString& PasswordInputType::formControlType() const
+{
+ return InputTypeNames::password();
+}
+
+bool PasswordInputType::saveFormControlState(String&) const
+{
+ // Should never save/restore password fields.
+ return false;
+}
+
+void PasswordInputType::restoreFormControlState(const String&) const
+{
+ // Should never save/restore password fields.
+ ASSERT_NOT_REACHED();
+}
+
+bool PasswordInputType::shouldUseInputMethod() const
+{
+ // Input methods are disabled for the password field because otherwise
+ // anyone can access the underlying password and display it in clear text.
+ return false;
+}
+
+bool PasswordInputType::shouldResetOnDocumentActivation()
+{
+ return true;
+}
+
+bool PasswordInputType::shouldRespectListAttribute()
+{
+ return false;
+}
+
+bool PasswordInputType::shouldRespectSpeechAttribute()
+{
+ return true;
+}
+
+bool PasswordInputType::isPasswordField() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/PasswordInputType.h b/Source/WebCore/html/PasswordInputType.h
new file mode 100644
index 0000000..04c82b5
--- /dev/null
+++ b/Source/WebCore/html/PasswordInputType.h
@@ -0,0 +1,56 @@
+/*
+ * 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:
+ *
+ * * 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 PasswordInputType_h
+#define PasswordInputType_h
+
+#include "BaseTextInputType.h"
+
+namespace WebCore {
+
+class PasswordInputType : public BaseTextInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ PasswordInputType(HTMLInputElement* element) : BaseTextInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool saveFormControlState(String&) const;
+ virtual void restoreFormControlState(const String&) const;
+ virtual bool shouldUseInputMethod() const;
+ virtual bool shouldResetOnDocumentActivation();
+ virtual bool shouldRespectListAttribute();
+ virtual bool shouldRespectSpeechAttribute();
+ virtual bool isPasswordField() const;
+};
+
+} // namespace WebCore
+
+#endif // PasswordInputType_h
diff --git a/Source/WebCore/html/PluginDocument.cpp b/Source/WebCore/html/PluginDocument.cpp
new file mode 100644
index 0000000..cebb949
--- /dev/null
+++ b/Source/WebCore/html/PluginDocument.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2006, 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
+ * 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 "PluginDocument.h"
+
+#include "DocumentLoader.h"
+#include "Frame.h"
+#include "FrameLoaderClient.h"
+#include "HTMLEmbedElement.h"
+#include "HTMLHtmlElement.h"
+#include "HTMLNames.h"
+#include "MainResourceLoader.h"
+#include "NodeList.h"
+#include "Page.h"
+#include "RawDataDocumentParser.h"
+#include "RenderEmbeddedObject.h"
+#include "Settings.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+// FIXME: Share more code with MediaDocumentParser.
+class PluginDocumentParser : public RawDataDocumentParser {
+public:
+ static PassRefPtr<PluginDocumentParser> create(PluginDocument* document)
+ {
+ return adoptRef(new PluginDocumentParser(document));
+ }
+
+private:
+ PluginDocumentParser(Document* document)
+ : RawDataDocumentParser(document)
+ , m_embedElement(0)
+ {
+ }
+
+ virtual void appendBytes(DocumentWriter*, const char*, int, bool);
+
+ void createDocumentStructure();
+
+ HTMLEmbedElement* m_embedElement;
+};
+
+void PluginDocumentParser::createDocumentStructure()
+{
+ ExceptionCode ec;
+ RefPtr<Element> rootElement = document()->createElement(htmlTag, false);
+ document()->appendChild(rootElement, ec);
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ static_cast<HTMLHtmlElement*>(rootElement.get())->insertedByParser();
+#endif
+
+ if (document()->frame() && document()->frame()->loader())
+ document()->frame()->loader()->dispatchDocumentElementAvailable();
+
+ RefPtr<Element> body = document()->createElement(bodyTag, false);
+ body->setAttribute(marginwidthAttr, "0");
+ body->setAttribute(marginheightAttr, "0");
+ body->setAttribute(bgcolorAttr, "rgb(38,38,38)");
+
+ rootElement->appendChild(body, ec);
+
+ RefPtr<Element> embedElement = document()->createElement(embedTag, false);
+
+ m_embedElement = static_cast<HTMLEmbedElement*>(embedElement.get());
+ m_embedElement->setAttribute(widthAttr, "100%");
+ m_embedElement->setAttribute(heightAttr, "100%");
+
+ m_embedElement->setAttribute(nameAttr, "plugin");
+ m_embedElement->setAttribute(srcAttr, document()->url().string());
+ m_embedElement->setAttribute(typeAttr, document()->frame()->loader()->writer()->mimeType());
+
+ static_cast<PluginDocument*>(document())->setPluginNode(m_embedElement);
+
+ body->appendChild(embedElement, ec);
+}
+
+void PluginDocumentParser::appendBytes(DocumentWriter*, const char*, int, bool)
+{
+ ASSERT(!m_embedElement);
+ if (m_embedElement)
+ return;
+
+ createDocumentStructure();
+
+ Frame* frame = document()->frame();
+ if (!frame)
+ return;
+ Settings* settings = frame->settings();
+ if (!settings || !frame->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin))
+ return;
+
+ document()->updateLayout();
+
+ if (RenderPart* renderer = m_embedElement->renderPart()) {
+ if (Widget* widget = renderer->widget()) {
+ frame->loader()->client()->redirectDataToPlugin(widget);
+ // In a plugin document, the main resource is the plugin. If we have a null widget, that means
+ // the loading of the plugin was cancelled, which gives us a null mainResourceLoader(), so we
+ // need to have this call in a null check of the widget or of mainResourceLoader().
+ frame->loader()->activeDocumentLoader()->mainResourceLoader()->setShouldBufferData(false);
+ }
+ }
+
+ finish();
+}
+
+PluginDocument::PluginDocument(Frame* frame, const KURL& url)
+ : HTMLDocument(frame, url)
+ , m_shouldLoadPluginManually(true)
+{
+ setCompatibilityMode(QuirksMode);
+ lockCompatibilityMode();
+}
+
+PassRefPtr<DocumentParser> PluginDocument::createParser()
+{
+ return PluginDocumentParser::create(this);
+}
+
+Widget* PluginDocument::pluginWidget()
+{
+ if (m_pluginNode && m_pluginNode->renderer()) {
+ ASSERT(m_pluginNode->renderer()->isEmbeddedObject());
+ return toRenderEmbeddedObject(m_pluginNode->renderer())->widget();
+ }
+ return 0;
+}
+
+Node* PluginDocument::pluginNode()
+{
+ return m_pluginNode.get();
+}
+
+void PluginDocument::detach()
+{
+ // Release the plugin node so that we don't have a circular reference.
+ m_pluginNode = 0;
+ HTMLDocument::detach();
+}
+
+void PluginDocument::cancelManualPluginLoad()
+{
+ // PluginDocument::cancelManualPluginLoad should only be called once, but there are issues
+ // with how many times we call beforeload on object elements. <rdar://problem/8441094>.
+ if (!shouldLoadPluginManually())
+ return;
+
+ frame()->loader()->activeDocumentLoader()->mainResourceLoader()->cancel();
+ setShouldLoadPluginManually(false);
+}
+
+}
diff --git a/Source/WebCore/html/PluginDocument.h b/Source/WebCore/html/PluginDocument.h
new file mode 100644
index 0000000..da0bb75
--- /dev/null
+++ b/Source/WebCore/html/PluginDocument.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2006, 2008, 2009Apple 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 PluginDocument_h
+#define PluginDocument_h
+
+#include "HTMLDocument.h"
+
+namespace WebCore {
+
+class Node;
+class Widget;
+class PluginDocument : public HTMLDocument {
+public:
+ static PassRefPtr<PluginDocument> create(Frame* frame, const KURL& url)
+ {
+ return adoptRef(new PluginDocument(frame, url));
+ }
+
+ void setPluginNode(Node* pluginNode) { m_pluginNode = pluginNode; }
+
+ Widget* pluginWidget();
+ Node* pluginNode();
+
+ virtual bool isPluginDocument() const { return true; }
+
+ virtual void detach();
+
+ void cancelManualPluginLoad();
+
+ bool shouldLoadPluginManually() { return m_shouldLoadPluginManually; }
+
+private:
+ PluginDocument(Frame*, const KURL&);
+
+ virtual PassRefPtr<DocumentParser> createParser();
+
+ void setShouldLoadPluginManually(bool loadManually) { m_shouldLoadPluginManually = loadManually; }
+
+ bool m_shouldLoadPluginManually;
+ RefPtr<Node> m_pluginNode;
+};
+
+inline PluginDocument* toPluginDocument(Document* document)
+{
+ ASSERT(!document || document->isPluginDocument());
+ return static_cast<PluginDocument*>(document);
+}
+
+inline const PluginDocument* toPluginDocument(const Document* document)
+{
+ ASSERT(!document || document->isPluginDocument());
+ return static_cast<const PluginDocument*>(document);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toPluginDocument(const PluginDocument*);
+
+}
+
+#endif // PluginDocument_h
diff --git a/Source/WebCore/html/RadioInputType.cpp b/Source/WebCore/html/RadioInputType.cpp
new file mode 100644
index 0000000..0c13161
--- /dev/null
+++ b/Source/WebCore/html/RadioInputType.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2005, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "RadioInputType.h"
+
+#include "Frame.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "KeyboardEvent.h"
+#include "LocalizedStrings.h"
+#include "MouseEvent.h"
+#include "Settings.h"
+#include "SpatialNavigation.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+PassOwnPtr<InputType> RadioInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new RadioInputType(element));
+}
+
+const AtomicString& RadioInputType::formControlType() const
+{
+ return InputTypeNames::radio();
+}
+
+bool RadioInputType::valueMissing(const String&) const
+{
+ return !element()->checkedRadioButtons().checkedButtonForGroup(element()->name());
+}
+
+String RadioInputType::valueMissingText() const
+{
+ return validationMessageValueMissingForRadioText();
+}
+
+void RadioInputType::handleClickEvent(MouseEvent* event)
+{
+ event->setDefaultHandled();
+}
+
+void RadioInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+ BaseCheckableInputType::handleKeydownEvent(event);
+ if (event->defaultHandled())
+ return;
+ const String& key = event->keyIdentifier();
+ if (key != "Up" && key != "Down" && key != "Left" && key != "Right")
+ return;
+
+ // Left and up mean "previous radio button".
+ // Right and down mean "next radio button".
+ // Tested in WinIE, and even for RTL, left still means previous radio button (and so moves
+ // to the right). Seems strange, but we'll match it.
+ // However, when using Spatial Navigation, we need to be able to navigate without changing the selection.
+ Document* document = element()->document();
+ if (isSpatialNavigationEnabled(document->frame()))
+ return;
+ bool forward = (key == "Down" || key == "Right");
+
+ // 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 ? node->traverseNextNode() : node->traversePreviousNode()))) {
+ // Once we encounter a form element, we know we're through.
+ if (node->hasTagName(formTag))
+ break;
+ // Look for more radio buttons.
+ if (!node->hasTagName(inputTag))
+ continue;
+ HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node);
+ if (inputElement->form() != element()->form())
+ break;
+ if (inputElement->isRadioButton() && inputElement->name() == element()->name() && inputElement->isFocusable()) {
+ inputElement->setChecked(true);
+ document->setFocusedNode(inputElement);
+ inputElement->dispatchSimulatedClick(event, false, false);
+ event->setDefaultHandled();
+ return;
+ }
+ }
+}
+
+void RadioInputType::handleKeyupEvent(KeyboardEvent* event)
+{
+ const String& key = event->keyIdentifier();
+ if (key != "U+0020")
+ return;
+ // If an unselected radio is tabbed into (because the entire group has nothing
+ // checked, or because of some explicit .focus() call), then allow space to check it.
+ if (element()->checked())
+ return;
+ dispatchSimulatedClickIfActive(event);
+}
+
+bool RadioInputType::isKeyboardFocusable() const
+{
+ // When using Spatial Navigation, every radio button should be focusable.
+ if (isSpatialNavigationEnabled(element()->document()->frame()))
+ return true;
+
+ // Never allow keyboard tabbing to leave you in the same radio group. Always
+ // skip any other elements in the group.
+ Node* currentFocusedNode = element()->document()->focusedNode();
+ if (currentFocusedNode && currentFocusedNode->hasTagName(inputTag)) {
+ HTMLInputElement* focusedInput = static_cast<HTMLInputElement*>(currentFocusedNode);
+ if (focusedInput->isRadioButton() && focusedInput->form() == element()->form() && focusedInput->name() == element()->name())
+ return false;
+ }
+
+ // Allow keyboard focus if we're checked or if nothing in the group is checked.
+ return element()->checked() || !element()->checkedRadioButtons().checkedButtonForGroup(element()->name());
+}
+
+void RadioInputType::attach()
+{
+ InputType::attach();
+ element()->updateCheckedRadioButtons();
+}
+
+bool RadioInputType::shouldSendChangeEventAfterCheckedChanged()
+{
+ // Don't send a change event for a radio button that's getting unchecked.
+ // This was done to match the behavior of other browsers.
+ return element()->checked();
+}
+
+PassOwnPtr<ClickHandlingState> RadioInputType::willDispatchClick()
+{
+ // An event handler can use preventDefault or "return false" to reverse the selection we do here.
+ // The ClickHandlingState object contains what we need to undo what we did here in didDispatchClick.
+
+ // We want radio groups to end up in sane states, i.e., to have something checked.
+ // Therefore if nothing is currently selected, we won't allow the upcoming action to be "undone", since
+ // we want some object in the radio group to actually get selected.
+
+ OwnPtr<ClickHandlingState> state = adoptPtr(new ClickHandlingState);
+
+ state->checked = element()->checked();
+ state->indeterminate = element()->indeterminate();
+ state->checkedRadioButton = element()->checkedRadioButtons().checkedButtonForGroup(element()->name());
+
+ if (element()->indeterminate())
+ element()->setIndeterminate(false);
+ element()->setChecked(true, true);
+
+ return state.release();
+}
+
+void RadioInputType::didDispatchClick(Event* event, const ClickHandlingState& state)
+{
+ if (event->defaultPrevented() || event->defaultHandled()) {
+ // Restore the original selected radio button if possible.
+ // Make sure it is still a radio button and only do the restoration if it still belongs to our group.
+ HTMLInputElement* checkedRadioButton = state.checkedRadioButton.get();
+ if (checkedRadioButton
+ && checkedRadioButton->isRadioButton()
+ && checkedRadioButton->form() == element()->form()
+ && checkedRadioButton->name() == element()->name()) {
+ checkedRadioButton->setChecked(true);
+ }
+ element()->setIndeterminate(state.indeterminate);
+ }
+
+ // The work we did in willDispatchClick was default handling.
+ event->setDefaultHandled();
+}
+
+bool RadioInputType::isRadioButton() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/RadioInputType.h b/Source/WebCore/html/RadioInputType.h
new file mode 100644
index 0000000..8c731d0
--- /dev/null
+++ b/Source/WebCore/html/RadioInputType.h
@@ -0,0 +1,60 @@
+/*
+ * 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:
+ *
+ * * 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 RadioInputType_h
+#define RadioInputType_h
+
+#include "BaseCheckableInputType.h"
+
+namespace WebCore {
+
+class RadioInputType : public BaseCheckableInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ RadioInputType(HTMLInputElement* element) : BaseCheckableInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool valueMissing(const String&) const;
+ virtual String valueMissingText() const;
+ virtual void handleClickEvent(MouseEvent*);
+ virtual void handleKeydownEvent(KeyboardEvent*);
+ virtual void handleKeyupEvent(KeyboardEvent*);
+ virtual bool isKeyboardFocusable() const;
+ virtual void attach();
+ virtual bool shouldSendChangeEventAfterCheckedChanged();
+ virtual PassOwnPtr<ClickHandlingState> willDispatchClick();
+ virtual void didDispatchClick(Event*, const ClickHandlingState&);
+ virtual bool isRadioButton() const;
+};
+
+} // namespace WebCore
+
+#endif // RadioInputType_h
diff --git a/Source/WebCore/html/RangeInputType.cpp b/Source/WebCore/html/RangeInputType.cpp
new file mode 100644
index 0000000..5d71da7
--- /dev/null
+++ b/Source/WebCore/html/RangeInputType.cpp
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 "RangeInputType.h"
+
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "KeyboardEvent.h"
+#include "RenderSlider.h"
+#include "StepRange.h"
+#include <limits>
+#include <wtf/MathExtras.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+using namespace std;
+
+static const double rangeDefaultMinimum = 0.0;
+static const double rangeDefaultMaximum = 100.0;
+static const double rangeDefaultStep = 1.0;
+static const double rangeStepScaleFactor = 1.0;
+
+PassOwnPtr<InputType> RangeInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new RangeInputType(element));
+}
+
+bool RangeInputType::isRangeControl() const
+{
+ return true;
+}
+
+const AtomicString& RangeInputType::formControlType() const
+{
+ return InputTypeNames::range();
+}
+
+double RangeInputType::valueAsNumber() const
+{
+ return parseToDouble(element()->value(), numeric_limits<double>::quiet_NaN());
+}
+
+void RangeInputType::setValueAsNumber(double newValue, ExceptionCode&) const
+{
+ element()->setValue(serialize(newValue));
+}
+
+bool RangeInputType::supportsRequired() const
+{
+ return false;
+}
+
+bool RangeInputType::rangeUnderflow(const String& value) const
+{
+ // Guaranteed by sanitization.
+ ASSERT_UNUSED(value, parseToDouble(value, numeric_limits<double>::quiet_NaN()) >= minimum());
+ return false;
+}
+
+bool RangeInputType::rangeOverflow(const String& value) const
+{
+ // Guaranteed by sanitization.
+ ASSERT_UNUSED(value, parseToDouble(value, numeric_limits<double>::quiet_NaN()) <= maximum());
+ return false;
+}
+
+bool RangeInputType::supportsRangeLimitation() const
+{
+ return true;
+}
+
+double RangeInputType::minimum() const
+{
+ return parseToDouble(element()->fastGetAttribute(minAttr), rangeDefaultMinimum);
+}
+
+double RangeInputType::maximum() const
+{
+ double max = parseToDouble(element()->fastGetAttribute(maxAttr), rangeDefaultMaximum);
+ // A remedy for the inconsistent min/max values.
+ // Sets the maximum to the default or the minimum value.
+ double min = minimum();
+ if (max < min)
+ max = std::max(min, rangeDefaultMaximum);
+ return max;
+}
+
+bool RangeInputType::stepMismatch(const String&, double) const
+{
+ // stepMismatch doesn't occur for type=range. RenderSlider guarantees the
+ // value matches to step on user input, and sanitization takes care
+ // of the general case.
+ return false;
+}
+
+double RangeInputType::stepBase() const
+{
+ return minimum();
+}
+
+double RangeInputType::defaultStep() const
+{
+ return rangeDefaultStep;
+}
+
+double RangeInputType::stepScaleFactor() const
+{
+ return rangeStepScaleFactor;
+}
+
+void RangeInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+ const String& key = event->keyIdentifier();
+ if (key != "Up" && key != "Right" && key != "Down" && key != "Left")
+ return;
+
+ ExceptionCode ec;
+ if (equalIgnoringCase(element()->fastGetAttribute(stepAttr), "any")) {
+ double min = minimum();
+ double max = maximum();
+ // FIXME: We can't use stepUp() for the step value "any". So, we increase
+ // or decrease the value by 1/100 of the value range. Is it reasonable?
+ double step = (max - min) / 100;
+ double current = parseToDouble(element()->value(), numeric_limits<double>::quiet_NaN());
+ ASSERT(isfinite(current));
+ // Stepping-up and -down for step="any" are special cases for type="range" from renderer for convenient.
+ // No stepping normally for step="any". They cannot be handled by stepUp()/stepDown()/stepUpFromRenderer().
+ // So calculating values stepped-up or -down here.
+ double newValue;
+ if (key == "Up" || key == "Right") {
+ newValue = current + step;
+ if (newValue > max)
+ newValue = max;
+ } else {
+ newValue = current - step;
+ if (newValue < min)
+ newValue = min;
+ }
+ if (newValue != current) {
+ setValueAsNumber(newValue, ec);
+ element()->dispatchFormControlChangeEvent();
+ }
+ } else {
+ int stepMagnification = (key == "Up" || key == "Right") ? 1 : -1;
+ // Reasonable stepping-up/-down by stepUpFromRenderer() unless step="any"
+ element()->stepUpFromRenderer(stepMagnification);
+ }
+ event->setDefaultHandled();
+}
+
+void RangeInputType::forwardEvent(Event* event)
+{
+ if (element()->renderer() && (event->isMouseEvent() || event->isDragEvent() || event->isWheelEvent()))
+ toRenderSlider(element()->renderer())->forwardEvent(event);
+}
+
+RenderObject* RangeInputType::createRenderer(RenderArena* arena, RenderStyle*) const
+{
+ return new (arena) RenderSlider(element());
+}
+
+double RangeInputType::parseToDouble(const String& src, double defaultValue) const
+{
+ double numberValue;
+ if (!parseToDoubleForNumberType(src, &numberValue))
+ return defaultValue;
+ ASSERT(isfinite(numberValue));
+ return numberValue;
+}
+
+String RangeInputType::serialize(double value) const
+{
+ if (!isfinite(value))
+ return String();
+ return serializeForNumberType(value);
+}
+
+// FIXME: Could share this with BaseButtonInputType and BaseCheckableInputType if we had a common base class.
+void RangeInputType::accessKeyAction(bool sendToAnyElement)
+{
+ InputType::accessKeyAction(sendToAnyElement);
+
+ // Send mouse button events if the caller specified sendToAnyElement.
+ // FIXME: The comment above is no good. It says what we do, but not why.
+ element()->dispatchSimulatedClick(0, sendToAnyElement);
+}
+
+void RangeInputType::minOrMaxAttributeChanged()
+{
+ InputType::minOrMaxAttributeChanged();
+
+ // Sanitize the value.
+ element()->setValue(element()->value());
+ element()->setNeedsStyleRecalc();
+}
+
+String RangeInputType::fallbackValue()
+{
+ return serializeForNumberType(StepRange(element()).defaultValue());
+}
+
+String RangeInputType::sanitizeValue(const String& proposedValue)
+{
+ // If the proposedValue is null than this is a reset scenario and we
+ // want the range input's value attribute to take priority over the
+ // calculated default (middle) value.
+ if (proposedValue.isNull())
+ return proposedValue;
+
+ return serializeForNumberType(StepRange(element()).clampValue(proposedValue));
+}
+
+bool RangeInputType::shouldRespectListAttribute()
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/RangeInputType.h b/Source/WebCore/html/RangeInputType.h
new file mode 100644
index 0000000..7f341a7
--- /dev/null
+++ b/Source/WebCore/html/RangeInputType.h
@@ -0,0 +1,72 @@
+/*
+ * 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:
+ *
+ * * 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 RangeInputType_h
+#define RangeInputType_h
+
+#include "InputType.h"
+
+namespace WebCore {
+
+class RangeInputType : public InputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ RangeInputType(HTMLInputElement* element) : InputType(element) { }
+ virtual bool isRangeControl() const;
+ virtual const AtomicString& formControlType() const;
+ virtual double valueAsNumber() const;
+ virtual void setValueAsNumber(double, ExceptionCode&) const;
+ virtual bool supportsRequired() const;
+ virtual bool rangeUnderflow(const String&) const;
+ virtual bool rangeOverflow(const String&) const;
+ virtual bool supportsRangeLimitation() const;
+ virtual double minimum() const;
+ virtual double maximum() const;
+ virtual bool stepMismatch(const String&, double) const;
+ virtual double stepBase() const;
+ virtual double defaultStep() const;
+ virtual double stepScaleFactor() const;
+ virtual void handleKeydownEvent(KeyboardEvent*);
+ virtual void forwardEvent(Event*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
+ virtual double parseToDouble(const String&, double) const;
+ virtual String serialize(double) const;
+ virtual void accessKeyAction(bool sendToAnyElement);
+ virtual void minOrMaxAttributeChanged();
+ virtual String fallbackValue();
+ virtual String sanitizeValue(const String& proposedValue);
+ virtual bool shouldRespectListAttribute();
+};
+
+} // namespace WebCore
+
+#endif // RangeInputType_h
diff --git a/Source/WebCore/html/ResetInputType.cpp b/Source/WebCore/html/ResetInputType.cpp
new file mode 100644
index 0000000..4a7be33
--- /dev/null
+++ b/Source/WebCore/html/ResetInputType.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 "ResetInputType.h"
+
+#include "Event.h"
+#include "HTMLFormElement.h"
+#include "HTMLInputElement.h"
+#include "LocalizedStrings.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<InputType> ResetInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new ResetInputType(element));
+}
+
+const AtomicString& ResetInputType::formControlType() const
+{
+ return InputTypeNames::reset();
+}
+
+bool ResetInputType::supportsValidation() const
+{
+ return false;
+}
+
+void ResetInputType::handleDOMActivateEvent(Event* event)
+{
+ if (element()->disabled() || !element()->form())
+ return;
+ element()->form()->reset();
+ event->setDefaultHandled();
+}
+
+String ResetInputType::defaultValue()
+{
+ return resetButtonDefaultLabel();
+}
+
+bool ResetInputType::isTextButton() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/ResetInputType.h b/Source/WebCore/html/ResetInputType.h
new file mode 100644
index 0000000..2c633bc
--- /dev/null
+++ b/Source/WebCore/html/ResetInputType.h
@@ -0,0 +1,53 @@
+/*
+ * 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:
+ *
+ * * 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 ResetInputType_h
+#define ResetInputType_h
+
+#include "BaseButtonInputType.h"
+
+namespace WebCore {
+
+class ResetInputType : public BaseButtonInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ ResetInputType(HTMLInputElement* element) : BaseButtonInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool supportsValidation() const;
+ virtual void handleDOMActivateEvent(Event*);
+ virtual String defaultValue();
+ virtual bool isTextButton() const;
+};
+
+} // namespace WebCore
+
+#endif // ResetInputType_h
diff --git a/Source/WebCore/html/SearchInputType.cpp b/Source/WebCore/html/SearchInputType.cpp
new file mode 100644
index 0000000..2006486
--- /dev/null
+++ b/Source/WebCore/html/SearchInputType.cpp
@@ -0,0 +1,58 @@
+/*
+ * 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:
+ *
+ * * 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 "SearchInputType.h"
+
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<InputType> SearchInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new SearchInputType(element));
+}
+
+const AtomicString& SearchInputType::formControlType() const
+{
+ return InputTypeNames::search();
+}
+
+bool SearchInputType::shouldRespectSpeechAttribute()
+{
+ return true;
+}
+
+bool SearchInputType::isSearchField() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/SearchInputType.h b/Source/WebCore/html/SearchInputType.h
new file mode 100644
index 0000000..56cda53
--- /dev/null
+++ b/Source/WebCore/html/SearchInputType.h
@@ -0,0 +1,51 @@
+/*
+ * 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:
+ *
+ * * 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 SearchInputType_h
+#define SearchInputType_h
+
+#include "BaseTextInputType.h"
+
+namespace WebCore {
+
+class SearchInputType : public BaseTextInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ SearchInputType(HTMLInputElement* element) : BaseTextInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool shouldRespectSpeechAttribute();
+ virtual bool isSearchField() const;
+};
+
+} // namespace WebCore
+
+#endif // SearchInputType_h
diff --git a/Source/WebCore/html/StepRange.cpp b/Source/WebCore/html/StepRange.cpp
new file mode 100644
index 0000000..68b0ebd
--- /dev/null
+++ b/Source/WebCore/html/StepRange.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "StepRange.h"
+
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include <wtf/MathExtras.h>
+#include <wtf/text/WTFString.h>
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+StepRange::StepRange(const HTMLInputElement* element)
+{
+ if (element->hasAttribute(precisionAttr)) {
+ step = 1.0;
+ hasStep = !equalIgnoringCase(element->getAttribute(precisionAttr), "float");
+ } else
+ hasStep = element->getAllowedValueStep(&step);
+
+ maximum = element->maximum();
+ minimum = element->minimum();
+}
+
+double StepRange::clampValue(double value)
+{
+ double clampedValue = max(minimum, min(value, maximum));
+ if (!hasStep)
+ return clampedValue;
+ // Rounds clampedValue to minimum + N * step.
+ clampedValue = minimum + round((clampedValue - minimum) / step) * step;
+ if (clampedValue > maximum)
+ clampedValue -= step;
+ ASSERT(clampedValue >= minimum);
+ ASSERT(clampedValue <= maximum);
+ return clampedValue;
+}
+
+double StepRange::clampValue(const String& stringValue)
+{
+ double value;
+ bool parseSuccess = parseToDoubleForNumberType(stringValue, &value);
+ if (!parseSuccess)
+ value = (minimum + maximum) / 2;
+ return clampValue(value);
+}
+
+double StepRange::valueFromElement(HTMLInputElement* element, bool* wasClamped)
+{
+ double oldValue;
+ bool parseSuccess = parseToDoubleForNumberType(element->value(), &oldValue);
+ if (!parseSuccess)
+ oldValue = (minimum + maximum) / 2;
+ double newValue = clampValue(oldValue);
+
+ if (wasClamped)
+ *wasClamped = !parseSuccess || newValue != oldValue;
+
+ return newValue;
+}
+
+}
diff --git a/Source/WebCore/html/StepRange.h b/Source/WebCore/html/StepRange.h
new file mode 100644
index 0000000..ce044ea
--- /dev/null
+++ b/Source/WebCore/html/StepRange.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef StepRange_h
+#define StepRange_h
+
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class HTMLInputElement;
+
+class StepRange : public Noncopyable {
+public:
+ bool hasStep;
+ double step;
+ double minimum;
+ double maximum; // maximum must be >= minimum.
+
+ explicit StepRange(const HTMLInputElement*);
+ double clampValue(double value);
+ double clampValue(const String& stringValue);
+
+ // Clamp the middle value according to the step
+ double defaultValue()
+ {
+ return clampValue((minimum + maximum) / 2);
+ }
+
+ // Map value into 0-1 range
+ double proportionFromValue(double value)
+ {
+ if (minimum == maximum)
+ return 0;
+
+ return (value - minimum) / (maximum - minimum);
+ }
+
+ // Map from 0-1 range to value
+ double valueFromProportion(double proportion)
+ {
+ return minimum + proportion * (maximum - minimum);
+ }
+
+ double valueFromElement(HTMLInputElement*, bool* wasClamped = 0);
+};
+
+}
+
+#endif // StepRange_h
diff --git a/Source/WebCore/html/SubmitInputType.cpp b/Source/WebCore/html/SubmitInputType.cpp
new file mode 100644
index 0000000..da6dde8
--- /dev/null
+++ b/Source/WebCore/html/SubmitInputType.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 "SubmitInputType.h"
+
+#include "Event.h"
+#include "FormDataList.h"
+#include "HTMLFormElement.h"
+#include "HTMLInputElement.h"
+#include "LocalizedStrings.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<InputType> SubmitInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new SubmitInputType(element));
+}
+
+const AtomicString& SubmitInputType::formControlType() const
+{
+ return InputTypeNames::submit();
+}
+
+bool SubmitInputType::appendFormData(FormDataList& encoding, bool) const
+{
+ if (!element()->isActivatedSubmit())
+ return false;
+ encoding.appendData(element()->name(), element()->valueWithDefault());
+ return true;
+}
+
+bool SubmitInputType::supportsRequired() const
+{
+ return false;
+}
+
+void SubmitInputType::handleDOMActivateEvent(Event* event)
+{
+ RefPtr<HTMLInputElement> element = this->element();
+ if (element->disabled() || !element->form())
+ return;
+ element->setActivatedSubmit(true);
+ element->form()->prepareForSubmission(event); // Event handlers can run.
+ element->setActivatedSubmit(false);
+ event->setDefaultHandled();
+}
+
+bool SubmitInputType::canBeSuccessfulSubmitButton()
+{
+ return true;
+}
+
+String SubmitInputType::defaultValue()
+{
+ return submitButtonDefaultLabel();
+}
+
+bool SubmitInputType::isSubmitButton() const
+{
+ return true;
+}
+
+bool SubmitInputType::isTextButton() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/SubmitInputType.h b/Source/WebCore/html/SubmitInputType.h
new file mode 100644
index 0000000..c102871
--- /dev/null
+++ b/Source/WebCore/html/SubmitInputType.h
@@ -0,0 +1,56 @@
+/*
+ * 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:
+ *
+ * * 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 SubmitInputType_h
+#define SubmitInputType_h
+
+#include "BaseButtonInputType.h"
+
+namespace WebCore {
+
+class SubmitInputType : public BaseButtonInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ SubmitInputType(HTMLInputElement* element) : BaseButtonInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool appendFormData(FormDataList&, bool) const;
+ virtual bool supportsRequired() const;
+ virtual void handleDOMActivateEvent(Event*);
+ virtual bool canBeSuccessfulSubmitButton();
+ virtual String defaultValue();
+ virtual bool isSubmitButton() const;
+ virtual bool isTextButton() const;
+};
+
+} // namespace WebCore
+
+#endif // SubmitInputType_h
diff --git a/Source/WebCore/html/TelephoneInputType.cpp b/Source/WebCore/html/TelephoneInputType.cpp
new file mode 100644
index 0000000..c1c77f0
--- /dev/null
+++ b/Source/WebCore/html/TelephoneInputType.cpp
@@ -0,0 +1,58 @@
+/*
+ * 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:
+ *
+ * * 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 "TelephoneInputType.h"
+
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<InputType> TelephoneInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new TelephoneInputType(element));
+}
+
+const AtomicString& TelephoneInputType::formControlType() const
+{
+ return InputTypeNames::telephone();
+}
+
+bool TelephoneInputType::shouldRespectSpeechAttribute()
+{
+ return true;
+}
+
+bool TelephoneInputType::isTelephoneField() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/TelephoneInputType.h b/Source/WebCore/html/TelephoneInputType.h
new file mode 100644
index 0000000..602c883
--- /dev/null
+++ b/Source/WebCore/html/TelephoneInputType.h
@@ -0,0 +1,51 @@
+/*
+ * 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:
+ *
+ * * 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 TelephoneInputType_h
+#define TelephoneInputType_h
+
+#include "BaseTextInputType.h"
+
+namespace WebCore {
+
+class TelephoneInputType : public BaseTextInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ TelephoneInputType(HTMLInputElement* element) : BaseTextInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool shouldRespectSpeechAttribute();
+ virtual bool isTelephoneField() const;
+};
+
+} // namespace WebCore
+
+#endif // TelephoneInputType_h
diff --git a/Source/WebCore/html/TextDocument.cpp b/Source/WebCore/html/TextDocument.cpp
new file mode 100644
index 0000000..9334a39
--- /dev/null
+++ b/Source/WebCore/html/TextDocument.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2006, 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
+ * 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 "TextDocument.h"
+
+#include "TextDocumentParser.h"
+
+namespace WebCore {
+
+TextDocument::TextDocument(Frame* frame, const KURL& url)
+ : HTMLDocument(frame, url)
+{
+ setCompatibilityMode(QuirksMode);
+ lockCompatibilityMode();
+}
+
+PassRefPtr<DocumentParser> TextDocument::createParser()
+{
+ return TextDocumentParser::create(this);
+}
+
+}
diff --git a/Source/WebCore/html/TextDocument.h b/Source/WebCore/html/TextDocument.h
new file mode 100644
index 0000000..2ea49f8
--- /dev/null
+++ b/Source/WebCore/html/TextDocument.h
@@ -0,0 +1,47 @@
+/*
+ * 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 TextDocument_h
+#define TextDocument_h
+
+#include "HTMLDocument.h"
+
+namespace WebCore {
+
+class TextDocument : public HTMLDocument {
+public:
+ static PassRefPtr<TextDocument> create(Frame* frame, const KURL& url)
+ {
+ return adoptRef(new TextDocument(frame, url));
+ }
+
+private:
+ TextDocument(Frame*, const KURL&);
+
+ virtual PassRefPtr<DocumentParser> createParser();
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/TextFieldInputType.cpp b/Source/WebCore/html/TextFieldInputType.cpp
new file mode 100644
index 0000000..54527b1
--- /dev/null
+++ b/Source/WebCore/html/TextFieldInputType.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2010 Google 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
+ * 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 "TextFieldInputType.h"
+
+#include "Frame.h"
+#include "HTMLInputElement.h"
+#include "KeyboardEvent.h"
+#include "RenderTextControlSingleLine.h"
+#include "TextEvent.h"
+#include "WheelEvent.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+bool TextFieldInputType::isTextField() const
+{
+ return true;
+}
+
+bool TextFieldInputType::valueMissing(const String& value) const
+{
+ return value.isEmpty();
+}
+
+void TextFieldInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+ if (!element()->focused())
+ return;
+ Frame* frame = element()->document()->frame();
+ if (!frame || !frame->editor()->doTextFieldCommandFromEvent(element(), event))
+ return;
+ event->setDefaultHandled();
+}
+
+void TextFieldInputType::handleKeydownEventForSpinButton(KeyboardEvent* event)
+{
+ const String& key = event->keyIdentifier();
+ int step = 0;
+ if (key == "Up")
+ step = 1;
+ else if (key == "Down")
+ step = -1;
+ else
+ return;
+ element()->stepUpFromRenderer(step);
+ event->setDefaultHandled();
+}
+
+void TextFieldInputType::handleWheelEventForSpinButton(WheelEvent* event)
+{
+ int step = 0;
+ if (event->wheelDeltaY() > 0)
+ step = 1;
+ else if (event->wheelDeltaY() < 0)
+ step = -1;
+ else
+ return;
+ element()->stepUpFromRenderer(step);
+ event->setDefaultHandled();
+}
+
+void TextFieldInputType::forwardEvent(Event* event)
+{
+ if (element()->renderer() && (event->isMouseEvent() || event->isDragEvent() || event->isWheelEvent() || event->type() == eventNames().blurEvent || event->type() == eventNames().focusEvent))
+ toRenderTextControlSingleLine(element()->renderer())->forwardEvent(event);
+}
+
+bool TextFieldInputType::shouldSubmitImplicitly(Event* event)
+{
+ return (event->type() == eventNames().textInputEvent && event->isTextEvent() && static_cast<TextEvent*>(event)->data() == "\n") || InputType::shouldSubmitImplicitly(event);
+}
+
+RenderObject* TextFieldInputType::createRenderer(RenderArena* arena, RenderStyle*) const
+{
+ return new (arena) RenderTextControlSingleLine(element(), element()->placeholderShouldBeVisible());
+}
+
+bool TextFieldInputType::shouldUseInputMethod() const
+{
+ return true;
+}
+
+String TextFieldInputType::sanitizeValue(const String& proposedValue)
+{
+ return InputElement::sanitizeValueForTextField(element(), proposedValue);
+}
+
+bool TextFieldInputType::shouldRespectListAttribute()
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/TextFieldInputType.h b/Source/WebCore/html/TextFieldInputType.h
new file mode 100644
index 0000000..e882c82
--- /dev/null
+++ b/Source/WebCore/html/TextFieldInputType.h
@@ -0,0 +1,60 @@
+/*
+ * 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:
+ *
+ * * 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 TextFieldInputType_h
+#define TextFieldInputType_h
+
+#include "InputType.h"
+
+namespace WebCore {
+
+// 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:
+ TextFieldInputType(HTMLInputElement* element) : InputType(element) { }
+ virtual void handleKeydownEvent(KeyboardEvent*);
+ void handleKeydownEventForSpinButton(KeyboardEvent*);
+ void handleWheelEventForSpinButton(WheelEvent*);
+
+private:
+ virtual bool isTextField() const;
+ virtual bool valueMissing(const String&) const;
+ virtual void forwardEvent(Event*);
+ virtual bool shouldSubmitImplicitly(Event*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
+ virtual bool shouldUseInputMethod() const;
+ virtual String sanitizeValue(const String& proposedValue);
+ virtual bool shouldRespectListAttribute();
+};
+
+} // namespace WebCore
+
+#endif // TextFieldInputType_h
diff --git a/Source/WebCore/html/TextInputType.cpp b/Source/WebCore/html/TextInputType.cpp
new file mode 100644
index 0000000..c37263a
--- /dev/null
+++ b/Source/WebCore/html/TextInputType.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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:
+ *
+ * * 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 "TextInputType.h"
+
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<InputType> TextInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new TextInputType(element));
+}
+
+const AtomicString& TextInputType::formControlType() const
+{
+ return InputTypeNames::text();
+}
+
+bool TextInputType::canSetSuggestedValue()
+{
+ // FIXME: Should this really be restricted to plain text? What about search, for example?
+ return true;
+}
+
+bool TextInputType::shouldRespectSpeechAttribute()
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/TextInputType.h b/Source/WebCore/html/TextInputType.h
new file mode 100644
index 0000000..3b6810e
--- /dev/null
+++ b/Source/WebCore/html/TextInputType.h
@@ -0,0 +1,51 @@
+/*
+ * 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:
+ *
+ * * 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 TextInputType_h
+#define TextInputType_h
+
+#include "BaseTextInputType.h"
+
+namespace WebCore {
+
+class TextInputType : public BaseTextInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ TextInputType(HTMLInputElement* element) : BaseTextInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool canSetSuggestedValue();
+ virtual bool shouldRespectSpeechAttribute();
+};
+
+} // namespace WebCore
+
+#endif // TextInputType_h
diff --git a/Source/WebCore/html/TextMetrics.h b/Source/WebCore/html/TextMetrics.h
new file mode 100644
index 0000000..b272ef6
--- /dev/null
+++ b/Source/WebCore/html/TextMetrics.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 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
+ * 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 TextMetrics_h
+#define TextMetrics_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class TextMetrics : public RefCounted<TextMetrics> {
+public:
+ static PassRefPtr<TextMetrics> create() { return adoptRef(new TextMetrics); }
+
+ float width() const { return m_width; }
+ void setWidth(float w) { m_width = w; }
+
+private:
+ TextMetrics()
+ : m_width(0)
+ { }
+
+ float m_width;
+};
+
+} // namespace WebCore
+
+#endif // TextMetrics_h
diff --git a/Source/WebCore/html/TextMetrics.idl b/Source/WebCore/html/TextMetrics.idl
new file mode 100644
index 0000000..1a315ba
--- /dev/null
+++ b/Source/WebCore/html/TextMetrics.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 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
+ * 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.
+ */
+
+module html {
+
+ interface TextMetrics {
+ readonly attribute float width;
+ };
+
+}
diff --git a/Source/WebCore/html/TimeInputType.cpp b/Source/WebCore/html/TimeInputType.cpp
new file mode 100644
index 0000000..33423a9
--- /dev/null
+++ b/Source/WebCore/html/TimeInputType.cpp
@@ -0,0 +1,112 @@
+/*
+ * 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:
+ *
+ * * 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 "TimeInputType.h"
+
+#include "DateComponents.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/DateMath.h>
+#include <wtf/MathExtras.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static const double timeDefaultStep = 60.0;
+static const double timeStepScaleFactor = 1000.0;
+
+PassOwnPtr<InputType> TimeInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new TimeInputType(element));
+}
+
+const AtomicString& TimeInputType::formControlType() const
+{
+ return InputTypeNames::time();
+}
+
+double TimeInputType::defaultValueForStepUp() const
+{
+ double current = currentTimeMS();
+ double utcOffset = calculateUTCOffset();
+ double dstOffset = calculateDSTOffset(current, utcOffset);
+ int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
+ current += offset * msPerMinute;
+
+ DateComponents date;
+ date.setMillisecondsSinceMidnight(current);
+ double milliseconds = date.millisecondsSinceEpoch();
+ ASSERT(isfinite(milliseconds));
+ return milliseconds;
+}
+
+double TimeInputType::minimum() const
+{
+ return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumTime());
+}
+
+double TimeInputType::maximum() const
+{
+ return parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumTime());
+}
+
+double TimeInputType::defaultStep() const
+{
+ return timeDefaultStep;
+}
+
+double TimeInputType::stepScaleFactor() const
+{
+ return timeStepScaleFactor;
+}
+
+bool TimeInputType::scaledStepValueShouldBeInteger() const
+{
+ return true;
+}
+
+bool TimeInputType::parseToDateComponentsInternal(const UChar* characters, unsigned length, DateComponents* out) const
+{
+ ASSERT(out);
+ unsigned end;
+ return out->parseTime(characters, length, 0, end) && end == length;
+}
+
+bool TimeInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+{
+ ASSERT(date);
+ return date->setMillisecondsSinceMidnight(value);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/TimeInputType.h b/Source/WebCore/html/TimeInputType.h
new file mode 100644
index 0000000..3e68fad
--- /dev/null
+++ b/Source/WebCore/html/TimeInputType.h
@@ -0,0 +1,57 @@
+/*
+ * 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:
+ *
+ * * 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 TimeInputType_h
+#define TimeInputType_h
+
+#include "BaseDateAndTimeInputType.h"
+
+namespace WebCore {
+
+class TimeInputType : public BaseDateAndTimeInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ TimeInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual double defaultValueForStepUp() const;
+ virtual double minimum() const;
+ virtual double maximum() const;
+ virtual double defaultStep() const;
+ virtual double stepScaleFactor() const;
+ virtual bool scaledStepValueShouldBeInteger() const;
+ virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const;
+ virtual bool setMillisecondToDateComponents(double, DateComponents*) const;
+};
+
+} // namespace WebCore
+
+#endif // TimeInputType_h
diff --git a/Source/WebCore/html/TimeRanges.cpp b/Source/WebCore/html/TimeRanges.cpp
new file mode 100644
index 0000000..1e18306
--- /dev/null
+++ b/Source/WebCore/html/TimeRanges.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2007, 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,
+ * 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 "TimeRanges.h"
+
+#include <math.h>
+
+using namespace WebCore;
+
+TimeRanges::TimeRanges(float start, float end)
+{
+ add(start, end);
+}
+
+PassRefPtr<TimeRanges> TimeRanges::copy()
+{
+ 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();
+}
+
+float TimeRanges::start(unsigned index, ExceptionCode& ec) const
+{
+ if (index >= length()) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+ return m_ranges[index].m_start;
+}
+
+float TimeRanges::end(unsigned index, ExceptionCode& ec) const
+{
+ if (index >= length()) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+ return m_ranges[index].m_end;
+}
+
+void TimeRanges::add(float start, float 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;
+ }
+ }
+ }
+ }
+
+ // Now that we are sure we don't overlap with any range, just add it.
+ m_ranges.insert(overlappingArcIndex, addedRange);
+}
+
+bool TimeRanges::contain(float time) const
+{
+ ExceptionCode unused;
+ for (unsigned n = 0; n < length(); n++) {
+ if (time >= start(n, unused) && time <= end(n, unused))
+ return true;
+ }
+ return false;
+}
+
+float TimeRanges::nearest(float time) const
+{
+ ExceptionCode unused;
+ float closest = 0;
+ unsigned count = length();
+ for (unsigned ndx = 0; ndx < count; ndx++) {
+ float startTime = start(ndx, unused);
+ float endTime = end(ndx, unused);
+ if (time >= startTime && time <= endTime)
+ return time;
+ if (fabs(startTime - time) < closest)
+ closest = fabsf(startTime - time);
+ else if (fabs(endTime - time) < closest)
+ closest = fabsf(endTime - time);
+ }
+ return closest;
+}
diff --git a/Source/WebCore/html/TimeRanges.h b/Source/WebCore/html/TimeRanges.h
new file mode 100644
index 0000000..2d7af25
--- /dev/null
+++ b/Source/WebCore/html/TimeRanges.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2007, 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,
+ * 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 TimeRanges_h
+#define TimeRanges_h
+
+#include "ExceptionCode.h"
+
+#include <algorithm>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class TimeRanges : public RefCounted<TimeRanges> {
+public:
+ static PassRefPtr<TimeRanges> create()
+ {
+ return adoptRef(new TimeRanges);
+ }
+ static PassRefPtr<TimeRanges> create(float start, float end)
+ {
+ return adoptRef(new TimeRanges(start, end));
+ }
+
+ PassRefPtr<TimeRanges> copy();
+
+ unsigned length() const { return m_ranges.size(); }
+ float start(unsigned index, ExceptionCode&) const;
+ float end(unsigned index, ExceptionCode&) const;
+
+ void add(float start, float end);
+
+ bool contain(float time) const;
+
+ float nearest(float time) const;
+
+private:
+ TimeRanges() { }
+ TimeRanges(float start, float end);
+ TimeRanges(const TimeRanges&);
+
+ // We consider all the Ranges to be semi-bounded as follow: [start, end[
+ struct Range {
+ Range() { }
+ Range(float start, float end)
+ {
+ m_start = start;
+ m_end = end;
+ }
+ float m_start;
+ float m_end;
+
+ inline bool isPointInRange(float 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;
+
+ 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
+
+#endif
diff --git a/Source/WebCore/html/TimeRanges.idl b/Source/WebCore/html/TimeRanges.idl
new file mode 100644
index 0000000..c37c360
--- /dev/null
+++ b/Source/WebCore/html/TimeRanges.idl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007, 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,
+ * 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.
+ */
+
+module html {
+
+ interface [
+ Conditional=VIDEO
+ ] TimeRanges {
+ readonly attribute unsigned long length;
+ float start(in unsigned long index)
+ raises (DOMException);
+ float end(in unsigned long index)
+ raises (DOMException);
+ };
+
+}
diff --git a/Source/WebCore/html/URLInputType.cpp b/Source/WebCore/html/URLInputType.cpp
new file mode 100644
index 0000000..3a913b2
--- /dev/null
+++ b/Source/WebCore/html/URLInputType.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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:
+ *
+ * * 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 "URLInputType.h"
+
+#include "HTMLInputElement.h"
+#include "LocalizedStrings.h"
+#include "KURL.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<InputType> URLInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new URLInputType(element));
+}
+
+const AtomicString& URLInputType::formControlType() const
+{
+ return InputTypeNames::url();
+}
+
+bool URLInputType::typeMismatchFor(const String& value) const
+{
+ return !value.isEmpty() && !KURL(KURL(), value).isValid();
+}
+
+bool URLInputType::typeMismatch() const
+{
+ return typeMismatchFor(element()->value());
+}
+
+String URLInputType::typeMismatchText() const
+{
+ return validationMessageTypeMismatchForURLText();
+}
+
+bool URLInputType::isURLField() const
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/URLInputType.h b/Source/WebCore/html/URLInputType.h
new file mode 100644
index 0000000..fb4bb3d
--- /dev/null
+++ b/Source/WebCore/html/URLInputType.h
@@ -0,0 +1,53 @@
+/*
+ * 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:
+ *
+ * * 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 URLInputType_h
+#define URLInputType_h
+
+#include "BaseTextInputType.h"
+
+namespace WebCore {
+
+class URLInputType : public BaseTextInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ URLInputType(HTMLInputElement* element) : BaseTextInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual bool typeMismatchFor(const String&) const;
+ virtual bool typeMismatch() const;
+ virtual String typeMismatchText() const;
+ virtual bool isURLField() const;
+};
+
+} // namespace WebCore
+
+#endif // URLInputType_h
diff --git a/Source/WebCore/html/ValidationMessage.cpp b/Source/WebCore/html/ValidationMessage.cpp
new file mode 100644
index 0000000..4418235
--- /dev/null
+++ b/Source/WebCore/html/ValidationMessage.cpp
@@ -0,0 +1,70 @@
+/*
+ * 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:
+ *
+ * * 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 "ValidationMessage.h"
+
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+ALWAYS_INLINE ValidationMessage::ValidationMessage(FormAssociatedElement* element)
+ : m_element(element)
+{
+}
+
+ValidationMessage::~ValidationMessage()
+{
+ hideMessage();
+}
+
+PassOwnPtr<ValidationMessage> ValidationMessage::create(FormAssociatedElement* element)
+{
+ return adoptPtr(new ValidationMessage(element));
+}
+
+void ValidationMessage::setMessage(const String& message)
+{
+ // FIXME: Construct validation message UI if m_message is empty.
+
+ m_message = message;
+
+ m_timer.set(new Timer<ValidationMessage>(this, &ValidationMessage::hideMessage));
+ m_timer->startOneShot(6.0); // FIXME: should be <message length> * something.
+}
+
+void ValidationMessage::hideMessage(Timer<ValidationMessage>*)
+{
+ // FIXME: Implement.
+
+ m_message = String();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/ValidationMessage.h b/Source/WebCore/html/ValidationMessage.h
new file mode 100644
index 0000000..d78e3f3
--- /dev/null
+++ b/Source/WebCore/html/ValidationMessage.h
@@ -0,0 +1,61 @@
+/*
+ * 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:
+ *
+ * * 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 ValidationMessage_h
+#define ValidationMessage_h
+
+#include "Timer.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class FormAssociatedElement;
+
+class ValidationMessage : public Noncopyable {
+public:
+ static PassOwnPtr<ValidationMessage> create(FormAssociatedElement*);
+ ~ValidationMessage();
+ String message() const { return m_message; }
+ void setMessage(const String&);
+
+private:
+ ValidationMessage(FormAssociatedElement*);
+ void hideMessage(Timer<ValidationMessage>* = 0);
+
+ FormAssociatedElement* m_element;
+ String m_message;
+ OwnPtr<Timer<ValidationMessage> > m_timer;
+};
+
+} // namespace WebCore
+
+#endif // ValidationMessage_h
diff --git a/Source/WebCore/html/ValidityState.cpp b/Source/WebCore/html/ValidityState.cpp
new file mode 100644
index 0000000..2e65327
--- /dev/null
+++ b/Source/WebCore/html/ValidityState.cpp
@@ -0,0 +1,216 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * Copyright (C) 2009 Michelangelo De Simone <micdesim@gmail.com>
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "ValidityState.h"
+
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "HTMLSelectElement.h"
+#include "HTMLTextAreaElement.h"
+#include "HTMLTreeBuilder.h"
+#include "LocalizedStrings.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+String ValidityState::validationMessage() const
+{
+ if (!toHTMLElement(m_control)->willValidate())
+ return String();
+
+ if (customError())
+ return m_customErrorMessage;
+ HTMLElement* element = toHTMLElement(m_control);
+ bool isInputElement = element->isFormControlElement() && element->hasTagName(inputTag);
+ bool isTextAreaElement = element->isFormControlElement() && element->hasTagName(textareaTag);
+ // The order of the following checks is meaningful. e.g. We'd like to show the
+ // valueMissing message even if the control has other validation errors.
+ if (valueMissing()) {
+ if (element->hasTagName(selectTag))
+ return validationMessageValueMissingForSelectText();
+ if (isInputElement)
+ return static_cast<HTMLInputElement*>(element)->valueMissingText();
+ return validationMessageValueMissingText();
+ }
+ if (typeMismatch()) {
+ if (isInputElement)
+ return static_cast<HTMLInputElement*>(element)->typeMismatchText();
+ return validationMessageTypeMismatchText();
+ }
+ if (patternMismatch())
+ return validationMessagePatternMismatchText();
+ if (tooLong()) {
+ if (!isInputElement && !isTextAreaElement) {
+ ASSERT_NOT_REACHED();
+ return String();
+ }
+ HTMLTextFormControlElement* text = static_cast<HTMLTextFormControlElement*>(element);
+ return validationMessageTooLongText(numGraphemeClusters(text->value()), text->maxLength());
+ }
+ if (rangeUnderflow()) {
+ if (!isInputElement) {
+ ASSERT_NOT_REACHED();
+ return String();
+ }
+ return validationMessageRangeUnderflowText(static_cast<HTMLInputElement*>(element)->minimumString());
+ }
+ if (rangeOverflow()) {
+ if (!isInputElement) {
+ ASSERT_NOT_REACHED();
+ return String();
+ }
+ return validationMessageRangeOverflowText(static_cast<HTMLInputElement*>(element)->maximumString());
+ }
+ if (stepMismatch()) {
+ if (!isInputElement) {
+ ASSERT_NOT_REACHED();
+ return String();
+ }
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(element);
+ return validationMessageStepMismatchText(input->stepBaseString(), input->stepString());
+ }
+
+ return String();
+}
+
+void ValidityState::setCustomErrorMessage(const String& message)
+{
+ m_customErrorMessage = message;
+ if (m_control->isFormControlElement())
+ static_cast<HTMLFormControlElement*>(m_control)->setNeedsValidityCheck();
+}
+
+bool ValidityState::valueMissing() const
+{
+ HTMLElement* element = toHTMLElement(m_control);
+ if (!element->willValidate())
+ return false;
+
+ if (element->hasTagName(inputTag)) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(element);
+ return input->valueMissing(input->value());
+ }
+ if (element->hasTagName(textareaTag)) {
+ HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(element);
+ return textArea->valueMissing(textArea->value());
+ }
+ if (element->hasTagName(selectTag)) {
+ HTMLSelectElement* select = static_cast<HTMLSelectElement*>(element);
+ return select->valueMissing();
+ }
+ return false;
+}
+
+bool ValidityState::typeMismatch() const
+{
+ HTMLElement* element = toHTMLElement(m_control);
+ if (!element->willValidate())
+ return false;
+
+ if (!element->hasTagName(inputTag))
+ return false;
+ return static_cast<HTMLInputElement*>(element)->typeMismatch();
+}
+
+bool ValidityState::patternMismatch() const
+{
+ HTMLElement* element = toHTMLElement(m_control);
+ if (!element->willValidate())
+ return false;
+
+ if (!element->hasTagName(inputTag))
+ return false;
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(element);
+ return input->patternMismatch(input->value());
+}
+
+bool ValidityState::tooLong() const
+{
+ HTMLElement* element = toHTMLElement(m_control);
+ if (!element->willValidate())
+ return false;
+
+ if (element->hasTagName(inputTag)) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(element);
+ return input->tooLong(input->value(), HTMLTextFormControlElement::CheckDirtyFlag);
+ }
+ if (element->hasTagName(textareaTag)) {
+ HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(element);
+ return textArea->tooLong(textArea->value(), HTMLTextFormControlElement::CheckDirtyFlag);
+ }
+ return false;
+}
+
+bool ValidityState::rangeUnderflow() const
+{
+ HTMLElement* element = toHTMLElement(m_control);
+ if (!element->willValidate())
+ return false;
+
+ if (!element->hasTagName(inputTag))
+ return false;
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(element);
+ return input->rangeUnderflow(input->value());
+}
+
+bool ValidityState::rangeOverflow() const
+{
+ HTMLElement* element = toHTMLElement(m_control);
+ if (!element->willValidate())
+ return false;
+
+ if (!element->hasTagName(inputTag))
+ return false;
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(element);
+ return input->rangeOverflow(input->value());
+}
+
+bool ValidityState::stepMismatch() const
+{
+ HTMLElement* element = toHTMLElement(m_control);
+ if (!element->willValidate())
+ return false;
+
+ if (!element->hasTagName(inputTag))
+ return false;
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(element);
+ return input->stepMismatch(input->value());
+}
+
+bool ValidityState::customError() const
+{
+ HTMLElement* element = toHTMLElement(m_control);
+ return element->willValidate() && !m_customErrorMessage.isEmpty();
+}
+
+bool ValidityState::valid() const
+{
+ bool someError = typeMismatch() || stepMismatch() || rangeUnderflow() || rangeOverflow()
+ || tooLong() || patternMismatch() || valueMissing() || customError();
+ return !someError;
+}
+
+} // namespace
diff --git a/Source/WebCore/html/ValidityState.h b/Source/WebCore/html/ValidityState.h
new file mode 100644
index 0000000..e140c49
--- /dev/null
+++ b/Source/WebCore/html/ValidityState.h
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * Copyright (C) 2009 Michelangelo De Simone <micdesim@gmail.com>
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef ValidityState_h
+#define ValidityState_h
+
+#include "FormAssociatedElement.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class ValidityState : public Noncopyable {
+public:
+ static PassOwnPtr<ValidityState> create(FormAssociatedElement* control)
+ {
+ return adoptPtr(new ValidityState(control));
+ }
+
+ void ref() { m_control->ref(); }
+ void deref() { m_control->deref(); }
+
+ String validationMessage() const;
+
+ void setCustomErrorMessage(const String&);
+
+ bool valueMissing() const;
+ bool typeMismatch() const;
+ bool patternMismatch() const;
+ bool tooLong() const;
+ bool rangeUnderflow() const;
+ bool rangeOverflow() const;
+ bool stepMismatch() const;
+ bool customError() const;
+ bool valid() const;
+
+private:
+ ValidityState(FormAssociatedElement* control) : m_control(control) { }
+
+ static bool isValidColorString(const String&);
+ static bool isValidEmailAddress(const String&);
+
+ FormAssociatedElement* m_control;
+ String m_customErrorMessage;
+};
+
+} // namespace WebCore
+
+#endif // ValidityState_h
diff --git a/Source/WebCore/html/ValidityState.idl b/Source/WebCore/html/ValidityState.idl
new file mode 100644
index 0000000..576fab4
--- /dev/null
+++ b/Source/WebCore/html/ValidityState.idl
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * Copyright (C) 2009 Michelangelo De Simone <micdesim@gmail.com>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+module html {
+
+ interface [OmitConstructor] ValidityState {
+ readonly attribute boolean valueMissing;
+ readonly attribute boolean typeMismatch;
+ readonly attribute boolean patternMismatch;
+ readonly attribute boolean tooLong;
+ readonly attribute boolean rangeUnderflow;
+ readonly attribute boolean rangeOverflow;
+ readonly attribute boolean stepMismatch;
+ readonly attribute boolean customError;
+ readonly attribute boolean valid;
+ };
+}
diff --git a/Source/WebCore/html/VoidCallback.h b/Source/WebCore/html/VoidCallback.h
new file mode 100644
index 0000000..c220411
--- /dev/null
+++ b/Source/WebCore/html/VoidCallback.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007 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 VoidCallback_h
+#define VoidCallback_h
+
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class VoidCallback : public RefCounted<VoidCallback> {
+public:
+ virtual ~VoidCallback() { }
+
+ virtual void handleEvent() = 0;
+
+protected:
+ VoidCallback() {}
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/VoidCallback.idl b/Source/WebCore/html/VoidCallback.idl
new file mode 100644
index 0000000..8a7cf19
--- /dev/null
+++ b/Source/WebCore/html/VoidCallback.idl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+module html {
+ interface [CustomNativeConverter, OmitConstructor] VoidCallback {
+ void handleEvent();
+ };
+}
diff --git a/Source/WebCore/html/WeekInputType.cpp b/Source/WebCore/html/WeekInputType.cpp
new file mode 100644
index 0000000..a5836dc
--- /dev/null
+++ b/Source/WebCore/html/WeekInputType.cpp
@@ -0,0 +1,100 @@
+/*
+ * 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:
+ *
+ * * 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 "WeekInputType.h"
+
+#include "DateComponents.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static const double weekDefaultStepBase = -259200000.0; // The first day of 1970-W01.
+static const double weekDefaultStep = 1.0;
+static const double weekStepScaleFactor = 604800000.0;
+
+PassOwnPtr<InputType> WeekInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new WeekInputType(element));
+}
+
+const AtomicString& WeekInputType::formControlType() const
+{
+ return InputTypeNames::week();
+}
+
+double WeekInputType::minimum() const
+{
+ return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumWeek());
+}
+
+double WeekInputType::maximum() const
+{
+ return parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumWeek());
+}
+
+double WeekInputType::stepBase() const
+{
+ return parseToDouble(element()->fastGetAttribute(minAttr), weekDefaultStepBase);
+}
+
+double WeekInputType::defaultStep() const
+{
+ return weekDefaultStep;
+}
+
+double WeekInputType::stepScaleFactor() const
+{
+ return weekStepScaleFactor;
+}
+
+bool WeekInputType::parsedStepValueShouldBeInteger() const
+{
+ return true;
+}
+
+bool WeekInputType::parseToDateComponentsInternal(const UChar* characters, unsigned length, DateComponents* out) const
+{
+ ASSERT(out);
+ unsigned end;
+ return out->parseWeek(characters, length, 0, end) && end == length;
+}
+
+bool WeekInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+{
+ ASSERT(date);
+ return date->setMillisecondsSinceEpochForWeek(value);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/WeekInputType.h b/Source/WebCore/html/WeekInputType.h
new file mode 100644
index 0000000..437164b
--- /dev/null
+++ b/Source/WebCore/html/WeekInputType.h
@@ -0,0 +1,57 @@
+/*
+ * 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:
+ *
+ * * 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 WeekInputType_h
+#define WeekInputType_h
+
+#include "BaseDateAndTimeInputType.h"
+
+namespace WebCore {
+
+class WeekInputType : public BaseDateAndTimeInputType {
+public:
+ static PassOwnPtr<InputType> create(HTMLInputElement*);
+
+private:
+ WeekInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { }
+ virtual const AtomicString& formControlType() const;
+ virtual double minimum() const;
+ virtual double maximum() const;
+ virtual double stepBase() const;
+ virtual double defaultStep() const;
+ virtual double stepScaleFactor() const;
+ virtual bool parsedStepValueShouldBeInteger() const;
+ virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const;
+ virtual bool setMillisecondToDateComponents(double, DateComponents*) const;
+};
+
+} // namespace WebCore
+
+#endif // WeekInputType_h
diff --git a/Source/WebCore/html/canvas/ArrayBuffer.cpp b/Source/WebCore/html/canvas/ArrayBuffer.cpp
new file mode 100644
index 0000000..2136f64
--- /dev/null
+++ b/Source/WebCore/html/canvas/ArrayBuffer.cpp
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ * 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(3D_CANVAS) || ENABLE(BLOB)
+
+#include "ArrayBuffer.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+PassRefPtr<ArrayBuffer> ArrayBuffer::create(unsigned numElements, unsigned elementByteSize)
+{
+ void* data = tryAllocate(numElements, elementByteSize);
+ if (!data)
+ return 0;
+ return adoptRef(new ArrayBuffer(data, numElements * elementByteSize));
+}
+
+PassRefPtr<ArrayBuffer> ArrayBuffer::create(ArrayBuffer* other)
+{
+ return ArrayBuffer::create(other->data(), other->byteLength());
+}
+
+PassRefPtr<ArrayBuffer> ArrayBuffer::create(void* source, unsigned byteLength)
+{
+ void* data = tryAllocate(byteLength, 1);
+ if (!data)
+ return 0;
+ RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(data, byteLength));
+ memcpy(buffer->data(), source, byteLength);
+ return buffer.release();
+}
+
+ArrayBuffer::ArrayBuffer(void* data, unsigned sizeInBytes)
+ : m_sizeInBytes(sizeInBytes)
+ , m_data(data)
+{
+}
+
+void* ArrayBuffer::data()
+{
+ return m_data;
+}
+
+const void* ArrayBuffer::data() const
+{
+ return m_data;
+}
+
+unsigned ArrayBuffer::byteLength() const
+{
+ return m_sizeInBytes;
+}
+
+ArrayBuffer::~ArrayBuffer()
+{
+ WTF::fastFree(m_data);
+}
+
+void* ArrayBuffer::tryAllocate(unsigned numElements, unsigned elementByteSize)
+{
+ void* result;
+ // Do not allow 32-bit overflow of the total size.
+ // FIXME: Why not? The tryFastCalloc function already checks its arguments,
+ // and will fail if there is any overflow, so why should we include a
+ // redudant unnecessarily restrictive check here?
+ if (numElements) {
+ unsigned totalSize = numElements * elementByteSize;
+ if (totalSize / numElements != elementByteSize)
+ return 0;
+ }
+ if (WTF::tryFastCalloc(numElements, elementByteSize).getValue(result))
+ return result;
+ return 0;
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB)
diff --git a/Source/WebCore/html/canvas/ArrayBuffer.h b/Source/WebCore/html/canvas/ArrayBuffer.h
new file mode 100644
index 0000000..ff5e599
--- /dev/null
+++ b/Source/WebCore/html/canvas/ArrayBuffer.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ * 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 ArrayBuffer_h
+#define ArrayBuffer_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class ArrayBuffer : public RefCounted<ArrayBuffer> {
+ public:
+ static PassRefPtr<ArrayBuffer> create(unsigned numElements, unsigned elementByteSize);
+ static PassRefPtr<ArrayBuffer> create(ArrayBuffer*);
+ static PassRefPtr<ArrayBuffer> create(void* source, unsigned byteLength);
+
+ void* data();
+ const void* data() const;
+ unsigned byteLength() const;
+
+ ~ArrayBuffer();
+
+ private:
+ ArrayBuffer(void* data, unsigned sizeInBytes);
+ ArrayBuffer(unsigned numElements, unsigned elementByteSize);
+ static void* tryAllocate(unsigned numElements, unsigned elementByteSize);
+ unsigned m_sizeInBytes;
+ void* m_data;
+};
+
+} // namespace WebCore
+
+#endif // ArrayBuffer_h
diff --git a/Source/WebCore/html/canvas/ArrayBuffer.idl b/Source/WebCore/html/canvas/ArrayBuffer.idl
new file mode 100644
index 0000000..79a4685
--- /dev/null
+++ b/Source/WebCore/html/canvas/ArrayBuffer.idl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 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,
+ * 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.
+ */
+
+module html {
+
+ interface [
+ Conditional=3D_CANVAS|BLOB,
+ CanBeConstructed,
+ CustomConstructFunction,
+ NoStaticTables,
+ V8CustomConstructor,
+ ] ArrayBuffer {
+ readonly attribute int byteLength;
+ };
+
+}
diff --git a/Source/WebCore/html/canvas/ArrayBufferView.cpp b/Source/WebCore/html/canvas/ArrayBufferView.cpp
new file mode 100644
index 0000000..7f41bda
--- /dev/null
+++ b/Source/WebCore/html/canvas/ArrayBufferView.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ * 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(3D_CANVAS) || ENABLE(BLOB)
+
+#include "ArrayBufferView.h"
+
+#include "ArrayBuffer.h"
+
+namespace WebCore {
+
+ArrayBufferView::ArrayBufferView(PassRefPtr<ArrayBuffer> buffer,
+ unsigned byteOffset)
+ : m_byteOffset(byteOffset)
+ , m_buffer(buffer)
+{
+ m_baseAddress = m_buffer ? (static_cast<char*>(m_buffer->data()) + m_byteOffset) : 0;
+}
+
+ArrayBufferView::~ArrayBufferView()
+{
+}
+
+void ArrayBufferView::setImpl(ArrayBufferView* array, unsigned byteOffset, ExceptionCode& ec)
+{
+ if (byteOffset > byteLength()
+ || byteOffset + array->byteLength() > byteLength()
+ || byteOffset + array->byteLength() < byteOffset) {
+ // Out of range offset or overflow
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ char* base = static_cast<char*>(baseAddress());
+ memmove(base + byteOffset, array->baseAddress(), array->byteLength());
+}
+
+void ArrayBufferView::setRangeImpl(const char* data, size_t dataByteLength, unsigned byteOffset, ExceptionCode& ec)
+{
+ if (byteOffset > byteLength()
+ || byteOffset + dataByteLength > byteLength()
+ || byteOffset + dataByteLength < byteOffset) {
+ // Out of range offset or overflow
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ char* base = static_cast<char*>(baseAddress());
+ memmove(base + byteOffset, data, dataByteLength);
+}
+
+void ArrayBufferView::zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength, ExceptionCode& ec)
+{
+ if (byteOffset > byteLength()
+ || byteOffset + rangeByteLength > byteLength()
+ || byteOffset + rangeByteLength < byteOffset) {
+ // Out of range offset or overflow
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ char* base = static_cast<char*>(baseAddress());
+ memset(base + byteOffset, 0, rangeByteLength);
+}
+
+void ArrayBufferView::calculateOffsetAndLength(int start, int end, unsigned arraySize,
+ unsigned* offset, unsigned* length)
+{
+ if (start < 0)
+ start += arraySize;
+ if (start < 0)
+ start = 0;
+ if (end < 0)
+ end += arraySize;
+ if (end < 0)
+ end = 0;
+ if (end < start)
+ end = start;
+ *offset = static_cast<unsigned>(start);
+ *length = static_cast<unsigned>(end - start);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB)
diff --git a/Source/WebCore/html/canvas/ArrayBufferView.h b/Source/WebCore/html/canvas/ArrayBufferView.h
new file mode 100644
index 0000000..701abbc
--- /dev/null
+++ b/Source/WebCore/html/canvas/ArrayBufferView.h
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ * 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 ArrayBufferView_h
+#define ArrayBufferView_h
+
+#include "ArrayBuffer.h"
+#include "ExceptionCode.h"
+
+#include <algorithm>
+#include <limits.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class ArrayBufferView : public RefCounted<ArrayBufferView> {
+ public:
+ virtual bool isByteArray() const { return false; }
+ virtual bool isUnsignedByteArray() const { return false; }
+ virtual bool isShortArray() const { return false; }
+ virtual bool isUnsignedShortArray() const { return false; }
+ virtual bool isIntArray() const { return false; }
+ virtual bool isUnsignedIntArray() const { return false; }
+ virtual bool isFloatArray() const { return false; }
+ virtual bool isDataView() const { return false; }
+
+ PassRefPtr<ArrayBuffer> buffer() const
+ {
+ return m_buffer;
+ }
+
+ void* baseAddress() const
+ {
+ return m_baseAddress;
+ }
+
+ unsigned byteOffset() const
+ {
+ return m_byteOffset;
+ }
+
+ virtual unsigned byteLength() const = 0;
+
+ virtual ~ArrayBufferView();
+
+ protected:
+ ArrayBufferView(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset);
+
+ void setImpl(ArrayBufferView* array, unsigned byteOffset, ExceptionCode& ec);
+
+ void setRangeImpl(const char* data, size_t dataByteLength, unsigned byteOffset, ExceptionCode& ec);
+
+ void zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength, ExceptionCode& ec);
+
+ static void calculateOffsetAndLength(int start, int end, unsigned arraySize,
+ unsigned* offset, unsigned* length);
+
+ // Helper to verify that a given sub-range of an ArrayBuffer is
+ // within range.
+ template <typename T>
+ static bool verifySubRange(PassRefPtr<ArrayBuffer> buffer,
+ unsigned byteOffset,
+ unsigned numElements)
+ {
+ if (!buffer)
+ return false;
+ if (sizeof(T) > 1 && byteOffset % sizeof(T))
+ return false;
+ if (byteOffset > buffer->byteLength())
+ return false;
+ unsigned remainingElements = (buffer->byteLength() - byteOffset) / sizeof(T);
+ if (numElements > remainingElements)
+ return false;
+ return true;
+ }
+
+ // Input offset is in number of elements from this array's view;
+ // output offset is in number of bytes from the underlying buffer's view.
+ template <typename T>
+ static void clampOffsetAndNumElements(PassRefPtr<ArrayBuffer> buffer,
+ unsigned arrayByteOffset,
+ unsigned *offset,
+ unsigned *numElements)
+ {
+ unsigned maxOffset = (UINT_MAX - arrayByteOffset) / sizeof(T);
+ if (*offset > maxOffset) {
+ *offset = buffer->byteLength();
+ *numElements = 0;
+ return;
+ }
+ *offset = arrayByteOffset + *offset * sizeof(T);
+ *offset = std::min(buffer->byteLength(), *offset);
+ unsigned remainingElements = (buffer->byteLength() - *offset) / sizeof(T);
+ *numElements = std::min(remainingElements, *numElements);
+ }
+
+ // This is the address of the ArrayBuffer's storage, plus the byte offset.
+ void* m_baseAddress;
+
+ unsigned m_byteOffset;
+
+ private:
+ RefPtr<ArrayBuffer> m_buffer;
+};
+
+} // namespace WebCore
+
+#endif // ArrayBufferView_h
diff --git a/Source/WebCore/html/canvas/ArrayBufferView.idl b/Source/WebCore/html/canvas/ArrayBufferView.idl
new file mode 100644
index 0000000..be217c1
--- /dev/null
+++ b/Source/WebCore/html/canvas/ArrayBufferView.idl
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ * 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.
+ */
+
+module html {
+ interface [Conditional=3D_CANVAS|BLOB, CustomToJS, NoStaticTables, OmitConstructor] ArrayBufferView {
+ readonly attribute ArrayBuffer buffer;
+ readonly attribute unsigned long byteOffset;
+ readonly attribute unsigned long byteLength;
+ };
+}
diff --git a/Source/WebCore/html/canvas/CanvasContextAttributes.cpp b/Source/WebCore/html/canvas/CanvasContextAttributes.cpp
new file mode 100644
index 0000000..d3d0398
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasContextAttributes.cpp
@@ -0,0 +1,41 @@
+/*
+ * 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:
+ * * 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.
+ *
+ * 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 "CanvasContextAttributes.h"
+
+namespace WebCore {
+
+CanvasContextAttributes::CanvasContextAttributes()
+{
+}
+
+CanvasContextAttributes::~CanvasContextAttributes()
+{
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasContextAttributes.h b/Source/WebCore/html/canvas/CanvasContextAttributes.h
new file mode 100644
index 0000000..97483b3
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasContextAttributes.h
@@ -0,0 +1,48 @@
+/*
+ * 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:
+ * * 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.
+ *
+ * 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 CanvasContextAttributes_h
+#define CanvasContextAttributes_h
+
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+// A base class for any attributes that are needed which would affect
+// the creation of the Canvas's rendering context. Currently only the
+// WebGLRenderingContext uses this mechanism.
+
+class CanvasContextAttributes : public RefCounted<CanvasContextAttributes> {
+ public:
+ virtual ~CanvasContextAttributes();
+
+ protected:
+ CanvasContextAttributes();
+};
+
+} // namespace WebCore
+
+#endif // CanvasContextAttributes_h
diff --git a/Source/WebCore/html/canvas/CanvasGradient.cpp b/Source/WebCore/html/canvas/CanvasGradient.cpp
new file mode 100644
index 0000000..7c98a82
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasGradient.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Alp Toker <alp@atoker.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 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"
+#include "CanvasGradient.h"
+
+#include "CanvasPattern.h"
+#include "CanvasStyle.h"
+#include "CSSParser.h"
+#include "ExceptionCode.h"
+
+namespace WebCore {
+
+CanvasGradient::CanvasGradient(const FloatPoint& p0, const FloatPoint& p1)
+ : m_gradient(Gradient::create(p0, p1))
+ , m_dashbardCompatibilityMode(false)
+{
+}
+
+CanvasGradient::CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1)
+ : m_gradient(Gradient::create(p0, r0, p1, r1))
+ , m_dashbardCompatibilityMode(false)
+{
+}
+
+void CanvasGradient::addColorStop(float value, const String& color, ExceptionCode& ec)
+{
+ if (!(value >= 0 && value <= 1.0f)) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ RGBA32 rgba = 0;
+ if (!parseColorOrCurrentColor(rgba, color, 0 /*canvas*/)) {
+ if (!m_dashbardCompatibilityMode)
+ ec = SYNTAX_ERR;
+ return;
+ }
+
+ m_gradient->addColorStop(value, Color(rgba));
+}
+
+} // namespace
diff --git a/Source/WebCore/html/canvas/CanvasGradient.h b/Source/WebCore/html/canvas/CanvasGradient.h
new file mode 100644
index 0000000..7550f9b
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasGradient.h
@@ -0,0 +1,70 @@
+/*
+ * 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
+ * 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 CanvasGradient_h
+#define CanvasGradient_h
+
+#include "Gradient.h"
+#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ typedef int ExceptionCode;
+
+ class CanvasGradient : public RefCounted<CanvasGradient> {
+ public:
+ static PassRefPtr<CanvasGradient> create(const FloatPoint& p0, const FloatPoint& p1)
+ {
+ return adoptRef(new CanvasGradient(p0, p1));
+ }
+ static PassRefPtr<CanvasGradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1)
+ {
+ return adoptRef(new CanvasGradient(p0, r0, p1, r1));
+ }
+
+ Gradient* gradient() const { return m_gradient.get(); }
+
+ void addColorStop(float value, const String& color, ExceptionCode&);
+
+ void getColor(float value, float* r, float* g, float* b, float* a) const { m_gradient->getColor(value, r, g, b, a); }
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ void setDashboardCompatibilityMode() { m_dashbardCompatibilityMode = true; }
+#endif
+
+ private:
+ CanvasGradient(const FloatPoint& p0, const FloatPoint& p1);
+ CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1);
+
+ RefPtr<Gradient> m_gradient;
+ bool m_dashbardCompatibilityMode;
+ };
+
+} //namespace
+
+#endif
diff --git a/Source/WebCore/html/canvas/CanvasGradient.idl b/Source/WebCore/html/canvas/CanvasGradient.idl
new file mode 100644
index 0000000..a925a26
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasGradient.idl
@@ -0,0 +1,39 @@
+/*
+ * 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
+ * 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.
+ */
+
+module html {
+
+ interface [
+ InterfaceUUID=bb1108ea-6b8c-4a08-894a-218628630cdb,
+ ImplementationUUID=a2942ae6-2731-4286-98cc-9d5e79e20de1
+ ] CanvasGradient {
+
+ void addColorStop(in float offset, in DOMString color)
+ raises (DOMException);
+
+ };
+
+}
+
diff --git a/Source/WebCore/html/canvas/CanvasPattern.cpp b/Source/WebCore/html/canvas/CanvasPattern.cpp
new file mode 100644
index 0000000..818d7d3
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPattern.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006, 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
+ * 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"
+#include "CanvasPattern.h"
+
+#include "ExceptionCode.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+void CanvasPattern::parseRepetitionType(const String& type, bool& repeatX, bool& repeatY, ExceptionCode& ec)
+{
+ ec = 0;
+ if (type.isEmpty() || type == "repeat") {
+ repeatX = true;
+ repeatY = true;
+ return;
+ }
+ if (type == "no-repeat") {
+ repeatX = false;
+ repeatY = false;
+ return;
+ }
+ if (type == "repeat-x") {
+ repeatX = true;
+ repeatY = false;
+ return;
+ }
+ if (type == "repeat-y") {
+ repeatX = false;
+ repeatY = true;
+ return;
+ }
+ ec = SYNTAX_ERR;
+}
+
+CanvasPattern::CanvasPattern(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
+ : m_pattern(Pattern::create(image, repeatX, repeatY))
+ , m_originClean(originClean)
+{
+}
+
+}
diff --git a/Source/WebCore/html/canvas/CanvasPattern.h b/Source/WebCore/html/canvas/CanvasPattern.h
new file mode 100644
index 0000000..58848a9
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPattern.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2006, 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
+ * 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 CanvasPattern_h
+#define CanvasPattern_h
+
+#include "Pattern.h"
+#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class Image;
+
+ typedef int ExceptionCode;
+
+ class CanvasPattern : public RefCounted<CanvasPattern> {
+ public:
+ static void parseRepetitionType(const String&, bool& repeatX, bool& repeatY, ExceptionCode&);
+
+ static PassRefPtr<CanvasPattern> create(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
+ {
+ return adoptRef(new CanvasPattern(image, repeatX, repeatY, originClean));
+ }
+
+ Pattern* pattern() const { return m_pattern.get(); }
+
+ bool originClean() const { return m_originClean; }
+
+ private:
+ CanvasPattern(PassRefPtr<Image>, bool repeatX, bool repeatY, bool originClean);
+
+ RefPtr<Pattern> m_pattern;
+ bool m_originClean;
+ };
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/canvas/CanvasPattern.idl b/Source/WebCore/html/canvas/CanvasPattern.idl
new file mode 100644
index 0000000..1cac8f8
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPattern.idl
@@ -0,0 +1,36 @@
+/*
+ * 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
+ * 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.
+ */
+
+module html {
+
+ interface [
+ InterfaceUUID=c2131348-6d8c-47b5-86cc-d41aff34ce15,
+ ImplementationUUID=82f5d713-3d17-44dd-aa4a-7766fe345940
+ ] CanvasPattern {
+
+ };
+
+}
+
diff --git a/Source/WebCore/html/canvas/CanvasPixelArray.cpp b/Source/WebCore/html/canvas/CanvasPixelArray.cpp
new file mode 100644
index 0000000..65ac7ec
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPixelArray.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 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.
+ * 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.
+ *
+ * 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"
+#include "CanvasPixelArray.h"
+
+namespace WebCore {
+
+PassRefPtr<CanvasPixelArray> CanvasPixelArray::create(unsigned length)
+{
+ return adoptRef(new CanvasPixelArray(length));
+}
+
+PassRefPtr<CanvasPixelArray> CanvasPixelArray::create(PassRefPtr<ByteArray> byteArray)
+{
+ return adoptRef(new CanvasPixelArray(byteArray));
+}
+
+CanvasPixelArray::CanvasPixelArray(unsigned length)
+ : m_data(ByteArray::create(length))
+{
+}
+
+CanvasPixelArray::CanvasPixelArray(PassRefPtr<ByteArray> byteArray)
+ : m_data(byteArray)
+{
+}
+
+}
diff --git a/Source/WebCore/html/canvas/CanvasPixelArray.h b/Source/WebCore/html/canvas/CanvasPixelArray.h
new file mode 100644
index 0000000..7a94b1f
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPixelArray.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 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.
+ * 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.
+ *
+ * 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 CanvasPixelArray_h
+#define CanvasPixelArray_h
+
+#include <wtf/ByteArray.h>
+#include <wtf/MathExtras.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class CanvasPixelArray : public RefCounted<CanvasPixelArray> {
+public:
+ static PassRefPtr<CanvasPixelArray> create(unsigned length);
+ static PassRefPtr<CanvasPixelArray> create(PassRefPtr<ByteArray>);
+
+ ByteArray* data() { return m_data.get(); }
+ const ByteArray* data() const { return m_data.get(); }
+ unsigned length() const { return m_data->length(); }
+
+ void set(unsigned index, double value)
+ {
+ m_data->set(index, value);
+ }
+
+ void set(unsigned index, unsigned char value)
+ {
+ m_data->set(index, value);
+ }
+
+ bool get(unsigned index, unsigned char& result) const
+ {
+ return m_data->get(index, result);
+ }
+
+ unsigned char get(unsigned index) const
+ {
+ return m_data->get(index);
+ }
+
+private:
+ CanvasPixelArray(unsigned length);
+ CanvasPixelArray(PassRefPtr<ByteArray>);
+
+ RefPtr<ByteArray> m_data;
+};
+
+} // namespace WebCore
+
+#endif // CanvasPixelArray_h
diff --git a/Source/WebCore/html/canvas/CanvasPixelArray.idl b/Source/WebCore/html/canvas/CanvasPixelArray.idl
new file mode 100644
index 0000000..8b7edbd
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasPixelArray.idl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 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.
+ * 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.
+ *
+ * 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.
+ */
+
+module html {
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT || defined(V8_BINDING) && V8_BINDING
+ interface [
+ OmitConstructor,
+ CustomHeader,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter
+ ] CanvasPixelArray {
+#if !defined(V8_BINDING) || !V8_BINDING
+ readonly attribute long length;
+#endif
+ };
+#endif
+}
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
new file mode 100644
index 0000000..c814c66
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ * 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"
+#include "CanvasRenderingContext.h"
+
+#include "CachedImage.h"
+#include "CanvasPattern.h"
+#include "HTMLCanvasElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLVideoElement.h"
+#include "KURL.h"
+#include "SecurityOrigin.h"
+
+namespace WebCore {
+
+CanvasRenderingContext::CanvasRenderingContext(HTMLCanvasElement* canvas)
+ : m_canvas(canvas)
+{
+}
+
+void CanvasRenderingContext::ref()
+{
+ m_canvas->ref();
+}
+
+void CanvasRenderingContext::deref()
+{
+ m_canvas->deref();
+}
+
+void CanvasRenderingContext::checkOrigin(const CanvasPattern* pattern)
+{
+ if (canvas()->originClean() && pattern && !pattern->originClean())
+ canvas()->setOriginTainted();
+}
+
+void CanvasRenderingContext::checkOrigin(const HTMLCanvasElement* sourceCanvas)
+{
+ if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean())
+ canvas()->setOriginTainted();
+}
+
+void CanvasRenderingContext::checkOrigin(const HTMLImageElement* image)
+{
+ if (!image || !canvas()->originClean())
+ return;
+
+ CachedImage* cachedImage = image->cachedImage();
+ checkOrigin(cachedImage->response().url());
+
+ if (canvas()->originClean() && !cachedImage->image()->hasSingleSecurityOrigin())
+ canvas()->setOriginTainted();
+}
+
+void CanvasRenderingContext::checkOrigin(const HTMLVideoElement* video)
+{
+#if ENABLE(VIDEO)
+ checkOrigin(KURL(KURL(), video->currentSrc()));
+ if (canvas()->originClean() && video && !video->hasSingleSecurityOrigin())
+ canvas()->setOriginTainted();
+#endif
+}
+
+void CanvasRenderingContext::checkOrigin(const KURL& url)
+{
+ if (!canvas()->originClean() || m_cleanOrigins.contains(url.string()))
+ return;
+
+ if (canvas()->securityOrigin().taintsCanvas(url))
+ canvas()->setOriginTainted();
+ else
+ m_cleanOrigins.add(url.string());
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.h b/Source/WebCore/html/canvas/CanvasRenderingContext.h
new file mode 100644
index 0000000..a25e8a1
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.h
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ * 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 CanvasRenderingContext_h
+#define CanvasRenderingContext_h
+
+#include "GraphicsLayer.h"
+
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+class CanvasPattern;
+class HTMLCanvasElement;
+class HTMLImageElement;
+class HTMLVideoElement;
+class KURL;
+class WebGLObject;
+
+class CanvasRenderingContext : public Noncopyable {
+public:
+ CanvasRenderingContext(HTMLCanvasElement*);
+ virtual ~CanvasRenderingContext() { }
+
+ // Ref and deref the m_canvas
+ void ref();
+ void deref();
+
+ HTMLCanvasElement* canvas() const { return m_canvas; }
+
+ virtual bool is2d() const { return false; }
+ virtual bool is3d() const { return false; }
+ virtual bool isAccelerated() const { return false; }
+
+ virtual void paintRenderingResultsToCanvas() {}
+ virtual bool paintsIntoCanvasBuffer() const { return true; }
+
+#if USE(ACCELERATED_COMPOSITING)
+ virtual PlatformLayer* platformLayer() const { return 0; }
+#endif
+
+protected:
+ void checkOrigin(const CanvasPattern*);
+ void checkOrigin(const HTMLCanvasElement*);
+ void checkOrigin(const HTMLImageElement*);
+ void checkOrigin(const HTMLVideoElement*);
+ void checkOrigin(const KURL&);
+
+private:
+ HTMLCanvasElement* m_canvas;
+ HashSet<String> m_cleanOrigins;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.idl b/Source/WebCore/html/canvas/CanvasRenderingContext.idl
new file mode 100644
index 0000000..a11aa75
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.idl
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ * 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.
+ */
+
+module html {
+
+ interface [
+ CustomToJS,
+ InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443,
+ ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54
+ ] CanvasRenderingContext {
+
+ readonly attribute HTMLCanvasElement canvas;
+ };
+
+}
+
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
new file mode 100644
index 0000000..62c5793
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -0,0 +1,1902 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2008 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. 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"
+#include "CanvasRenderingContext2D.h"
+
+#include "AffineTransform.h"
+#include "CSSMutableStyleDeclaration.h"
+#include "CSSParser.h"
+#include "CSSPropertyNames.h"
+#include "CSSStyleSelector.h"
+#include "CachedImage.h"
+#include "CanvasGradient.h"
+#include "CanvasPattern.h"
+#include "CanvasStyle.h"
+#include "ExceptionCode.h"
+#include "FloatConversion.h"
+#include "GraphicsContext.h"
+#include "HTMLCanvasElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLMediaElement.h"
+#include "HTMLNames.h"
+#include "HTMLVideoElement.h"
+#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "KURL.h"
+#include "Page.h"
+#include "RenderHTMLCanvas.h"
+#include "SecurityOrigin.h"
+#include "Settings.h"
+#include "StrokeStyleApplier.h"
+#include "TextMetrics.h"
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "DrawingBuffer.h"
+#include "FrameView.h"
+#include "GraphicsContext3D.h"
+#include "SharedGraphicsContext3D.h"
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayer.h"
+#endif
+#endif
+
+#include <wtf/ByteArray.h>
+#include <wtf/MathExtras.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/UnusedParam.h>
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static const char* const defaultFont = "10px sans-serif";
+
+
+class CanvasStrokeStyleApplier : public StrokeStyleApplier {
+public:
+ CanvasStrokeStyleApplier(CanvasRenderingContext2D* canvasContext)
+ : m_canvasContext(canvasContext)
+ {
+ }
+
+ virtual void strokeStyle(GraphicsContext* c)
+ {
+ c->setStrokeThickness(m_canvasContext->lineWidth());
+ c->setLineCap(m_canvasContext->getLineCap());
+ c->setLineJoin(m_canvasContext->getLineJoin());
+ c->setMiterLimit(m_canvasContext->miterLimit());
+ }
+
+private:
+ CanvasRenderingContext2D* m_canvasContext;
+};
+
+CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode)
+ : CanvasRenderingContext(canvas)
+ , m_stateStack(1)
+ , m_usesCSSCompatibilityParseMode(usesCSSCompatibilityParseMode)
+#if ENABLE(DASHBOARD_SUPPORT)
+ , m_usesDashboardCompatibilityMode(usesDashboardCompatibilityMode)
+#endif
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ , m_context3D(0)
+#endif
+{
+#if !ENABLE(DASHBOARD_SUPPORT)
+ ASSERT_UNUSED(usesDashboardCompatibilityMode, !usesDashboardCompatibilityMode);
+#endif
+
+ // Make sure that even if the drawingContext() has a different default
+ // thickness, it is in sync with the canvas thickness.
+ setLineWidth(lineWidth());
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ Page* p = canvas->document()->page();
+ if (!p)
+ return;
+ if (!p->settings()->accelerated2dCanvasEnabled())
+ return;
+ if (GraphicsContext* c = drawingContext()) {
+ m_context3D = p->sharedGraphicsContext3D();
+ if (m_context3D) {
+ m_drawingBuffer = m_context3D->graphicsContext3D()->createDrawingBuffer(IntSize(canvas->width(), canvas->height()));
+ c->setSharedGraphicsContext3D(m_context3D.get(), m_drawingBuffer.get(), IntSize(canvas->width(), canvas->height()));
+ }
+ }
+#endif
+}
+
+CanvasRenderingContext2D::~CanvasRenderingContext2D()
+{
+}
+
+bool CanvasRenderingContext2D::isAccelerated() const
+{
+#if USE(IOSURFACE_CANVAS_BACKING_STORE)
+ return true;
+#elif ENABLE(ACCELERATED_2D_CANVAS)
+ return m_context3D;
+#else
+ return false;
+#endif
+}
+
+bool CanvasRenderingContext2D::paintsIntoCanvasBuffer() const
+{
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ if (m_context3D)
+ return m_context3D->paintsIntoCanvasBuffer();
+#endif
+ return true;
+}
+
+
+void CanvasRenderingContext2D::reset()
+{
+ m_stateStack.resize(1);
+ m_stateStack.first() = State();
+ m_path.clear();
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ if (GraphicsContext* c = drawingContext()) {
+ if (m_context3D) {
+ m_drawingBuffer->reset(IntSize(canvas()->width(), canvas()->height()));
+ c->setSharedGraphicsContext3D(m_context3D.get(), m_drawingBuffer.get(), IntSize(canvas()->width(), canvas()->height()));
+ }
+ }
+#endif
+}
+
+CanvasRenderingContext2D::State::State()
+ : m_strokeStyle(CanvasStyle::createFromRGBA(Color::black))
+ , m_fillStyle(CanvasStyle::createFromRGBA(Color::black))
+ , m_lineWidth(1)
+ , m_lineCap(ButtCap)
+ , m_lineJoin(MiterJoin)
+ , m_miterLimit(10)
+ , m_shadowBlur(0)
+ , m_shadowColor(Color::transparent)
+ , m_globalAlpha(1)
+ , m_globalComposite(CompositeSourceOver)
+ , m_invertibleCTM(true)
+ , m_textAlign(StartTextAlign)
+ , m_textBaseline(AlphabeticTextBaseline)
+ , m_unparsedFont(defaultFont)
+ , m_realizedFont(false)
+{
+}
+
+void CanvasRenderingContext2D::save()
+{
+ ASSERT(m_stateStack.size() >= 1);
+ m_stateStack.append(state());
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->save();
+}
+
+void CanvasRenderingContext2D::restore()
+{
+ ASSERT(m_stateStack.size() >= 1);
+ if (m_stateStack.size() <= 1)
+ return;
+ m_path.transform(state().m_transform);
+ m_stateStack.removeLast();
+ m_path.transform(state().m_transform.inverse());
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->restore();
+}
+
+void CanvasRenderingContext2D::setAllAttributesToDefault()
+{
+ state().m_globalAlpha = 1;
+ state().m_shadowOffset = FloatSize();
+ state().m_shadowBlur = 0;
+ state().m_shadowColor = Color::transparent;
+ state().m_globalComposite = CompositeSourceOver;
+
+ GraphicsContext* context = drawingContext();
+ if (!context)
+ return;
+
+ context->setShadow(FloatSize(), 0, Color::transparent, ColorSpaceDeviceRGB);
+ context->setAlpha(1);
+ context->setCompositeOperation(CompositeSourceOver);
+}
+
+CanvasStyle* CanvasRenderingContext2D::strokeStyle() const
+{
+ return state().m_strokeStyle.get();
+}
+
+void CanvasRenderingContext2D::setStrokeStyle(PassRefPtr<CanvasStyle> style)
+{
+ if (!style)
+ return;
+
+ if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentColor(*style))
+ return;
+
+ if (style->isCurrentColor()) {
+ if (style->hasOverrideAlpha())
+ style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
+ else
+ style = CanvasStyle::createFromRGBA(currentColor(canvas()));
+ } else
+ checkOrigin(style->canvasPattern());
+
+ state().m_strokeStyle = style;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ state().m_strokeStyle->applyStrokeColor(c);
+ state().m_unparsedStrokeColor = String();
+}
+
+CanvasStyle* CanvasRenderingContext2D::fillStyle() const
+{
+ return state().m_fillStyle.get();
+}
+
+void CanvasRenderingContext2D::setFillStyle(PassRefPtr<CanvasStyle> style)
+{
+ if (!style)
+ return;
+
+ if (state().m_fillStyle && state().m_fillStyle->isEquivalentColor(*style))
+ return;
+
+ if (style->isCurrentColor()) {
+ if (style->hasOverrideAlpha())
+ style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
+ else
+ style = CanvasStyle::createFromRGBA(currentColor(canvas()));
+ } else
+ checkOrigin(style->canvasPattern());
+
+ state().m_fillStyle = style;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ state().m_fillStyle->applyFillColor(c);
+ state().m_unparsedFillColor = String();
+}
+
+float CanvasRenderingContext2D::lineWidth() const
+{
+ return state().m_lineWidth;
+}
+
+void CanvasRenderingContext2D::setLineWidth(float width)
+{
+ if (!(isfinite(width) && width > 0))
+ return;
+ state().m_lineWidth = width;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setStrokeThickness(width);
+}
+
+String CanvasRenderingContext2D::lineCap() const
+{
+ return lineCapName(state().m_lineCap);
+}
+
+void CanvasRenderingContext2D::setLineCap(const String& s)
+{
+ LineCap cap;
+ if (!parseLineCap(s, cap))
+ return;
+ state().m_lineCap = cap;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setLineCap(cap);
+}
+
+String CanvasRenderingContext2D::lineJoin() const
+{
+ return lineJoinName(state().m_lineJoin);
+}
+
+void CanvasRenderingContext2D::setLineJoin(const String& s)
+{
+ LineJoin join;
+ if (!parseLineJoin(s, join))
+ return;
+ state().m_lineJoin = join;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setLineJoin(join);
+}
+
+float CanvasRenderingContext2D::miterLimit() const
+{
+ return state().m_miterLimit;
+}
+
+void CanvasRenderingContext2D::setMiterLimit(float limit)
+{
+ if (!(isfinite(limit) && limit > 0))
+ return;
+ state().m_miterLimit = limit;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setMiterLimit(limit);
+}
+
+float CanvasRenderingContext2D::shadowOffsetX() const
+{
+ return state().m_shadowOffset.width();
+}
+
+void CanvasRenderingContext2D::setShadowOffsetX(float x)
+{
+ if (!isfinite(x))
+ return;
+ state().m_shadowOffset.setWidth(x);
+ applyShadow();
+}
+
+float CanvasRenderingContext2D::shadowOffsetY() const
+{
+ return state().m_shadowOffset.height();
+}
+
+void CanvasRenderingContext2D::setShadowOffsetY(float y)
+{
+ if (!isfinite(y))
+ return;
+ state().m_shadowOffset.setHeight(y);
+ applyShadow();
+}
+
+float CanvasRenderingContext2D::shadowBlur() const
+{
+ return state().m_shadowBlur;
+}
+
+void CanvasRenderingContext2D::setShadowBlur(float blur)
+{
+ if (!(isfinite(blur) && blur >= 0))
+ return;
+ state().m_shadowBlur = blur;
+ applyShadow();
+}
+
+String CanvasRenderingContext2D::shadowColor() const
+{
+ return Color(state().m_shadowColor).serialized();
+}
+
+void CanvasRenderingContext2D::setShadowColor(const String& color)
+{
+ if (!parseColorOrCurrentColor(state().m_shadowColor, color, canvas()))
+ return;
+
+ applyShadow();
+}
+
+float CanvasRenderingContext2D::globalAlpha() const
+{
+ return state().m_globalAlpha;
+}
+
+void CanvasRenderingContext2D::setGlobalAlpha(float alpha)
+{
+ if (!(alpha >= 0 && alpha <= 1))
+ return;
+ state().m_globalAlpha = alpha;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setAlpha(alpha);
+}
+
+String CanvasRenderingContext2D::globalCompositeOperation() const
+{
+ return compositeOperatorName(state().m_globalComposite);
+}
+
+void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operation)
+{
+ CompositeOperator op;
+ if (!parseCompositeOperator(operation, op))
+ return;
+ state().m_globalComposite = op;
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ c->setCompositeOperation(op);
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ if (isAccelerated() && op != CompositeSourceOver) {
+ c->setSharedGraphicsContext3D(0, 0, IntSize());
+ m_drawingBuffer.clear();
+ m_context3D.clear();
+ // Mark as needing a style recalc so our compositing layer can be removed.
+ canvas()->setNeedsStyleRecalc(SyntheticStyleChange);
+ }
+#endif
+}
+
+void CanvasRenderingContext2D::scale(float sx, float sy)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!isfinite(sx) | !isfinite(sy))
+ return;
+
+ AffineTransform newTransform = state().m_transform;
+ newTransform.scaleNonUniform(sx, sy);
+ if (!newTransform.isInvertible()) {
+ state().m_invertibleCTM = false;
+ return;
+ }
+
+ state().m_transform = newTransform;
+ c->scale(FloatSize(sx, sy));
+ m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy));
+}
+
+void CanvasRenderingContext2D::rotate(float angleInRadians)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!isfinite(angleInRadians))
+ return;
+
+ AffineTransform newTransform = state().m_transform;
+ newTransform.rotate(angleInRadians / piDouble * 180.0);
+ if (!newTransform.isInvertible()) {
+ state().m_invertibleCTM = false;
+ return;
+ }
+
+ state().m_transform = newTransform;
+ c->rotate(angleInRadians);
+ m_path.transform(AffineTransform().rotate(-angleInRadians / piDouble * 180.0));
+}
+
+void CanvasRenderingContext2D::translate(float tx, float ty)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!isfinite(tx) | !isfinite(ty))
+ return;
+
+ AffineTransform newTransform = state().m_transform;
+ newTransform.translate(tx, ty);
+ if (!newTransform.isInvertible()) {
+ state().m_invertibleCTM = false;
+ return;
+ }
+
+ state().m_transform = newTransform;
+ c->translate(tx, ty);
+ m_path.transform(AffineTransform().translate(-tx, -ty));
+}
+
+void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float m22, float dx, float dy)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!isfinite(m11) | !isfinite(m21) | !isfinite(dx) | !isfinite(m12) | !isfinite(m22) | !isfinite(dy))
+ return;
+
+ AffineTransform transform(m11, m12, m21, m22, dx, dy);
+ AffineTransform newTransform = transform * state().m_transform;
+ if (!newTransform.isInvertible()) {
+ state().m_invertibleCTM = false;
+ return;
+ }
+
+ state().m_transform = newTransform;
+ c->concatCTM(transform);
+ m_path.transform(transform.inverse());
+}
+
+void CanvasRenderingContext2D::setTransform(float m11, float m12, float m21, float m22, float dx, float dy)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ if (!isfinite(m11) | !isfinite(m21) | !isfinite(dx) | !isfinite(m12) | !isfinite(m22) | !isfinite(dy))
+ return;
+
+ AffineTransform ctm = state().m_transform;
+ if (!ctm.isInvertible())
+ return;
+ c->concatCTM(c->getCTM().inverse());
+ c->concatCTM(canvas()->baseTransform());
+ state().m_transform.multiply(ctm.inverse());
+ m_path.transform(ctm);
+
+ state().m_invertibleCTM = true;
+ transform(m11, m12, m21, m22, dx, dy);
+}
+
+void CanvasRenderingContext2D::setStrokeColor(const String& color)
+{
+ if (color == state().m_unparsedStrokeColor)
+ return;
+ setStrokeStyle(CanvasStyle::createFromString(color));
+ state().m_unparsedStrokeColor = color;
+}
+
+void CanvasRenderingContext2D::setStrokeColor(float grayLevel)
+{
+ if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentRGBA(grayLevel, grayLevel, grayLevel, 1.0f))
+ return;
+ setStrokeStyle(CanvasStyle::createFromGrayLevelWithAlpha(grayLevel, 1.0f));
+}
+
+void CanvasRenderingContext2D::setStrokeColor(const String& color, float alpha)
+{
+ setStrokeStyle(CanvasStyle::createFromStringWithOverrideAlpha(color, alpha));
+}
+
+void CanvasRenderingContext2D::setStrokeColor(float grayLevel, float alpha)
+{
+ if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentRGBA(grayLevel, grayLevel, grayLevel, alpha))
+ return;
+ setStrokeStyle(CanvasStyle::createFromGrayLevelWithAlpha(grayLevel, alpha));
+}
+
+void CanvasRenderingContext2D::setStrokeColor(float r, float g, float b, float a)
+{
+ if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentRGBA(r, g, b, a))
+ return;
+ setStrokeStyle(CanvasStyle::createFromRGBAChannels(r, g, b, a));
+}
+
+void CanvasRenderingContext2D::setStrokeColor(float c, float m, float y, float k, float a)
+{
+ if (state().m_strokeStyle && state().m_strokeStyle->isEquivalentCMYKA(c, m, y, k, a))
+ return;
+ setStrokeStyle(CanvasStyle::createFromCMYKAChannels(c, m, y, k, a));
+}
+
+void CanvasRenderingContext2D::setFillColor(const String& color)
+{
+ if (color == state().m_unparsedFillColor)
+ return;
+ setFillStyle(CanvasStyle::createFromString(color));
+ state().m_unparsedFillColor = color;
+}
+
+void CanvasRenderingContext2D::setFillColor(float grayLevel)
+{
+ if (state().m_fillStyle && state().m_fillStyle->isEquivalentRGBA(grayLevel, grayLevel, grayLevel, 1.0f))
+ return;
+ setFillStyle(CanvasStyle::createFromGrayLevelWithAlpha(grayLevel, 1.0f));
+}
+
+void CanvasRenderingContext2D::setFillColor(const String& color, float alpha)
+{
+ setFillStyle(CanvasStyle::createFromStringWithOverrideAlpha(color, alpha));
+}
+
+void CanvasRenderingContext2D::setFillColor(float grayLevel, float alpha)
+{
+ if (state().m_fillStyle && state().m_fillStyle->isEquivalentRGBA(grayLevel, grayLevel, grayLevel, alpha))
+ return;
+ setFillStyle(CanvasStyle::createFromGrayLevelWithAlpha(grayLevel, alpha));
+}
+
+void CanvasRenderingContext2D::setFillColor(float r, float g, float b, float a)
+{
+ if (state().m_fillStyle && state().m_fillStyle->isEquivalentRGBA(r, g, b, a))
+ return;
+ setFillStyle(CanvasStyle::createFromRGBAChannels(r, g, b, a));
+}
+
+void CanvasRenderingContext2D::setFillColor(float c, float m, float y, float k, float a)
+{
+ if (state().m_fillStyle && state().m_fillStyle->isEquivalentCMYKA(c, m, y, k, a))
+ return;
+ setFillStyle(CanvasStyle::createFromCMYKAChannels(c, m, y, k, a));
+}
+
+void CanvasRenderingContext2D::beginPath()
+{
+ m_path.clear();
+}
+
+void CanvasRenderingContext2D::closePath()
+{
+ if (m_path.isEmpty())
+ return;
+
+ FloatRect boundRect = m_path.boundingRect();
+ if (boundRect.width() || boundRect.height())
+ m_path.closeSubpath();
+}
+
+void CanvasRenderingContext2D::moveTo(float x, float y)
+{
+ if (!isfinite(x) | !isfinite(y))
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+ m_path.moveTo(FloatPoint(x, y));
+}
+
+void CanvasRenderingContext2D::lineTo(float x, float y)
+{
+ if (!isfinite(x) | !isfinite(y))
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ FloatPoint p1 = FloatPoint(x, y);
+ if (!m_path.hasCurrentPoint())
+ m_path.moveTo(p1);
+ else if (p1 != m_path.currentPoint())
+ m_path.addLineTo(FloatPoint(x, y));
+}
+
+void CanvasRenderingContext2D::quadraticCurveTo(float cpx, float cpy, float x, float y)
+{
+ if (!isfinite(cpx) | !isfinite(cpy) | !isfinite(x) | !isfinite(y))
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+ if (!m_path.hasCurrentPoint())
+ m_path.moveTo(FloatPoint(cpx, cpy));
+
+ FloatPoint p1 = FloatPoint(x, y);
+ if (p1 != m_path.currentPoint())
+ m_path.addQuadCurveTo(FloatPoint(cpx, cpy), p1);
+}
+
+void CanvasRenderingContext2D::bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y)
+{
+ if (!isfinite(cp1x) | !isfinite(cp1y) | !isfinite(cp2x) | !isfinite(cp2y) | !isfinite(x) | !isfinite(y))
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+ if (!m_path.hasCurrentPoint())
+ m_path.moveTo(FloatPoint(cp1x, cp1y));
+
+ FloatPoint p1 = FloatPoint(x, y);
+ if (p1 != m_path.currentPoint())
+ m_path.addBezierCurveTo(FloatPoint(cp1x, cp1y), FloatPoint(cp2x, cp2y), p1);
+}
+
+void CanvasRenderingContext2D::arcTo(float x1, float y1, float x2, float y2, float r, ExceptionCode& ec)
+{
+ ec = 0;
+ if (!isfinite(x1) | !isfinite(y1) | !isfinite(x2) | !isfinite(y2) | !isfinite(r))
+ return;
+
+ if (r < 0) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ if (!state().m_invertibleCTM)
+ return;
+
+ FloatPoint p1 = FloatPoint(x1, y1);
+ FloatPoint p2 = FloatPoint(x2, y2);
+
+ if (!m_path.hasCurrentPoint())
+ m_path.moveTo(p1);
+ else if (p1 == m_path.currentPoint() || p1 == p2 || !r)
+ lineTo(x1, y1);
+ else
+ m_path.addArcTo(p1, p2, r);
+}
+
+void CanvasRenderingContext2D::arc(float x, float y, float r, float sa, float ea, bool anticlockwise, ExceptionCode& ec)
+{
+ ec = 0;
+ if (!isfinite(x) | !isfinite(y) | !isfinite(r) | !isfinite(sa) | !isfinite(ea))
+ return;
+
+ if (r < 0) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ if (sa == ea)
+ return;
+
+ if (!state().m_invertibleCTM)
+ return;
+ m_path.addArc(FloatPoint(x, y), r, sa, ea, anticlockwise);
+}
+
+static bool validateRectForCanvas(float& x, float& y, float& width, float& height)
+{
+ if (!isfinite(x) | !isfinite(y) | !isfinite(width) | !isfinite(height))
+ return false;
+
+ if (!width && !height)
+ return false;
+
+ if (width < 0) {
+ width = -width;
+ x -= width;
+ }
+
+ if (height < 0) {
+ height = -height;
+ y -= height;
+ }
+
+ return true;
+}
+
+void CanvasRenderingContext2D::rect(float x, float y, float width, float height)
+{
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!isfinite(x) || !isfinite(y) || !isfinite(width) || !isfinite(height))
+ return;
+
+ if (!width && !height) {
+ m_path.moveTo(FloatPoint(x, y));
+ return;
+ }
+
+ m_path.addRect(FloatRect(x, y, width, height));
+}
+
+#if ENABLE(DASHBOARD_SUPPORT)
+void CanvasRenderingContext2D::clearPathForDashboardBackwardCompatibilityMode()
+{
+ if (m_usesDashboardCompatibilityMode)
+ m_path.clear();
+}
+#endif
+
+void CanvasRenderingContext2D::fill()
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!m_path.isEmpty()) {
+ c->fillPath(m_path);
+ didDraw(m_path.boundingRect());
+ }
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ clearPathForDashboardBackwardCompatibilityMode();
+#endif
+}
+
+void CanvasRenderingContext2D::stroke()
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ if (!m_path.isEmpty()) {
+#if PLATFORM(QT)
+ // Fast approximation of the stroke's bounding rect.
+ // This yields a slightly oversized rect but is very fast
+ // compared to Path::strokeBoundingRect().
+ FloatRect boundingRect = m_path.platformPath().controlPointRect();
+ boundingRect.inflate(state().m_miterLimit + state().m_lineWidth);
+#else
+ CanvasStrokeStyleApplier strokeApplier(this);
+ FloatRect boundingRect = m_path.strokeBoundingRect(&strokeApplier);
+#endif
+ c->strokePath(m_path);
+ didDraw(boundingRect);
+ }
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ clearPathForDashboardBackwardCompatibilityMode();
+#endif
+}
+
+void CanvasRenderingContext2D::clip()
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+ c->canvasClip(m_path);
+#if ENABLE(DASHBOARD_SUPPORT)
+ clearPathForDashboardBackwardCompatibilityMode();
+#endif
+}
+
+bool CanvasRenderingContext2D::isPointInPath(const float x, const float y)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return false;
+ if (!state().m_invertibleCTM)
+ return false;
+
+ FloatPoint point(x, y);
+ AffineTransform ctm = state().m_transform;
+ FloatPoint transformedPoint = ctm.inverse().mapPoint(point);
+ return m_path.contains(transformedPoint);
+}
+
+void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height)
+{
+ if (!validateRectForCanvas(x, y, width, height))
+ return;
+ GraphicsContext* context = drawingContext();
+ if (!context)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+ FloatRect rect(x, y, width, height);
+
+ save();
+ setAllAttributesToDefault();
+ context->clearRect(rect);
+ didDraw(rect);
+ restore();
+}
+
+void CanvasRenderingContext2D::fillRect(float x, float y, float width, float height)
+{
+ if (!validateRectForCanvas(x, y, width, height))
+ return;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ // from the HTML5 Canvas spec:
+ // If x0 = x1 and y0 = y1, then the linear gradient must paint nothing
+ // If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint nothing
+ Gradient* gradient = c->fillGradient();
+ if (gradient && gradient->isZeroSize())
+ return;
+
+ FloatRect rect(x, y, width, height);
+
+ c->fillRect(rect);
+ didDraw(rect);
+}
+
+void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float height)
+{
+ if (!validateRectForCanvas(x, y, width, height))
+ return;
+ strokeRect(x, y, width, height, state().m_lineWidth);
+}
+
+void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float height, float lineWidth)
+{
+ if (!validateRectForCanvas(x, y, width, height))
+ return;
+
+ if (!(lineWidth >= 0))
+ return;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ FloatRect rect(x, y, width, height);
+
+ FloatRect boundingRect = rect;
+ boundingRect.inflate(lineWidth / 2);
+
+ c->strokeRect(rect, lineWidth);
+ didDraw(boundingRect);
+}
+
+#if PLATFORM(CG)
+static inline CGSize adjustedShadowSize(CGFloat width, CGFloat height)
+{
+ // Work around <rdar://problem/5539388> by ensuring that shadow offsets will get truncated
+ // to the desired integer.
+ static const CGFloat extraShadowOffset = narrowPrecisionToCGFloat(1.0 / 128);
+ if (width > 0)
+ width += extraShadowOffset;
+ else if (width < 0)
+ width -= extraShadowOffset;
+
+ if (height > 0)
+ height += extraShadowOffset;
+ else if (height < 0)
+ height -= extraShadowOffset;
+
+ return CGSizeMake(width, height);
+}
+#endif
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur)
+{
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+ state().m_shadowColor = Color::transparent;
+ applyShadow();
+}
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, const String& color)
+{
+ if (!parseColorOrCurrentColor(state().m_shadowColor, color, canvas()))
+ return;
+
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+ applyShadow();
+}
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float grayLevel)
+{
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+ state().m_shadowColor = makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, 1.0f);
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ c->setShadow(IntSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+}
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, const String& color, float alpha)
+{
+ RGBA32 rgba;
+
+ if (!parseColorOrCurrentColor(rgba, color, canvas()))
+ return;
+
+ state().m_shadowColor = colorWithOverrideAlpha(rgba, alpha);
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ c->setShadow(IntSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+}
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float grayLevel, float alpha)
+{
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+ state().m_shadowColor = makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, alpha);
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ c->setShadow(IntSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+}
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float r, float g, float b, float a)
+{
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+ state().m_shadowColor = makeRGBA32FromFloats(r, g, b, a);
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ c->setShadow(IntSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+}
+
+void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float c, float m, float y, float k, float a)
+{
+ state().m_shadowOffset = FloatSize(width, height);
+ state().m_shadowBlur = blur;
+ state().m_shadowColor = makeRGBAFromCMYKA(c, m, y, k, a);
+
+ GraphicsContext* dc = drawingContext();
+ if (!dc)
+ return;
+#if PLATFORM(CG)
+ const CGFloat components[5] = { c, m, y, k, a };
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceCMYK();
+ CGColorRef shadowColor = CGColorCreate(colorSpace, components);
+ CGColorSpaceRelease(colorSpace);
+ CGContextSetShadowWithColor(dc->platformContext(), adjustedShadowSize(width, -height), blur, shadowColor);
+ CGColorRelease(shadowColor);
+#else
+ dc->setShadow(IntSize(width, -height), blur, state().m_shadowColor, ColorSpaceDeviceRGB);
+#endif
+}
+
+void CanvasRenderingContext2D::clearShadow()
+{
+ state().m_shadowOffset = FloatSize();
+ state().m_shadowBlur = 0;
+ state().m_shadowColor = Color::transparent;
+ applyShadow();
+}
+
+void CanvasRenderingContext2D::applyShadow()
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+
+ float width = state().m_shadowOffset.width();
+ float height = state().m_shadowOffset.height();
+ c->setShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+}
+
+static IntSize size(HTMLImageElement* image)
+{
+ if (CachedImage* cachedImage = image->cachedImage())
+ return cachedImage->imageSize(1.0f); // FIXME: Not sure about this.
+ return IntSize();
+}
+
+#if ENABLE(VIDEO)
+static IntSize size(HTMLVideoElement* video)
+{
+ if (MediaPlayer* player = video->player())
+ return player->naturalSize();
+ return IntSize();
+}
+#endif
+
+static inline FloatRect normalizeRect(const FloatRect& rect)
+{
+ return FloatRect(min(rect.x(), rect.right()),
+ min(rect.y(), rect.bottom()),
+ max(rect.width(), -rect.width()),
+ max(rect.height(), -rect.height()));
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y, ExceptionCode& ec)
+{
+ if (!image) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ IntSize s = size(image);
+ drawImage(image, x, y, s.width(), s.height(), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
+ float x, float y, float width, float height, ExceptionCode& ec)
+{
+ if (!image) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ IntSize s = size(image);
+ drawImage(image, FloatRect(0, 0, s.width(), s.height()), FloatRect(x, y, width, height), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
+ float sx, float sy, float sw, float sh,
+ float dx, float dy, float dw, float dh, ExceptionCode& ec)
+{
+ if (!image) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect,
+ ExceptionCode& ec)
+{
+ if (!image) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+
+ ec = 0;
+
+ if (!isfinite(dstRect.x()) || !isfinite(dstRect.y()) || !isfinite(dstRect.width()) || !isfinite(dstRect.height())
+ || !isfinite(srcRect.x()) || !isfinite(srcRect.y()) || !isfinite(srcRect.width()) || !isfinite(srcRect.height()))
+ return;
+
+ if (!dstRect.width() || !dstRect.height())
+ return;
+
+ if (!image->complete())
+ return;
+
+ FloatRect normalizedSrcRect = normalizeRect(srcRect);
+ FloatRect normalizedDstRect = normalizeRect(dstRect);
+
+ FloatRect imageRect = FloatRect(FloatPoint(), size(image));
+ if (!imageRect.contains(normalizedSrcRect) || !srcRect.width() || !srcRect.height()) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ CachedImage* cachedImage = image->cachedImage();
+ if (!cachedImage)
+ return;
+
+ checkOrigin(image);
+
+ FloatRect sourceRect = c->roundToDevicePixels(normalizedSrcRect);
+ FloatRect destRect = c->roundToDevicePixels(normalizedDstRect);
+ c->drawImage(cachedImage->image(), ColorSpaceDeviceRGB, destRect, sourceRect, state().m_globalComposite);
+ didDraw(destRect);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, float x, float y, ExceptionCode& ec)
+{
+ if (!canvas) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ drawImage(canvas, x, y, canvas->width(), canvas->height(), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas,
+ float x, float y, float width, float height, ExceptionCode& ec)
+{
+ if (!canvas) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ drawImage(canvas, FloatRect(0, 0, canvas->width(), canvas->height()), FloatRect(x, y, width, height), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas,
+ float sx, float sy, float sw, float sh,
+ float dx, float dy, float dw, float dh, ExceptionCode& ec)
+{
+ drawImage(canvas, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const FloatRect& srcRect,
+ const FloatRect& dstRect, ExceptionCode& ec)
+{
+ if (!sourceCanvas) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+
+ FloatRect srcCanvasRect = FloatRect(FloatPoint(), sourceCanvas->size());
+
+ if (!srcCanvasRect.width() || !srcCanvasRect.height()) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+
+ if (!srcCanvasRect.contains(normalizeRect(srcRect)) || !srcRect.width() || !srcRect.height()) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ ec = 0;
+
+ if (!dstRect.width() || !dstRect.height())
+ return;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ FloatRect sourceRect = c->roundToDevicePixels(srcRect);
+ FloatRect destRect = c->roundToDevicePixels(dstRect);
+
+ // FIXME: Do this through platform-independent GraphicsContext API.
+ ImageBuffer* buffer = sourceCanvas->buffer();
+ if (!buffer)
+ return;
+
+ checkOrigin(sourceCanvas);
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ // If we're drawing from one accelerated canvas 2d to another, avoid calling sourceCanvas->makeRenderingResultsAvailable()
+ // as that will do a readback to software.
+ CanvasRenderingContext* sourceContext = sourceCanvas->renderingContext();
+ // FIXME: Implement an accelerated path for drawing from a WebGL canvas to a 2d canvas when possible.
+ if (!isAccelerated() || !sourceContext || !sourceContext->isAccelerated() || !sourceContext->is2d())
+ sourceCanvas->makeRenderingResultsAvailable();
+#else
+ sourceCanvas->makeRenderingResultsAvailable();
+#endif
+
+ c->drawImageBuffer(buffer, ColorSpaceDeviceRGB, destRect, sourceRect, state().m_globalComposite);
+ didDraw(destRect);
+}
+
+#if ENABLE(VIDEO)
+void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, float x, float y, ExceptionCode& ec)
+{
+ if (!video) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ IntSize s = size(video);
+ drawImage(video, x, y, s.width(), s.height(), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
+ float x, float y, float width, float height, ExceptionCode& ec)
+{
+ if (!video) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ IntSize s = size(video);
+ drawImage(video, FloatRect(0, 0, s.width(), s.height()), FloatRect(x, y, width, height), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
+ float sx, float sy, float sw, float sh,
+ float dx, float dy, float dw, float dh, ExceptionCode& ec)
+{
+ drawImage(video, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), ec);
+}
+
+void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRect& srcRect, const FloatRect& dstRect,
+ ExceptionCode& ec)
+{
+ if (!video) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+
+ ec = 0;
+
+ if (video->readyState() == HTMLMediaElement::HAVE_NOTHING || video->readyState() == HTMLMediaElement::HAVE_METADATA)
+ return;
+
+ FloatRect videoRect = FloatRect(FloatPoint(), size(video));
+ if (!videoRect.contains(normalizeRect(srcRect)) || !srcRect.width() || !srcRect.height()) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ if (!dstRect.width() || !dstRect.height())
+ return;
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ checkOrigin(video);
+
+ FloatRect sourceRect = c->roundToDevicePixels(srcRect);
+ FloatRect destRect = c->roundToDevicePixels(dstRect);
+
+ c->save();
+ c->clip(destRect);
+ c->translate(destRect.x(), destRect.y());
+ c->scale(FloatSize(destRect.width() / sourceRect.width(), destRect.height() / sourceRect.height()));
+ c->translate(-sourceRect.x(), -sourceRect.y());
+ video->paintCurrentFrameInContext(c, IntRect(IntPoint(), size(video)));
+ c->restore();
+ didDraw(destRect);
+}
+#endif
+
+// FIXME: Why isn't this just another overload of drawImage? Why have a different name?
+void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
+ float sx, float sy, float sw, float sh,
+ float dx, float dy, float dw, float dh,
+ const String& compositeOperation)
+{
+ if (!image)
+ return;
+
+ CachedImage* cachedImage = image->cachedImage();
+ if (!cachedImage)
+ return;
+
+ checkOrigin(image);
+
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ CompositeOperator op;
+ if (!parseCompositeOperator(compositeOperation, op))
+ op = CompositeSourceOver;
+
+ FloatRect destRect = FloatRect(dx, dy, dw, dh);
+ c->drawImage(cachedImage->image(), ColorSpaceDeviceRGB, destRect, FloatRect(sx, sy, sw, sh), op);
+ didDraw(destRect);
+}
+
+void CanvasRenderingContext2D::setAlpha(float alpha)
+{
+ setGlobalAlpha(alpha);
+}
+
+void CanvasRenderingContext2D::setCompositeOperation(const String& operation)
+{
+ setGlobalCompositeOperation(operation);
+}
+
+void CanvasRenderingContext2D::prepareGradientForDashboard(CanvasGradient* gradient) const
+{
+#if ENABLE(DASHBOARD_SUPPORT)
+ if (m_usesDashboardCompatibilityMode)
+ gradient->setDashboardCompatibilityMode();
+#else
+ UNUSED_PARAM(gradient);
+#endif
+}
+
+PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode& ec)
+{
+ if (!isfinite(x0) || !isfinite(y0) || !isfinite(x1) || !isfinite(y1)) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+
+ RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
+ prepareGradientForDashboard(gradient.get());
+ return gradient.release();
+}
+
+PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode& ec)
+{
+ if (!isfinite(x0) || !isfinite(y0) || !isfinite(r0) || !isfinite(x1) || !isfinite(y1) || !isfinite(r1)) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+
+ if (r0 < 0 || r1 < 0) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+
+ RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
+ prepareGradientForDashboard(gradient.get());
+ return gradient.release();
+}
+
+PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageElement* image,
+ const String& repetitionType, ExceptionCode& ec)
+{
+ if (!image) {
+ ec = TYPE_MISMATCH_ERR;
+ return 0;
+ }
+ bool repeatX, repeatY;
+ ec = 0;
+ CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, ec);
+ if (ec)
+ return 0;
+
+ if (!image->complete())
+ return 0;
+
+ CachedImage* cachedImage = image->cachedImage();
+ if (!cachedImage || !image->cachedImage()->image())
+ return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
+
+ bool originClean = !canvas()->securityOrigin().taintsCanvas(KURL(KURL(), cachedImage->response().url())) && cachedImage->image()->hasSingleSecurityOrigin();
+ return CanvasPattern::create(cachedImage->image(), repeatX, repeatY, originClean);
+}
+
+PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElement* canvas,
+ const String& repetitionType, ExceptionCode& ec)
+{
+ if (!canvas) {
+ ec = TYPE_MISMATCH_ERR;
+ return 0;
+ }
+ if (!canvas->width() || !canvas->height()) {
+ ec = INVALID_STATE_ERR;
+ return 0;
+ }
+
+ bool repeatX, repeatY;
+ ec = 0;
+ CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, ec);
+ if (ec)
+ return 0;
+ return CanvasPattern::create(canvas->copiedImage(), repeatX, repeatY, canvas->originClean());
+}
+
+void CanvasRenderingContext2D::didDraw(const FloatRect& r, unsigned options)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+
+ FloatRect dirtyRect = r;
+ if (options & CanvasDidDrawApplyTransform) {
+ AffineTransform ctm = state().m_transform;
+ dirtyRect = ctm.mapRect(r);
+ }
+
+ if (options & CanvasDidDrawApplyShadow && alphaChannel(state().m_shadowColor)) {
+ // The shadow gets applied after transformation
+ FloatRect shadowRect(dirtyRect);
+ shadowRect.move(state().m_shadowOffset);
+ shadowRect.inflate(state().m_shadowBlur);
+ dirtyRect.unite(shadowRect);
+ }
+
+ if (options & CanvasDidDrawApplyClip) {
+ // FIXME: apply the current clip to the rectangle. Unfortunately we can't get the clip
+ // back out of the GraphicsContext, so to take clip into account for incremental painting,
+ // we'd have to keep the clip path around.
+ }
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ if (isAccelerated())
+ drawingContext()->markDirtyRect(enclosingIntRect(dirtyRect));
+#endif
+#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
+ // If we are drawing to hardware and we have a composited layer, just call contentChanged().
+ RenderBox* renderBox = canvas()->renderBox();
+ if (isAccelerated() && renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
+ renderBox->layer()->contentChanged(RenderLayer::CanvasChanged);
+ else
+#endif
+ canvas()->didDraw(dirtyRect);
+}
+
+GraphicsContext* CanvasRenderingContext2D::drawingContext() const
+{
+ return canvas()->drawingContext();
+}
+
+static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size)
+{
+ RefPtr<ImageData> data = ImageData::create(size);
+ memset(data->data()->data()->data(), 0, data->data()->data()->length());
+ return data.release();
+}
+
+PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(PassRefPtr<ImageData> imageData, ExceptionCode& ec) const
+{
+ if (!imageData) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+
+ return createEmptyImageData(imageData->size());
+}
+
+PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh, ExceptionCode& ec) const
+{
+ ec = 0;
+ if (!sw || !sh) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+ if (!isfinite(sw) || !isfinite(sh)) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+
+ FloatSize unscaledSize(fabs(sw), fabs(sh));
+ IntSize scaledSize = canvas()->convertLogicalToDevice(unscaledSize);
+ if (scaledSize.width() < 1)
+ scaledSize.setWidth(1);
+ if (scaledSize.height() < 1)
+ scaledSize.setHeight(1);
+
+ return createEmptyImageData(scaledSize);
+}
+
+PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh, ExceptionCode& ec) const
+{
+ if (!canvas()->originClean()) {
+ ec = SECURITY_ERR;
+ return 0;
+ }
+ if (!sw || !sh) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+ if (!isfinite(sx) || !isfinite(sy) || !isfinite(sw) || !isfinite(sh)) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+
+ if (sw < 0) {
+ sx += sw;
+ sw = -sw;
+ }
+ if (sh < 0) {
+ sy += sh;
+ sh = -sh;
+ }
+
+ FloatRect unscaledRect(sx, sy, sw, sh);
+ IntRect scaledRect = canvas()->convertLogicalToDevice(unscaledRect);
+ if (scaledRect.width() < 1)
+ scaledRect.setWidth(1);
+ if (scaledRect.height() < 1)
+ scaledRect.setHeight(1);
+ ImageBuffer* buffer = canvas()->buffer();
+ if (!buffer)
+ return createEmptyImageData(scaledRect.size());
+ return ImageData::create(scaledRect.size(), buffer->getUnmultipliedImageData(scaledRect));
+}
+
+void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, ExceptionCode& ec)
+{
+ if (!data) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ putImageData(data, dx, dy, 0, 0, data->width(), data->height(), ec);
+}
+
+void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, float dirtyX, float dirtyY,
+ float dirtyWidth, float dirtyHeight, ExceptionCode& ec)
+{
+ if (!data) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ if (!isfinite(dx) || !isfinite(dy) || !isfinite(dirtyX) || !isfinite(dirtyY) || !isfinite(dirtyWidth) || !isfinite(dirtyHeight)) {
+ ec = NOT_SUPPORTED_ERR;
+ return;
+ }
+
+ ImageBuffer* buffer = canvas()->buffer();
+ if (!buffer)
+ return;
+
+ if (dirtyWidth < 0) {
+ dirtyX += dirtyWidth;
+ dirtyWidth = -dirtyWidth;
+ }
+
+ if (dirtyHeight < 0) {
+ dirtyY += dirtyHeight;
+ dirtyHeight = -dirtyHeight;
+ }
+
+ FloatRect clipRect(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
+ clipRect.intersect(IntRect(0, 0, data->width(), data->height()));
+ IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy));
+ IntRect destRect = enclosingIntRect(clipRect);
+ destRect.move(destOffset);
+ destRect.intersect(IntRect(IntPoint(), buffer->size()));
+ if (destRect.isEmpty())
+ return;
+ IntRect sourceRect(destRect);
+ sourceRect.move(-destOffset);
+
+ buffer->putUnmultipliedImageData(data->data()->data(), IntSize(data->width(), data->height()), sourceRect, IntPoint(destOffset));
+ didDraw(destRect, CanvasDidDrawApplyNone); // ignore transform, shadow and clip
+}
+
+String CanvasRenderingContext2D::font() const
+{
+ return state().m_unparsedFont;
+}
+
+void CanvasRenderingContext2D::setFont(const String& newFont)
+{
+ RefPtr<CSSMutableStyleDeclaration> tempDecl = CSSMutableStyleDeclaration::create();
+ CSSParser parser(!m_usesCSSCompatibilityParseMode);
+
+ String declarationText("font: ");
+ declarationText += newFont;
+ parser.parseDeclaration(tempDecl.get(), declarationText);
+ if (!tempDecl->length())
+ return;
+
+ // The parse succeeded.
+ state().m_unparsedFont = newFont;
+
+ // Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
+ // relative to the canvas.
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ if (RenderStyle* computedStyle = canvas()->computedStyle())
+ newStyle->setFontDescription(computedStyle->fontDescription());
+ newStyle->font().update(newStyle->font().fontSelector());
+
+ // Now map the font property into the style.
+ CSSStyleSelector* styleSelector = canvas()->styleSelector();
+ styleSelector->applyPropertyToStyle(CSSPropertyFont, tempDecl->getPropertyCSSValue(CSSPropertyFont).get(), newStyle.get());
+
+ state().m_font = newStyle->font();
+ state().m_font.update(styleSelector->fontSelector());
+ state().m_realizedFont = true;
+}
+
+void CanvasRenderingContext2D::updateFont()
+{
+ if (!state().m_realizedFont)
+ return;
+
+ const Font& font = state().m_font;
+ font.update(font.fontSelector());
+}
+
+String CanvasRenderingContext2D::textAlign() const
+{
+ return textAlignName(state().m_textAlign);
+}
+
+void CanvasRenderingContext2D::setTextAlign(const String& s)
+{
+ TextAlign align;
+ if (!parseTextAlign(s, align))
+ return;
+ state().m_textAlign = align;
+}
+
+String CanvasRenderingContext2D::textBaseline() const
+{
+ return textBaselineName(state().m_textBaseline);
+}
+
+void CanvasRenderingContext2D::setTextBaseline(const String& s)
+{
+ TextBaseline baseline;
+ if (!parseTextBaseline(s, baseline))
+ return;
+ state().m_textBaseline = baseline;
+}
+
+void CanvasRenderingContext2D::fillText(const String& text, float x, float y)
+{
+ drawTextInternal(text, x, y, true);
+}
+
+void CanvasRenderingContext2D::fillText(const String& text, float x, float y, float maxWidth)
+{
+ drawTextInternal(text, x, y, true, maxWidth, true);
+}
+
+void CanvasRenderingContext2D::strokeText(const String& text, float x, float y)
+{
+ drawTextInternal(text, x, y, false);
+}
+
+void CanvasRenderingContext2D::strokeText(const String& text, float x, float y, float maxWidth)
+{
+ drawTextInternal(text, x, y, false, maxWidth, true);
+}
+
+PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
+{
+ RefPtr<TextMetrics> metrics = TextMetrics::create();
+
+#if PLATFORM(QT)
+ // We always use complex text shaping since it can't be turned off for QPainterPath::addText().
+ Font::CodePath oldCodePath = Font::codePath();
+ Font::setCodePath(Font::Complex);
+#endif
+
+ metrics->setWidth(accessFont().width(TextRun(text.characters(), text.length())));
+
+#if PLATFORM(QT)
+ Font::setCodePath(oldCodePath);
+#endif
+
+ return metrics.release();
+}
+
+void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, float y, bool fill, float /*maxWidth*/, bool /*useMaxWidth*/)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
+ return;
+ if (!state().m_invertibleCTM)
+ return;
+ if (!isfinite(x) | !isfinite(y))
+ return;
+
+ const Font& font = accessFont();
+
+ // FIXME: Handle maxWidth.
+ // FIXME: Need to turn off font smoothing.
+
+ RenderStyle* computedStyle = canvas()->computedStyle();
+ bool rtl = computedStyle ? !computedStyle->isLeftToRightDirection() : false;
+ bool override = computedStyle ? computedStyle->unicodeBidi() == Override : false;
+
+ unsigned length = text.length();
+ const UChar* string = text.characters();
+ TextRun textRun(string, length, 0, 0, 0, rtl, override, false, false);
+
+ // Draw the item text at the correct point.
+ FloatPoint location(x, y);
+ switch (state().m_textBaseline) {
+ case TopTextBaseline:
+ case HangingTextBaseline:
+ location.setY(y + font.ascent());
+ break;
+ case BottomTextBaseline:
+ case IdeographicTextBaseline:
+ location.setY(y - font.descent());
+ break;
+ case MiddleTextBaseline:
+ location.setY(y - font.descent() + font.height() / 2);
+ break;
+ case AlphabeticTextBaseline:
+ default:
+ // Do nothing.
+ break;
+ }
+
+ float width = font.width(TextRun(text, false, 0, 0, rtl, override));
+
+ TextAlign align = state().m_textAlign;
+ if (align == StartTextAlign)
+ align = rtl ? RightTextAlign : LeftTextAlign;
+ else if (align == EndTextAlign)
+ align = rtl ? LeftTextAlign : RightTextAlign;
+
+ switch (align) {
+ case CenterTextAlign:
+ location.setX(location.x() - width / 2);
+ break;
+ case RightTextAlign:
+ location.setX(location.x() - width);
+ break;
+ default:
+ break;
+ }
+
+ // The slop built in to this mask rect matches the heuristic used in FontCGWin.cpp for GDI text.
+ FloatRect textRect = FloatRect(location.x() - font.height() / 2, location.y() - font.ascent() - font.lineGap(),
+ width + font.height(), font.lineSpacing());
+ if (!fill)
+ textRect.inflate(c->strokeThickness() / 2);
+
+#if PLATFORM(CG)
+ CanvasStyle* drawStyle = fill ? state().m_fillStyle.get() : state().m_strokeStyle.get();
+ if (drawStyle->canvasGradient() || drawStyle->canvasPattern()) {
+ // FIXME: The rect is not big enough for miters on stroked text.
+ IntRect maskRect = enclosingIntRect(textRect);
+
+#if USE(IOSURFACE_CANVAS_BACKING_STORE)
+ OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), ColorSpaceDeviceRGB, Accelerated);
+#else
+ OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size());
+#endif
+
+ GraphicsContext* maskImageContext = maskImage->context();
+
+ if (fill)
+ maskImageContext->setFillColor(Color::black, ColorSpaceDeviceRGB);
+ else {
+ maskImageContext->setStrokeColor(Color::black, ColorSpaceDeviceRGB);
+ maskImageContext->setStrokeThickness(c->strokeThickness());
+ }
+
+ maskImageContext->setTextDrawingMode(fill ? TextModeFill : TextModeStroke);
+ maskImageContext->translate(-maskRect.x(), -maskRect.y());
+
+ maskImageContext->drawBidiText(font, textRun, location);
+
+ c->save();
+ c->clipToImageBuffer(maskImage.get(), maskRect);
+ drawStyle->applyFillColor(c);
+ c->fillRect(maskRect);
+ c->restore();
+
+ return;
+ }
+#endif
+
+ c->setTextDrawingMode(fill ? TextModeFill : TextModeStroke);
+
+#if PLATFORM(QT)
+ // We always use complex text shaping since it can't be turned off for QPainterPath::addText().
+ Font::CodePath oldCodePath = Font::codePath();
+ Font::setCodePath(Font::Complex);
+#endif
+
+ c->drawBidiText(font, textRun, location);
+
+ if (fill)
+ didDraw(textRect);
+ else {
+ // When stroking text, pointy miters can extend outside of textRect, so we
+ // punt and dirty the whole canvas.
+ didDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
+ }
+
+#if PLATFORM(QT)
+ Font::setCodePath(oldCodePath);
+#endif
+}
+
+const Font& CanvasRenderingContext2D::accessFont()
+{
+ canvas()->document()->updateStyleIfNeeded();
+
+ if (!state().m_realizedFont)
+ setFont(state().m_unparsedFont);
+ return state().m_font;
+}
+
+void CanvasRenderingContext2D::paintRenderingResultsToCanvas()
+{
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ if (GraphicsContext* c = drawingContext())
+ c->syncSoftwareCanvas();
+#endif
+}
+
+#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
+PlatformLayer* CanvasRenderingContext2D::platformLayer() const
+{
+ return m_drawingBuffer->platformLayer();
+}
+#endif
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.h b/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
new file mode 100644
index 0000000..206744e
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2006, 2007, 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,
+ * 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 CanvasRenderingContext2D_h
+#define CanvasRenderingContext2D_h
+
+#include "AffineTransform.h"
+#include "CanvasRenderingContext.h"
+#include "Color.h"
+#include "FloatSize.h"
+#include "Font.h"
+#include "GraphicsTypes.h"
+#include "Path.h"
+#include "PlatformString.h"
+
+#include <wtf/Vector.h>
+
+#if PLATFORM(CG)
+#include <ApplicationServices/ApplicationServices.h>
+#endif
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "GraphicsLayer.h"
+#endif
+
+namespace WebCore {
+
+class CanvasGradient;
+class CanvasPattern;
+class CanvasStyle;
+class FloatRect;
+class GraphicsContext;
+class HTMLCanvasElement;
+class HTMLImageElement;
+class HTMLVideoElement;
+class ImageData;
+class TextMetrics;
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+class DrawingBuffer;
+class SharedGraphicsContext3D;
+#endif
+
+typedef int ExceptionCode;
+
+class CanvasRenderingContext2D : public CanvasRenderingContext {
+public:
+ CanvasRenderingContext2D(HTMLCanvasElement*, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode);
+
+ virtual ~CanvasRenderingContext2D();
+
+ virtual bool is2d() const { return true; }
+ virtual bool isAccelerated() const;
+ virtual bool paintsIntoCanvasBuffer() const;
+
+ CanvasStyle* strokeStyle() const;
+ void setStrokeStyle(PassRefPtr<CanvasStyle>);
+
+ CanvasStyle* fillStyle() const;
+ void setFillStyle(PassRefPtr<CanvasStyle>);
+
+ float lineWidth() const;
+ void setLineWidth(float);
+
+ String lineCap() const;
+ void setLineCap(const String&);
+
+ String lineJoin() const;
+ void setLineJoin(const String&);
+
+ float miterLimit() const;
+ void setMiterLimit(float);
+
+ float shadowOffsetX() const;
+ void setShadowOffsetX(float);
+
+ float shadowOffsetY() const;
+ void setShadowOffsetY(float);
+
+ float shadowBlur() const;
+ void setShadowBlur(float);
+
+ String shadowColor() const;
+ void setShadowColor(const String&);
+
+ float globalAlpha() const;
+ void setGlobalAlpha(float);
+
+ String globalCompositeOperation() const;
+ void setGlobalCompositeOperation(const String&);
+
+ void save();
+ void restore();
+ void setAllAttributesToDefault();
+
+ void scale(float sx, float sy);
+ void rotate(float angleInRadians);
+ 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);
+
+ void setStrokeColor(const String& color);
+ void setStrokeColor(float grayLevel);
+ void setStrokeColor(const String& color, float alpha);
+ void setStrokeColor(float grayLevel, 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(const String& color);
+ void setFillColor(float grayLevel);
+ void setFillColor(const String& color, float alpha);
+ void setFillColor(float grayLevel, 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 beginPath();
+ void closePath();
+
+ 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);
+ 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 clockwise, ExceptionCode&);
+ void rect(float x, float y, float width, float height);
+
+ void fill();
+ void stroke();
+ void clip();
+
+ bool isPointInPath(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);
+ void strokeRect(float x, float y, float width, float height, float lineWidth);
+
+ void setShadow(float width, float height, float blur);
+ void setShadow(float width, float height, float blur, const String& color);
+ void setShadow(float width, float height, float blur, float grayLevel);
+ void setShadow(float width, float height, float blur, const String& color, float alpha);
+ void setShadow(float width, float height, float blur, float grayLevel, 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);
+
+ void clearShadow();
+
+ void drawImage(HTMLImageElement*, float x, float y, ExceptionCode&);
+ void drawImage(HTMLImageElement*, float x, float y, float width, float height, ExceptionCode&);
+ void drawImage(HTMLImageElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
+ void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
+ void drawImage(HTMLCanvasElement*, float x, float y, ExceptionCode&);
+ void drawImage(HTMLCanvasElement*, float x, float y, float width, float height, ExceptionCode&);
+ void drawImage(HTMLCanvasElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
+ void drawImage(HTMLCanvasElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
+#if ENABLE(VIDEO)
+ void drawImage(HTMLVideoElement*, float x, float y, ExceptionCode&);
+ void drawImage(HTMLVideoElement*, float x, float y, float width, float height, ExceptionCode&);
+ void drawImage(HTMLVideoElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
+ void drawImage(HTMLVideoElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
+#endif
+
+ void drawImageFromRect(HTMLImageElement*, float sx, float sy, float sw, float sh,
+ float dx, float dy, float dw, float dh, const String& compositeOperation);
+
+ void setAlpha(float);
+
+ void setCompositeOperation(const String&);
+
+ 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&);
+
+ 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;
+ 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 reset();
+
+ String font() const;
+ void setFont(const String&);
+ void updateFont();
+
+ String textAlign() const;
+ void setTextAlign(const String&);
+
+ String textBaseline() const;
+ void setTextBaseline(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);
+ PassRefPtr<TextMetrics> measureText(const String& text);
+
+ LineCap getLineCap() const { return state().m_lineCap; }
+ LineJoin getLineJoin() const { return state().m_lineJoin; }
+
+ virtual void paintRenderingResultsToCanvas();
+
+#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
+ virtual PlatformLayer* platformLayer() const;
+#endif
+
+private:
+ struct State {
+ State();
+
+ String m_unparsedStrokeColor;
+ String m_unparsedFillColor;
+ RefPtr<CanvasStyle> m_strokeStyle;
+ RefPtr<CanvasStyle> m_fillStyle;
+ float m_lineWidth;
+ LineCap m_lineCap;
+ LineJoin m_lineJoin;
+ float m_miterLimit;
+ FloatSize m_shadowOffset;
+ float m_shadowBlur;
+ RGBA32 m_shadowColor;
+ float m_globalAlpha;
+ CompositeOperator m_globalComposite;
+ AffineTransform m_transform;
+ bool m_invertibleCTM;
+
+ // Text state.
+ TextAlign m_textAlign;
+ TextBaseline m_textBaseline;
+
+ String m_unparsedFont;
+ Font m_font;
+ bool m_realizedFont;
+ };
+ Path m_path;
+
+ State& state() { return m_stateStack.last(); }
+ const State& state() const { return m_stateStack.last(); }
+
+ void applyShadow();
+
+ enum CanvasDidDrawOption {
+ CanvasDidDrawApplyNone = 0,
+ CanvasDidDrawApplyTransform = 1,
+ CanvasDidDrawApplyShadow = 1 << 1,
+ CanvasDidDrawApplyClip = 1 << 2,
+ CanvasDidDrawApplyAll = 0xffffffff
+ };
+
+ void didDraw(const FloatRect&, unsigned options = CanvasDidDrawApplyAll);
+
+ GraphicsContext* drawingContext() const;
+
+ void applyStrokePattern();
+ void applyFillPattern();
+
+ void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
+
+ const Font& accessFont();
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ void clearPathForDashboardBackwardCompatibilityMode();
+#endif
+
+ void prepareGradientForDashboard(CanvasGradient* gradient) const;
+
+ Vector<State, 1> m_stateStack;
+ bool m_usesCSSCompatibilityParseMode;
+#if ENABLE(DASHBOARD_SUPPORT)
+ bool m_usesDashboardCompatibilityMode;
+#endif
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ RefPtr<DrawingBuffer> m_drawingBuffer;
+ RefPtr<SharedGraphicsContext3D> m_context3D;
+#endif
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl b/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
new file mode 100644
index 0000000..23afc11
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
@@ -0,0 +1,181 @@
+/*
+ * 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
+ * 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.
+ */
+
+module html {
+
+ interface [
+ InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443,
+ ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54
+ ] CanvasRenderingContext2D : CanvasRenderingContext {
+
+ // Web Applications 1.0 draft
+
+ void save();
+ void restore();
+
+ void scale(in float sx, in float sy);
+ void rotate(in float angle);
+ void translate(in float tx, in float ty);
+ void transform(in float m11, in float m12, in float m21, in float m22, in float dx, in float dy);
+ void setTransform(in float m11, in float m12, in float m21, in float m22, in float dx, in float dy);
+
+ attribute float globalAlpha;
+ attribute [ConvertNullToNullString] DOMString globalCompositeOperation;
+
+ CanvasGradient createLinearGradient(in float x0, in float y0, in float x1, in float y1)
+ raises (DOMException);
+ CanvasGradient createRadialGradient(in float x0, in float y0, in float r0, in float x1, in float y1, in float r1)
+ raises (DOMException);
+
+ attribute float lineWidth;
+ attribute [ConvertNullToNullString] DOMString lineCap;
+ attribute [ConvertNullToNullString] DOMString lineJoin;
+ attribute float miterLimit;
+
+ attribute float shadowOffsetX;
+ attribute float shadowOffsetY;
+ attribute float shadowBlur;
+ attribute [ConvertNullToNullString] DOMString shadowColor;
+
+ void clearRect(in float x, in float y, in float width, in float height);
+ void fillRect(in float x, in float y, in float width, in float height);
+
+ void beginPath();
+ void closePath();
+ void moveTo(in float x, in float y);
+ void lineTo(in float x, in float y);
+ void quadraticCurveTo(in float cpx, in float cpy, in float x, in float y);
+ void bezierCurveTo(in float cp1x, in float cp1y, in float cp2x, in float cp2y, in float x, in float y);
+ void arcTo(in float x1, in float y1, in float x2, in float y2, in float radius)
+ raises (DOMException);
+ void rect(in float x, in float y, in float width, in float height);
+ void arc(in float x, in float y, in float radius, in float startAngle, in float endAngle, in boolean anticlockwise)
+ raises (DOMException);
+ void fill();
+ void stroke();
+ void clip();
+ boolean isPointInPath(in float x, in float y);
+
+ // text
+ attribute DOMString font;
+ attribute DOMString textAlign;
+ attribute DOMString textBaseline;
+
+ TextMetrics measureText(in DOMString text);
+
+ // other
+
+ void setAlpha(in float alpha);
+ void setCompositeOperation(in DOMString compositeOperation);
+
+#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
+ void setLineWidth(in float width);
+ void setLineCap(in DOMString cap);
+ void setLineJoin(in DOMString join);
+ void setMiterLimit(in float limit);
+#endif
+
+ void clearShadow();
+
+#if defined(V8_BINDING) && V8_BINDING
+ void fillText(in DOMString text, in float x, in float y, in [Optional] float maxWidth);
+ void strokeText(in DOMString text, in float x, in float y, in [Optional] float maxWidth);
+
+ void setStrokeColor(in DOMString color, in [Optional] float alpha);
+ void setStrokeColor(in float grayLevel, in [Optional] float alpha);
+ void setStrokeColor(in float r, in float g, in float b, in float a);
+ void setStrokeColor(in float c, in float m, in float y, in float k, in float a);
+
+ void setFillColor(in DOMString color, in [Optional] float alpha);
+ void setFillColor(in float grayLevel, in [Optional] float alpha);
+ void setFillColor(in float r, in float g, in float b, in float a);
+ void setFillColor(in float c, in float m, in float y, in float k, in float a);
+
+ void strokeRect(in float x, in float y, in float width, in float height, in [Optional] float lineWidth);
+
+ void drawImage(in HTMLImageElement image, in float x, in float y)
+ raises (DOMException);
+ void drawImage(in HTMLImageElement image, in float x, in float y, in float width, in float height)
+ raises (DOMException);
+ void drawImage(in HTMLImageElement image, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh)
+ raises (DOMException);
+ void drawImage(in HTMLCanvasElement canvas, in float x, in float y)
+ raises (DOMException);
+ void drawImage(in HTMLCanvasElement canvas, in float x, in float y, in float width, in float height)
+ raises (DOMException);
+ void drawImage(in HTMLCanvasElement canvas, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh)
+ raises (DOMException);
+#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
+ void drawImage(in HTMLVideoElement video, in float x, in float y)
+ raises (DOMException);
+ void drawImage(in HTMLVideoElement video, in float x, in float y, in float width, in float height)
+ raises (DOMException);
+ void drawImage(in HTMLVideoElement video, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh)
+ raises (DOMException);
+#endif
+ void drawImageFromRect(in HTMLImageElement image,
+ in float sx, in float sy, in float sw, in float sh,
+ in float dx, in float dy, in float dw, in float dh, in DOMString compositeOperation);
+
+ void setShadow(in float width, in float height, in float blur, in [Optional] DOMString color, in [Optional] float alpha);
+ void setShadow(in float width, in float height, in float blur, in float grayLevel, in [Optional] float alpha);
+ void setShadow(in float width, in float height, in float blur, in float r, in float g, in float b, in float a);
+ void setShadow(in float width, in float height, in float blur, in float c, in float m, in float y, in float k, in float a);
+
+ CanvasPattern createPattern(in HTMLCanvasElement canvas, in [ConvertNullToNullString] DOMString repetitionType)
+ raises (DOMException);
+ CanvasPattern createPattern(in HTMLImageElement image, in [ConvertNullToNullString] DOMString repetitionType)
+ raises (DOMException);
+ void putImageData(in ImageData imagedata, in float dx, in float dy, in [Optional] float dirtyX, in float dirtyY, in float dirtyWidth, in float dirtyHeight)
+ raises(DOMException);
+ ImageData createImageData(in ImageData imagedata)
+ raises (DOMException);
+ ImageData createImageData(in float sw, in float sh)
+ raises (DOMException);
+#else
+ // FIXME: Remove 'else' once JSC supports overloads too.
+ [Custom] void fillText(/* 4 */);
+ [Custom] void strokeText(/* 4 */);
+ [Custom] void setStrokeColor(/* 1 */);
+ [Custom] void setFillColor(/* 1 */);
+ [Custom] void strokeRect(/* 4 */);
+ [Custom] void drawImage(/* 3 */);
+ [Custom] void drawImageFromRect(/* 10 */);
+ [Custom] void setShadow(/* 3 */);
+ [Custom] void createPattern(/* 2 */);
+ [Custom] void putImageData(/* in ImageData imagedata, in float dx, in float dy [, in float dirtyX, in float dirtyY, in float dirtyWidth, in float dirtyHeight] */);
+ [Custom] ImageData createImageData(/* 3 */);
+#endif // defined(V8_BINDING)
+
+ attribute [Custom] custom strokeStyle;
+ attribute [Custom] custom fillStyle;
+
+ // pixel manipulation
+ ImageData getImageData(in float sx, in float sy, in float sw, in float sh)
+ raises(DOMException);
+ };
+
+}
+
diff --git a/Source/WebCore/html/canvas/CanvasStyle.cpp b/Source/WebCore/html/canvas/CanvasStyle.cpp
new file mode 100644
index 0000000..a4e87e3
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasStyle.cpp
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ *
+ * 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"
+#include "CanvasStyle.h"
+
+#include "CSSParser.h"
+#include "CSSPropertyNames.h"
+#include "CanvasGradient.h"
+#include "CanvasPattern.h"
+#include "GraphicsContext.h"
+#include "HTMLCanvasElement.h"
+#include <wtf/Assertions.h>
+#include <wtf/PassRefPtr.h>
+
+#if PLATFORM(CG)
+#include <CoreGraphics/CGContext.h>
+#endif
+
+#if PLATFORM(QT)
+#include <QPainter>
+#include <QBrush>
+#include <QPen>
+#include <QColor>
+#endif
+
+namespace WebCore {
+
+enum ColorParseResult { ParsedRGBA, ParsedCurrentColor, ParseFailed };
+
+static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString)
+{
+ if (equalIgnoringCase(colorString, "currentcolor"))
+ return ParsedCurrentColor;
+ if (CSSParser::parseColor(parsedColor, colorString))
+ return ParsedRGBA;
+ return ParseFailed;
+}
+
+RGBA32 currentColor(HTMLCanvasElement* canvas)
+{
+ if (!canvas || !canvas->inDocument())
+ return Color::black;
+ RGBA32 rgba = Color::black;
+ CSSParser::parseColor(rgba, canvas->style()->getPropertyValue(CSSPropertyColor));
+ return rgba;
+}
+
+bool parseColorOrCurrentColor(RGBA32& parsedColor, const String& colorString, HTMLCanvasElement* canvas)
+{
+ ColorParseResult parseResult = parseColor(parsedColor, colorString);
+ switch (parseResult) {
+ case ParsedRGBA:
+ return true;
+ case ParsedCurrentColor:
+ parsedColor = currentColor(canvas);
+ return true;
+ case ParseFailed:
+ return false;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+}
+
+CanvasStyle::CanvasStyle(Type type, float overrideAlpha)
+ : m_type(type)
+ , m_overrideAlpha(overrideAlpha)
+{
+}
+
+CanvasStyle::CanvasStyle(RGBA32 rgba)
+ : m_type(RGBA)
+ , m_rgba(rgba)
+{
+}
+
+CanvasStyle::CanvasStyle(float grayLevel, float alpha)
+ : m_type(RGBA)
+ , m_rgba(makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, alpha))
+{
+}
+
+CanvasStyle::CanvasStyle(float r, float g, float b, float a)
+ : m_type(RGBA)
+ , m_rgba(makeRGBA32FromFloats(r, g, b, a))
+{
+}
+
+CanvasStyle::CanvasStyle(float c, float m, float y, float k, float a)
+ : m_type(CMYKA)
+ , m_rgba(makeRGBAFromCMYKA(c, m, y, k, a))
+ , m_cmyka(c, m, y, k, a)
+{
+}
+
+CanvasStyle::CanvasStyle(PassRefPtr<CanvasGradient> gradient)
+ : m_type(Gradient)
+ , m_gradient(gradient)
+{
+}
+
+CanvasStyle::CanvasStyle(PassRefPtr<CanvasPattern> pattern)
+ : m_type(ImagePattern)
+ , m_pattern(pattern)
+{
+}
+
+PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color)
+{
+ RGBA32 rgba;
+ ColorParseResult parseResult = parseColor(rgba, color);
+ switch (parseResult) {
+ case ParsedRGBA:
+ return adoptRef(new CanvasStyle(rgba));
+ case ParsedCurrentColor:
+ return adoptRef(new CanvasStyle(CurrentColor));
+ case ParseFailed:
+ return 0;
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+}
+
+PassRefPtr<CanvasStyle> CanvasStyle::createFromStringWithOverrideAlpha(const String& color, float alpha)
+{
+ RGBA32 rgba;
+ ColorParseResult parseResult = parseColor(rgba, color);
+ switch (parseResult) {
+ case ParsedRGBA:
+ return adoptRef(new CanvasStyle(colorWithOverrideAlpha(rgba, alpha)));
+ case ParsedCurrentColor:
+ return adoptRef(new CanvasStyle(CurrentColorWithOverrideAlpha, alpha));
+ case ParseFailed:
+ return 0;
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+}
+
+PassRefPtr<CanvasStyle> CanvasStyle::createFromGradient(PassRefPtr<CanvasGradient> gradient)
+{
+ if (!gradient)
+ return 0;
+ return adoptRef(new CanvasStyle(gradient));
+}
+PassRefPtr<CanvasStyle> CanvasStyle::createFromPattern(PassRefPtr<CanvasPattern> pattern)
+{
+ if (!pattern)
+ return 0;
+ return adoptRef(new CanvasStyle(pattern));
+}
+
+bool CanvasStyle::isEquivalentColor(const CanvasStyle& other) const
+{
+ if (m_type != other.m_type)
+ return false;
+
+ switch (m_type) {
+ case RGBA:
+ return m_rgba == other.m_rgba;
+ case CMYKA:
+ return m_cmyka.c == other.m_cmyka.c
+ && m_cmyka.m == other.m_cmyka.m
+ && m_cmyka.y == other.m_cmyka.y
+ && m_cmyka.k == other.m_cmyka.k
+ && m_cmyka.a == other.m_cmyka.a;
+ case Gradient:
+ case ImagePattern:
+ case CurrentColor:
+ case CurrentColorWithOverrideAlpha:
+ return false;
+ }
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+bool CanvasStyle::isEquivalentRGBA(float r, float g, float b, float a) const
+{
+ if (m_type != RGBA)
+ return false;
+
+ return m_rgba == makeRGBA32FromFloats(r, g, b, a);
+}
+
+bool CanvasStyle::isEquivalentCMYKA(float c, float m, float y, float k, float a) const
+{
+ if (m_type != CMYKA)
+ return false;
+
+ return c == m_cmyka.c
+ && m == m_cmyka.m
+ && y == m_cmyka.y
+ && k == m_cmyka.k
+ && a == m_cmyka.a;
+}
+
+void CanvasStyle::applyStrokeColor(GraphicsContext* context)
+{
+ if (!context)
+ return;
+ switch (m_type) {
+ case RGBA:
+ context->setStrokeColor(m_rgba, ColorSpaceDeviceRGB);
+ break;
+ case CMYKA: {
+ // FIXME: Do this through platform-independent GraphicsContext API.
+ // We'll need a fancier Color abstraction to support CMYKA correctly
+#if PLATFORM(CG)
+ CGContextSetCMYKStrokeColor(context->platformContext(), m_cmyka.c, m_cmyka.m, m_cmyka.y, m_cmyka.k, m_cmyka.a);
+#elif PLATFORM(QT)
+ QPen currentPen = context->platformContext()->pen();
+ QColor clr;
+ clr.setCmykF(m_cmyka.c, m_cmyka.m, m_cmyka.y, m_cmyka.k, m_cmyka.a);
+ currentPen.setColor(clr);
+ context->platformContext()->setPen(currentPen);
+#else
+ context->setStrokeColor(m_rgba, ColorSpaceDeviceRGB);
+#endif
+ break;
+ }
+ case Gradient:
+ context->setStrokeGradient(canvasGradient()->gradient());
+ break;
+ case ImagePattern:
+ context->setStrokePattern(canvasPattern()->pattern());
+ break;
+ case CurrentColor:
+ case CurrentColorWithOverrideAlpha:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void CanvasStyle::applyFillColor(GraphicsContext* context)
+{
+ if (!context)
+ return;
+ switch (m_type) {
+ case RGBA:
+ context->setFillColor(m_rgba, ColorSpaceDeviceRGB);
+ break;
+ case CMYKA: {
+ // FIXME: Do this through platform-independent GraphicsContext API.
+ // We'll need a fancier Color abstraction to support CMYKA correctly
+#if PLATFORM(CG)
+ CGContextSetCMYKFillColor(context->platformContext(), m_cmyka.c, m_cmyka.m, m_cmyka.y, m_cmyka.k, m_cmyka.a);
+#elif PLATFORM(QT)
+ QBrush currentBrush = context->platformContext()->brush();
+ QColor clr;
+ clr.setCmykF(m_cmyka.c, m_cmyka.m, m_cmyka.y, m_cmyka.k, m_cmyka.a);
+ currentBrush.setColor(clr);
+ context->platformContext()->setBrush(currentBrush);
+#else
+ context->setFillColor(m_rgba, ColorSpaceDeviceRGB);
+#endif
+ break;
+ }
+ case Gradient:
+ context->setFillGradient(canvasGradient()->gradient());
+ break;
+ case ImagePattern:
+ context->setFillPattern(canvasPattern()->pattern());
+ break;
+ case CurrentColor:
+ case CurrentColorWithOverrideAlpha:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+}
diff --git a/Source/WebCore/html/canvas/CanvasStyle.h b/Source/WebCore/html/canvas/CanvasStyle.h
new file mode 100644
index 0000000..91dc923
--- /dev/null
+++ b/Source/WebCore/html/canvas/CanvasStyle.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 CanvasStyle_h
+#define CanvasStyle_h
+
+#include "Color.h"
+#include "PlatformString.h"
+#include <wtf/Assertions.h>
+
+namespace WebCore {
+
+ class CanvasGradient;
+ class CanvasPattern;
+ class GraphicsContext;
+ class HTMLCanvasElement;
+
+ class CanvasStyle : public RefCounted<CanvasStyle> {
+ public:
+ static PassRefPtr<CanvasStyle> createFromRGBA(RGBA32 rgba) { return adoptRef(new CanvasStyle(rgba)); }
+ static PassRefPtr<CanvasStyle> createFromString(const String& color);
+ static PassRefPtr<CanvasStyle> createFromStringWithOverrideAlpha(const String& color, float alpha);
+ static PassRefPtr<CanvasStyle> createFromGrayLevelWithAlpha(float grayLevel, float alpha) { return adoptRef(new CanvasStyle(grayLevel, alpha)); }
+ static PassRefPtr<CanvasStyle> createFromRGBAChannels(float r, float g, float b, float a) { return adoptRef(new CanvasStyle(r, g, b, a)); }
+ static PassRefPtr<CanvasStyle> createFromCMYKAChannels(float c, float m, float y, float k, float a) { return adoptRef(new CanvasStyle(c, m, y, k, a)); }
+ static PassRefPtr<CanvasStyle> createFromGradient(PassRefPtr<CanvasGradient>);
+ static PassRefPtr<CanvasStyle> createFromPattern(PassRefPtr<CanvasPattern>);
+
+ bool isCurrentColor() const { return m_type == CurrentColor || m_type == CurrentColorWithOverrideAlpha; }
+ bool hasOverrideAlpha() const { return m_type == CurrentColorWithOverrideAlpha; }
+ float overrideAlpha() const { ASSERT(m_type == CurrentColorWithOverrideAlpha); return m_overrideAlpha; }
+
+ String color() const { ASSERT(m_type == RGBA || m_type == CMYKA); return Color(m_rgba).serialized(); }
+ CanvasGradient* canvasGradient() const { return m_gradient.get(); }
+ CanvasPattern* canvasPattern() const { return m_pattern.get(); }
+
+ void applyFillColor(GraphicsContext*);
+ void applyStrokeColor(GraphicsContext*);
+
+ bool isEquivalentColor(const CanvasStyle&) const;
+ bool isEquivalentRGBA(float r, float g, float b, float a) const;
+ bool isEquivalentCMYKA(float c, float m, float y, float k, float a) const;
+
+ private:
+ enum Type { RGBA, CMYKA, Gradient, ImagePattern, CurrentColor, CurrentColorWithOverrideAlpha };
+
+ CanvasStyle(Type, float overrideAlpha = 0);
+ CanvasStyle(RGBA32 rgba);
+ CanvasStyle(float grayLevel, float alpha);
+ CanvasStyle(float r, float g, float b, float a);
+ CanvasStyle(float c, float m, float y, float k, float a);
+ CanvasStyle(PassRefPtr<CanvasGradient>);
+ CanvasStyle(PassRefPtr<CanvasPattern>);
+
+ Type m_type;
+
+ union {
+ RGBA32 m_rgba;
+ float m_overrideAlpha;
+ };
+
+ RefPtr<CanvasGradient> m_gradient;
+ RefPtr<CanvasPattern> m_pattern;
+
+ struct CMYKAValues {
+ CMYKAValues() {}
+ CMYKAValues(float cyan, float magenta, float yellow, float black, float alpha) : c(cyan), m(magenta), y(yellow), k(black), a(alpha) {}
+ float c;
+ float m;
+ float y;
+ float k;
+ float a;
+ } m_cmyka;
+ };
+
+ RGBA32 currentColor(HTMLCanvasElement*);
+ bool parseColorOrCurrentColor(RGBA32& parsedColor, const String& colorString, HTMLCanvasElement*);
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/canvas/CheckedInt.h b/Source/WebCore/html/canvas/CheckedInt.h
new file mode 100644
index 0000000..861e8e6
--- /dev/null
+++ b/Source/WebCore/html/canvas/CheckedInt.h
@@ -0,0 +1,527 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla code.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Benoit Jacob <bjacob@mozilla.com>
+ * Jeff Muizelaar <jmuizelaar@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Necessary modifications are made to the original CheckedInt.h file to remove
+// dependencies on prtypes.
+// Also, change define Mozilla_CheckedInt_h to CheckedInt_h, change namespace
+// from mozilla to WebCore for easier usage.
+
+#ifndef CheckedInt_h
+#define CheckedInt_h
+
+#include <climits>
+
+namespace WebCore {
+
+namespace CheckedInt_internal {
+
+/* we don't want to use std::numeric_limits here because int... types may not support it,
+ * depending on the platform, e.g. on certain platform they use nonstandard built-in types
+ */
+
+/*** Step 1: manually record information for all the types that we want to support
+ ***/
+
+struct unsupported_type {};
+
+template<typename T> struct integer_type_manually_recorded_info
+{
+ enum { is_supported = 0 };
+ typedef unsupported_type twice_bigger_type;
+};
+
+
+#define CHECKEDINT_REGISTER_SUPPORTED_TYPE(T,_twice_bigger_type) \
+template<> struct integer_type_manually_recorded_info<T> \
+{ \
+ enum { is_supported = 1 }; \
+ typedef _twice_bigger_type twice_bigger_type; \
+ static void TYPE_NOT_SUPPORTED_BY_CheckedInt() {} \
+};
+
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(int8_t, int16_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(uint8_t, uint16_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(int16_t, int32_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(uint16_t, uint32_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(int32_t, int64_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(uint32_t, uint64_t)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(int64_t, unsupported_type)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(uint64_t, unsupported_type)
+
+
+/*** Step 2: record some info about a given integer type,
+ *** including whether it is supported, whether a twice bigger integer type
+ *** is supported, what that twice bigger type is, and some stuff as found
+ *** in std::numeric_limits (which we don't use because int.. types may
+ *** not support it, if they are defined directly from compiler built-in types).
+ ***/
+
+template<typename T> struct is_unsupported_type { enum { answer = 0 }; };
+template<> struct is_unsupported_type<unsupported_type> { enum { answer = 1 }; };
+
+template<typename T> struct integer_traits
+{
+ typedef typename integer_type_manually_recorded_info<T>::twice_bigger_type twice_bigger_type;
+
+ enum {
+ is_supported = integer_type_manually_recorded_info<T>::is_supported,
+ twice_bigger_type_is_supported
+ = is_unsupported_type<
+ typename integer_type_manually_recorded_info<T>::twice_bigger_type
+ >::answer ? 0 : 1,
+ size = sizeof(T),
+ position_of_sign_bit = CHAR_BIT * size - 1,
+ is_signed = (T(-1) > T(0)) ? 0 : 1
+ };
+
+ static T min()
+ {
+ // bitwise ops may return a larger type, that's why we cast explicitly to T
+ return is_signed ? T(T(1) << position_of_sign_bit) : T(0);
+ }
+
+ static T max()
+ {
+ return ~min();
+ }
+};
+
+/*** Step 3: Implement the actual validity checks --- ideas taken from IntegerLib, code different.
+ ***/
+
+// bitwise ops may return a larger type, so it's good to use these inline helpers guaranteeing that
+// the result is really of type T
+
+template<typename T> inline T has_sign_bit(T x)
+{
+ return x >> integer_traits<T>::position_of_sign_bit;
+}
+
+template<typename T> inline T binary_complement(T x)
+{
+ return ~x;
+}
+
+template<typename T, typename U,
+ bool is_T_signed = integer_traits<T>::is_signed,
+ bool is_U_signed = integer_traits<U>::is_signed>
+struct is_in_range_impl {};
+
+template<typename T, typename U>
+struct is_in_range_impl<T, U, true, true>
+{
+ static T run(U x)
+ {
+ return (x <= integer_traits<T>::max()) &
+ (x >= integer_traits<T>::min());
+ }
+};
+
+template<typename T, typename U>
+struct is_in_range_impl<T, U, false, false>
+{
+ static T run(U x)
+ {
+ return x <= integer_traits<T>::max();
+ }
+};
+
+template<typename T, typename U>
+struct is_in_range_impl<T, U, true, false>
+{
+ static T run(U x)
+ {
+ if (sizeof(T) > sizeof(U))
+ return 1;
+ else
+ return x <= U(integer_traits<T>::max());
+ }
+};
+
+template<typename T, typename U>
+struct is_in_range_impl<T, U, false, true>
+{
+ static T run(U x)
+ {
+ if (sizeof(T) >= sizeof(U))
+ return x >= 0;
+ else
+ return x >= 0 && x <= U(integer_traits<T>::max());
+ }
+};
+
+template<typename T, typename U> inline T is_in_range(U x)
+{
+ return is_in_range_impl<T, U>::run(x);
+}
+
+template<typename T> inline T is_add_valid(T x, T y, T result)
+{
+ return integer_traits<T>::is_signed ?
+ // addition is valid if the sign of x+y is equal to either that of x or that of y.
+ // Beware! These bitwise operations can return a larger integer type, if T was a
+ // small type like int8, so we explicitly cast to T.
+ has_sign_bit(binary_complement(T((result^x) & (result^y))))
+ :
+ binary_complement(x) >= y;
+}
+
+template<typename T> inline T is_sub_valid(T x, T y, T result)
+{
+ return integer_traits<T>::is_signed ?
+ // substraction is valid if either x and y have same sign, or x-y and x have same sign
+ has_sign_bit(binary_complement(T((result^x) & (x^y))))
+ :
+ x >= y;
+}
+
+template<typename T,
+ bool is_signed = integer_traits<T>::is_signed,
+ bool twice_bigger_type_is_supported = integer_traits<T>::twice_bigger_type_is_supported>
+struct is_mul_valid_impl {};
+
+template<typename T>
+struct is_mul_valid_impl<T, true, true>
+{
+ static T run(T x, T y)
+ {
+ typedef typename integer_traits<T>::twice_bigger_type twice_bigger_type;
+ twice_bigger_type product = twice_bigger_type(x) * twice_bigger_type(y);
+ return is_in_range<T>(product);
+ }
+};
+
+template<typename T>
+struct is_mul_valid_impl<T, false, true>
+{
+ static T run(T x, T y)
+ {
+ typedef typename integer_traits<T>::twice_bigger_type twice_bigger_type;
+ twice_bigger_type product = twice_bigger_type(x) * twice_bigger_type(y);
+ return is_in_range<T>(product);
+ }
+};
+
+template<typename T>
+struct is_mul_valid_impl<T, true, false>
+{
+ static T run(T x, T y)
+ {
+ const T max_value = integer_traits<T>::max();
+ const T min_value = integer_traits<T>::min();
+
+ if (x == 0 || y == 0) return true;
+
+ if (x > 0) {
+ if (y > 0)
+ return x <= max_value / y;
+ else
+ return y >= min_value / x;
+ } else {
+ if (y > 0)
+ return x >= min_value / y;
+ else
+ return y >= max_value / x;
+ }
+ }
+};
+
+template<typename T>
+struct is_mul_valid_impl<T, false, false>
+{
+ static T run(T x, T y)
+ {
+ const T max_value = integer_traits<T>::max();
+ if (x == 0 || y == 0) return true;
+ return x <= max_value / y;
+ }
+};
+
+template<typename T> inline T is_mul_valid(T x, T y, T /*result not used*/)
+{
+ return is_mul_valid_impl<T>::run(x, y);
+}
+
+template<typename T> inline T is_div_valid(T x, T y)
+{
+ return integer_traits<T>::is_signed ?
+ // keep in mind that min/-1 is invalid because abs(min)>max
+ y != 0 && (x != integer_traits<T>::min() || y != T(-1))
+ :
+ y != 0;
+}
+
+} // end namespace CheckedInt_internal
+
+
+/*** Step 4: Now define the CheckedInt class.
+ ***/
+
+/** \class CheckedInt
+ * \brief Integer wrapper class checking for integer overflow and other errors
+ * \param T the integer type to wrap. Can be any of int8_t, uint8_t, int16_t, uint16_t,
+ * int32_t, uint32_t, int64_t, uint64_t.
+ *
+ * This class implements guarded integer arithmetic. Do a computation, then check that
+ * valid() returns true, you then have a guarantee that no problem, such as integer overflow,
+ * happened during this computation.
+ *
+ * The arithmetic operators in this class are guaranteed not to crash your app
+ * in case of a division by zero.
+ *
+ * For example, suppose that you want to implement a function that computes (x+y)/z,
+ * that doesn't crash if z==0, and that reports on error (divide by zero or integer overflow).
+ * You could code it as follows:
+ \code
+ bool compute_x_plus_y_over_z(int32_t x, int32_t y, int32_t z, int32_t *result)
+ {
+ CheckedInt<int32_t> checked_result = (CheckedInt<int32_t>(x) + y) / z;
+ *result = checked_result.value();
+ return checked_result.valid();
+ }
+ \endcode
+ *
+ * Implicit conversion from plain integers to checked integers is allowed. The plain integer
+ * is checked to be in range before being casted to the destination type. This means that the following
+ * lines all compile, and the resulting CheckedInts are correctly detected as valid or invalid:
+ * \code
+ CheckedInt<uint8_t> x(1); // 1 is of type int, is found to be in range for uint8_t, x is valid
+ CheckedInt<uint8_t> x(-1); // -1 is of type int, is found not to be in range for uint8_t, x is invalid
+ CheckedInt<int8_t> x(-1); // -1 is of type int, is found to be in range for int8_t, x is valid
+ CheckedInt<int8_t> x(int16_t(1000)); // 1000 is of type int16_t, is found not to be in range for int8_t, x is invalid
+ CheckedInt<int32_t> x(uint32_t(123456789)); // 3123456789 is of type uint32_t, is found not to be in range
+ // for int32_t, x is invalid
+ * \endcode
+ * Implicit conversion from
+ * checked integers to plain integers is not allowed. As shown in the
+ * above example, to get the value of a checked integer as a normal integer, call value().
+ *
+ * Arithmetic operations between checked and plain integers is allowed; the result type
+ * is the type of the checked integer.
+ *
+ * Safe integers of different types cannot be used in the same arithmetic expression.
+ */
+template<typename T>
+class CheckedInt
+{
+protected:
+ T mValue;
+ T mIsValid; // stored as a T to limit the number of integer conversions when
+ // evaluating nested arithmetic expressions.
+
+ template<typename U>
+ CheckedInt(const U& value, bool isValid) : mValue(value), mIsValid(isValid)
+ {
+ CheckedInt_internal::integer_type_manually_recorded_info<T>
+ ::TYPE_NOT_SUPPORTED_BY_CheckedInt();
+ }
+
+public:
+ /** Constructs a checked integer with given \a value. The checked integer is initialized as valid or invalid
+ * depending on whether the \a value is in range.
+ *
+ * This constructor is not explicit. Instead, the type of its argument is a separate template parameter,
+ * ensuring that no conversion is performed before this constructor is actually called.
+ * As explained in the above documentation for class CheckedInt, this constructor checks that its argument is
+ * valid.
+ */
+ template<typename U>
+ CheckedInt(const U& value)
+ : mValue(value),
+ mIsValid(CheckedInt_internal::is_in_range<T>(value))
+ {
+ CheckedInt_internal::integer_type_manually_recorded_info<T>
+ ::TYPE_NOT_SUPPORTED_BY_CheckedInt();
+ }
+
+ /** Constructs a valid checked integer with uninitialized value */
+ CheckedInt() : mIsValid(1)
+ {
+ CheckedInt_internal::integer_type_manually_recorded_info<T>
+ ::TYPE_NOT_SUPPORTED_BY_CheckedInt();
+ }
+
+ /** \returns the actual value */
+ T value() const { return mValue; }
+
+ /** \returns true if the checked integer is valid, i.e. is not the result
+ * of an invalid operation or of an operation involving an invalid checked integer
+ */
+ bool valid() const { return mIsValid; }
+
+ /** \returns the sum. Checks for overflow. */
+ template<typename U> friend CheckedInt<U> operator +(const CheckedInt<U>& lhs, const CheckedInt<U>& rhs);
+ /** Adds. Checks for overflow. \returns self reference */
+ template<typename U> CheckedInt& operator +=(const U &rhs);
+ /** \returns the difference. Checks for overflow. */
+ template<typename U> friend CheckedInt<U> operator -(const CheckedInt<U>& lhs, const CheckedInt<U> &rhs);
+ /** Substracts. Checks for overflow. \returns self reference */
+ template<typename U> CheckedInt& operator -=(const U &rhs);
+ /** \returns the product. Checks for overflow. */
+ template<typename U> friend CheckedInt<U> operator *(const CheckedInt<U>& lhs, const CheckedInt<U> &rhs);
+ /** Multiplies. Checks for overflow. \returns self reference */
+ template<typename U> CheckedInt& operator *=(const U &rhs);
+ /** \returns the quotient. Checks for overflow and for divide-by-zero. */
+ template<typename U> friend CheckedInt<U> operator /(const CheckedInt<U>& lhs, const CheckedInt<U> &rhs);
+ /** Divides. Checks for overflow and for divide-by-zero. \returns self reference */
+ template<typename U> CheckedInt& operator /=(const U &rhs);
+
+ /** \returns the opposite value. Checks for overflow. */
+ CheckedInt operator -() const
+ {
+ T result = -value();
+ /* give the compiler a good chance to perform RVO */
+ return CheckedInt(result,
+ mIsValid & CheckedInt_internal::is_sub_valid(T(0), value(), result));
+ }
+
+ /** \returns true if the left and right hand sides are valid and have the same value. */
+ bool operator ==(const CheckedInt& other) const
+ {
+ return bool(mIsValid & other.mIsValid & T(value() == other.value()));
+ }
+
+private:
+ /** operator!= is disabled. Indeed: (a!=b) should be the same as !(a==b) but that
+ * would mean that if a or b is invalid, (a!=b) is always true, which is very tricky.
+ */
+ template<typename U>
+ bool operator !=(const U& other) const { return !(*this == other); }
+};
+
+#define CHECKEDINT_BASIC_BINARY_OPERATOR(NAME, OP) \
+template<typename T> \
+inline CheckedInt<T> operator OP(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs) \
+{ \
+ T x = lhs.value(); \
+ T y = rhs.value(); \
+ T result = x OP y; \
+ T is_op_valid \
+ = CheckedInt_internal::is_##NAME##_valid(x, y, result); \
+ /* give the compiler a good chance to perform RVO */ \
+ return CheckedInt<T>(result, \
+ lhs.mIsValid & \
+ rhs.mIsValid & \
+ is_op_valid); \
+}
+
+CHECKEDINT_BASIC_BINARY_OPERATOR(add, +)
+CHECKEDINT_BASIC_BINARY_OPERATOR(sub, -)
+CHECKEDINT_BASIC_BINARY_OPERATOR(mul, *)
+
+// division can't be implemented by CHECKEDINT_BASIC_BINARY_OPERATOR
+// because if rhs == 0, we are not allowed to even try to compute the quotient.
+template<typename T>
+inline CheckedInt<T> operator /(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs)
+{
+ T x = lhs.value();
+ T y = rhs.value();
+ T is_op_valid = CheckedInt_internal::is_div_valid(x, y);
+ T result = is_op_valid ? (x / y) : 0;
+ /* give the compiler a good chance to perform RVO */
+ return CheckedInt<T>(result,
+ lhs.mIsValid &
+ rhs.mIsValid &
+ is_op_valid);
+}
+
+// implement cast_to_CheckedInt<T>(x), making sure that
+// - it allows x to be either a CheckedInt<T> or any integer type that can be casted to T
+// - if x is already a CheckedInt<T>, we just return a reference to it, instead of copying it (optimization)
+
+template<typename T, typename U>
+struct cast_to_CheckedInt_impl
+{
+ typedef CheckedInt<T> return_type;
+ static CheckedInt<T> run(const U& u) { return u; }
+};
+
+template<typename T>
+struct cast_to_CheckedInt_impl<T, CheckedInt<T> >
+{
+ typedef const CheckedInt<T>& return_type;
+ static const CheckedInt<T>& run(const CheckedInt<T>& u) { return u; }
+};
+
+template<typename T, typename U>
+inline typename cast_to_CheckedInt_impl<T, U>::return_type
+cast_to_CheckedInt(const U& u)
+{
+ return cast_to_CheckedInt_impl<T, U>::run(u);
+}
+
+#define CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(OP, COMPOUND_OP) \
+template<typename T> \
+template<typename U> \
+CheckedInt<T>& CheckedInt<T>::operator COMPOUND_OP(const U &rhs) \
+{ \
+ *this = *this OP cast_to_CheckedInt<T>(rhs); \
+ return *this; \
+} \
+template<typename T, typename U> \
+inline CheckedInt<T> operator OP(const CheckedInt<T> &lhs, const U &rhs) \
+{ \
+ return lhs OP cast_to_CheckedInt<T>(rhs); \
+} \
+template<typename T, typename U> \
+inline CheckedInt<T> operator OP(const U & lhs, const CheckedInt<T> &rhs) \
+{ \
+ return cast_to_CheckedInt<T>(lhs) OP rhs; \
+}
+
+CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=)
+CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=)
+CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=)
+CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=)
+
+template<typename T, typename U>
+inline bool operator ==(const CheckedInt<T> &lhs, const U &rhs)
+{
+ return lhs == cast_to_CheckedInt<T>(rhs);
+}
+
+template<typename T, typename U>
+inline bool operator ==(const U & lhs, const CheckedInt<T> &rhs)
+{
+ return cast_to_CheckedInt<T>(lhs) == rhs;
+}
+
+} // end namespace WebCore
+
+#endif /* CheckedInt_h */
diff --git a/Source/WebCore/html/canvas/DataView.cpp b/Source/WebCore/html/canvas/DataView.cpp
new file mode 100755
index 0000000..82b10b3
--- /dev/null
+++ b/Source/WebCore/html/canvas/DataView.cpp
@@ -0,0 +1,235 @@
+/*
+ * 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 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(3D_CANVAS) || ENABLE(BLOB)
+
+#include "DataView.h"
+
+#include "CheckedInt.h"
+
+namespace {
+
+template<typename T>
+union Value {
+ T data;
+ char bytes[sizeof(T)];
+};
+
+}
+
+namespace WebCore {
+
+PassRefPtr<DataView> DataView::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength)
+{
+ if (byteOffset > buffer->byteLength())
+ return 0;
+ CheckedInt<uint32_t> checkedOffset(byteOffset);
+ CheckedInt<uint32_t> checkedLength(byteLength);
+ CheckedInt<uint32_t> checkedMax = checkedOffset + checkedLength;
+ if (!checkedMax.valid() || checkedMax.value() > buffer->byteLength())
+ return 0;
+ return adoptRef(new DataView(buffer, byteOffset, byteLength));
+}
+
+DataView::DataView(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength)
+ : ArrayBufferView(buffer, byteOffset)
+ , m_byteLength(byteLength)
+{
+}
+
+static bool needToFlipBytes(bool littleEndian)
+{
+#if CPU(BIG_ENDIAN)
+ return littleEndian;
+#else
+ return !littleEndian;
+#endif
+}
+
+inline void swapBytes(char* p, char* q)
+{
+ char temp = *p;
+ *p = *q;
+ *q = temp;
+}
+
+static void flipBytesFor16Bits(char* p)
+{
+ swapBytes(p, p + 1);
+}
+
+static void flipBytesFor32Bits(char* p)
+{
+ swapBytes(p, p + 3);
+ swapBytes(p + 1, p + 2);
+}
+
+static void flipBytesFor64Bits(char* p)
+{
+ swapBytes(p, p + 7);
+ swapBytes(p + 1, p + 6);
+ swapBytes(p + 2, p + 5);
+ swapBytes(p + 3, p + 4);
+}
+
+static void flipBytesIfNeeded(char* value, size_t size, bool littleEndian)
+{
+ if (!needToFlipBytes(littleEndian))
+ return;
+
+ switch (size) {
+ case 1:
+ // Nothing to do.
+ break;
+ case 2:
+ flipBytesFor16Bits(value);
+ break;
+ case 4:
+ flipBytesFor32Bits(value);
+ break;
+ case 8:
+ flipBytesFor64Bits(value);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+template<typename T>
+T DataView::getData(unsigned byteOffset, bool littleEndian, ExceptionCode& ec) const
+{
+ if (beyondRange<T>(byteOffset)) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+
+ // We do not want to load the data directly since it would cause a bus error on architectures that don't support unaligned loads.
+ Value<T> value;
+ memcpy(value.bytes, static_cast<const char*>(m_baseAddress) + byteOffset, sizeof(T));
+ flipBytesIfNeeded(value.bytes, sizeof(T), littleEndian);
+ return value.data;
+}
+
+template<typename T>
+void DataView::setData(unsigned byteOffset, T value, bool littleEndian, ExceptionCode& ec)
+{
+ if (beyondRange<T>(byteOffset)) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ // We do not want to store the data directly since it would cause a bus error on architectures that don't support unaligned stores.
+ Value<T> tempValue;
+ tempValue.data = value;
+ flipBytesIfNeeded(tempValue.bytes, sizeof(T), littleEndian);
+ memcpy(static_cast<char*>(m_baseAddress) + byteOffset, tempValue.bytes, sizeof(T));
+}
+
+int8_t DataView::getInt8(unsigned byteOffset, ExceptionCode& ec)
+{
+ return getData<int8_t>(byteOffset, false, ec);
+}
+
+uint8_t DataView::getUint8(unsigned byteOffset, ExceptionCode& ec)
+{
+ return getData<uint8_t>(byteOffset, false, ec);
+}
+
+int16_t DataView::getInt16(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<int16_t>(byteOffset, littleEndian, ec);
+}
+
+uint16_t DataView::getUint16(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<uint16_t>(byteOffset, littleEndian, ec);
+}
+
+int32_t DataView::getInt32(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<int32_t>(byteOffset, littleEndian, ec);
+}
+
+uint32_t DataView::getUint32(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<uint32_t>(byteOffset, littleEndian, ec);
+}
+
+float DataView::getFloat32(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<float>(byteOffset, littleEndian, ec);
+}
+
+double DataView::getFloat64(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<double>(byteOffset, littleEndian, ec);
+}
+
+void DataView::setInt8(unsigned byteOffset, int8_t value, ExceptionCode& ec)
+{
+ setData<int8_t>(byteOffset, value, false, ec);
+}
+
+void DataView::setUint8(unsigned byteOffset, uint8_t value, ExceptionCode& ec)
+{
+ setData<uint8_t>(byteOffset, value, false, ec);
+}
+
+void DataView::setInt16(unsigned byteOffset, short value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<int16_t>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setUint16(unsigned byteOffset, uint16_t value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<uint16_t>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setInt32(unsigned byteOffset, int32_t value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<int32_t>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setUint32(unsigned byteOffset, uint32_t value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<uint32_t>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setFloat32(unsigned byteOffset, float value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<float>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setFloat64(unsigned byteOffset, double value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<double>(byteOffset, value, littleEndian, ec);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB)
diff --git a/Source/WebCore/html/canvas/DataView.h b/Source/WebCore/html/canvas/DataView.h
new file mode 100755
index 0000000..5707aa3
--- /dev/null
+++ b/Source/WebCore/html/canvas/DataView.h
@@ -0,0 +1,92 @@
+/*
+ * 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 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 DataView_h
+#define DataView_h
+
+#include "ArrayBufferView.h"
+#include "ExceptionCode.h"
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class DataView : public ArrayBufferView {
+public:
+ static PassRefPtr<DataView> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength);
+
+ virtual bool isDataView() const { return true; }
+ virtual unsigned length() const { return m_byteLength; }
+ virtual unsigned byteLength() const { return m_byteLength; }
+ virtual PassRefPtr<ArrayBufferView> slice(int, int) const { return 0; }
+
+ int8_t getInt8(unsigned byteOffset, ExceptionCode&);
+ uint8_t getUint8(unsigned byteOffset, ExceptionCode&);
+ int16_t getInt16(unsigned byteOffset, ExceptionCode& ec) { return getInt16(byteOffset, false, ec); }
+ int16_t getInt16(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ uint16_t getUint16(unsigned byteOffset, ExceptionCode& ec) { return getUint16(byteOffset, false, ec); }
+ uint16_t getUint16(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ int32_t getInt32(unsigned byteOffset, ExceptionCode& ec) { return getInt32(byteOffset, false, ec); }
+ int32_t getInt32(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ uint32_t getUint32(unsigned byteOffset, ExceptionCode& ec) { return getUint32(byteOffset, false, ec); }
+ uint32_t getUint32(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ float getFloat32(unsigned byteOffset, ExceptionCode& ec) { return getFloat32(byteOffset, false, ec); }
+ float getFloat32(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ double getFloat64(unsigned byteOffset, ExceptionCode& ec) { return getFloat64(byteOffset, false, ec); }
+ double getFloat64(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+
+ void setInt8(unsigned byteOffset, int8_t value, ExceptionCode&);
+ void setUint8(unsigned byteOffset, uint8_t value, ExceptionCode&);
+ void setInt16(unsigned byteOffset, int16_t value, ExceptionCode& ec) { setInt16(byteOffset, value, false, ec); }
+ void setInt16(unsigned byteOffset, int16_t value, bool littleEndian, ExceptionCode&);
+ void setUint16(unsigned byteOffset, uint16_t value, ExceptionCode& ec) { setUint16(byteOffset, value, false, ec); }
+ void setUint16(unsigned byteOffset, uint16_t value, bool littleEndian, ExceptionCode&);
+ void setInt32(unsigned byteOffset, int32_t value, ExceptionCode& ec) { setInt32(byteOffset, value, false, ec); }
+ void setInt32(unsigned byteOffset, int32_t value, bool littleEndian, ExceptionCode&);
+ void setUint32(unsigned byteOffset, uint32_t value, ExceptionCode& ec) { setUint32(byteOffset, value, false, ec); }
+ void setUint32(unsigned byteOffset, uint32_t value, bool littleEndian, ExceptionCode&);
+ void setFloat32(unsigned byteOffset, float value, ExceptionCode& ec) { setFloat32(byteOffset, value, false, ec); }
+ void setFloat32(unsigned byteOffset, float value, bool littleEndian, ExceptionCode&);
+ void setFloat64(unsigned byteOffset, double value, ExceptionCode& ec) { setFloat64(byteOffset, value, false, ec); }
+ void setFloat64(unsigned byteOffset, double value, bool littleEndian, ExceptionCode&);
+
+private:
+ DataView(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength);
+
+ template<typename T>
+ inline bool beyondRange(unsigned byteOffset) const { return byteOffset + sizeof(T) > m_byteLength; }
+
+ template<typename T>
+ T getData(unsigned byteOffset, bool littleEndian, ExceptionCode&) const;
+
+ template<typename T>
+ void setData(unsigned byteOffset, T value, bool littleEndian, ExceptionCode&);
+
+ unsigned m_byteLength;
+};
+
+
+} // namespace WebCore
+
+#endif // DataView_h
diff --git a/Source/WebCore/html/canvas/DataView.idl b/Source/WebCore/html/canvas/DataView.idl
new file mode 100755
index 0000000..f99a814
--- /dev/null
+++ b/Source/WebCore/html/canvas/DataView.idl
@@ -0,0 +1,83 @@
+/*
+ * 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 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.
+ */
+
+module html {
+
+ interface [
+ Conditional=3D_CANVAS|BLOB,
+ CanBeConstructed,
+ CustomConstructFunction,
+ CustomToJS,
+ NoStaticTables,
+ V8CustomConstructor
+ ] DataView : ArrayBufferView {
+ // All these methods raise an exception if they would read or write beyond the end of the view.
+
+ // We have to use custom code because our code generator does not support int8_t type.
+ // int8_t getInt8(in unsigned long byteOffset);
+ // uint8_t getUint8(in unsigned long byteOffset);
+ [Custom] DOMObject getInt8()
+ raises (DOMException);
+ [Custom] DOMObject getUint8()
+ raises (DOMException);
+
+ [StrictTypeChecking, RequiresAllArguments=Raise] short getInt16(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] unsigned short getUint16(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] long getInt32(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] unsigned long getUint32(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+
+ // Use custom code to handle NaN case for JSC.
+ [JSCCustom, StrictTypeChecking, RequiresAllArguments=Raise] float getFloat32(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [JSCCustom, StrictTypeChecking, RequiresAllArguments=Raise] double getFloat64(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+
+ // We have to use custom code because our code generator does not support uint8_t type.
+ // void setInt8(in unsigned long byteOffset, in int8_t value);
+ // void setUint8(in unsigned long byteOffset, in uint8_t value);
+ [Custom] void setInt8()
+ raises (DOMException);
+ [Custom] void setUint8()
+ raises (DOMException);
+
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setInt16(in unsigned long byteOffset, in short value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setUint16(in unsigned long byteOffset, in unsigned short value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setInt32(in unsigned long byteOffset, in long value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setUint32(in unsigned long byteOffset, in unsigned long value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setFloat32(in unsigned long byteOffset, in float value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setFloat64(in unsigned long byteOffset, in double value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ };
+
+}
diff --git a/Source/WebCore/html/canvas/Float32Array.cpp b/Source/WebCore/html/canvas/Float32Array.cpp
new file mode 100644
index 0000000..1b26aef
--- /dev/null
+++ b/Source/WebCore/html/canvas/Float32Array.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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(3D_CANVAS) || ENABLE(BLOB)
+
+#include "Float32Array.h"
+
+namespace WebCore {
+
+PassRefPtr<Float32Array> Float32Array::create(unsigned length)
+{
+ return TypedArrayBase<float>::create<Float32Array>(length);
+}
+
+PassRefPtr<Float32Array> Float32Array::create(const float* array, unsigned length)
+{
+ return TypedArrayBase<float>::create<Float32Array>(array, length);
+}
+
+PassRefPtr<Float32Array> Float32Array::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+{
+ return TypedArrayBase<float>::create<Float32Array>(buffer, byteOffset, length);
+}
+
+Float32Array::Float32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+ : TypedArrayBase<float>(buffer, byteOffset, length)
+{
+}
+
+PassRefPtr<Float32Array> Float32Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Float32Array> Float32Array::slice(int start, int end) const
+{
+ return sliceImpl<Float32Array>(start, end);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB)
diff --git a/Source/WebCore/html/canvas/Float32Array.h b/Source/WebCore/html/canvas/Float32Array.h
new file mode 100644
index 0000000..d00a7c5
--- /dev/null
+++ b/Source/WebCore/html/canvas/Float32Array.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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 Float32Array_h
+#define Float32Array_h
+
+#include "TypedArrayBase.h"
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+class Float32Array : public TypedArrayBase<float> {
+public:
+ static PassRefPtr<Float32Array> create(unsigned length);
+ static PassRefPtr<Float32Array> create(const float* array, unsigned length);
+ static PassRefPtr<Float32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
+
+ using TypedArrayBase<float>::set;
+
+ void set(unsigned index, double value)
+ {
+ if (index >= TypedArrayBase<float>::m_length)
+ return;
+ TypedArrayBase<float>::data()[index] = static_cast<float>(value);
+ }
+
+ // Invoked by the indexed getter. Does not perform range checks; caller
+ // is responsible for doing so and returning undefined as necessary.
+ float item(unsigned index) const
+ {
+ ASSERT(index < TypedArrayBase<float>::m_length);
+ float result = TypedArrayBase<float>::data()[index];
+ return result;
+ }
+
+ PassRefPtr<Float32Array> slice(int start) const;
+ PassRefPtr<Float32Array> slice(int start, int end) const;
+
+private:
+ Float32Array(PassRefPtr<ArrayBuffer> buffer,
+ unsigned byteOffset,
+ unsigned length);
+ // Make constructor visible to superclass.
+ friend class TypedArrayBase<float>;
+
+ // Overridden from ArrayBufferView.
+ virtual bool isFloatArray() const { return true; }
+};
+
+} // namespace WebCore
+
+#endif // Float32Array_h
diff --git a/Source/WebCore/html/canvas/Float32Array.idl b/Source/WebCore/html/canvas/Float32Array.idl
new file mode 100644
index 0000000..b979d29
--- /dev/null
+++ b/Source/WebCore/html/canvas/Float32Array.idl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2006, 2010 Apple Computer, Inc. All rights reserved.
+ * 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:
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=3D_CANVAS|BLOB,
+ CanBeConstructed,
+ CustomConstructFunction,
+ V8CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Float32Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 4;
+
+ readonly attribute unsigned long length;
+ Float32Array slice(in long start, in [Optional] long end);
+
+ // void set(in Float32Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/Int16Array.cpp b/Source/WebCore/html/canvas/Int16Array.cpp
new file mode 100644
index 0000000..a3d04bc
--- /dev/null
+++ b/Source/WebCore/html/canvas/Int16Array.cpp
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ * 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(3D_CANVAS) || ENABLE(BLOB)
+
+#include "Int16Array.h"
+
+namespace WebCore {
+
+PassRefPtr<Int16Array> Int16Array::create(unsigned length)
+{
+ return TypedArrayBase<short>::create<Int16Array>(length);
+}
+
+PassRefPtr<Int16Array> Int16Array::create(short* array, unsigned length)
+{
+ return TypedArrayBase<short>::create<Int16Array>(array, length);
+}
+
+PassRefPtr<Int16Array> Int16Array::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+{
+ return TypedArrayBase<short>::create<Int16Array>(buffer, byteOffset, length);
+}
+
+Int16Array::Int16Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+ : IntegralTypedArrayBase<short>(buffer, byteOffset, length)
+{
+}
+
+PassRefPtr<Int16Array> Int16Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Int16Array> Int16Array::slice(int start, int end) const
+{
+ return sliceImpl<Int16Array>(start, end);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB)
diff --git a/Source/WebCore/html/canvas/Int16Array.h b/Source/WebCore/html/canvas/Int16Array.h
new file mode 100644
index 0000000..a6286c6
--- /dev/null
+++ b/Source/WebCore/html/canvas/Int16Array.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ * 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 Int16Array_h
+#define Int16Array_h
+
+#include "IntegralTypedArrayBase.h"
+
+namespace WebCore {
+
+class ArrayBuffer;
+
+class Int16Array : public IntegralTypedArrayBase<short> {
+public:
+ static PassRefPtr<Int16Array> create(unsigned length);
+ static PassRefPtr<Int16Array> create(short* array, unsigned length);
+ static PassRefPtr<Int16Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
+
+ using TypedArrayBase<short>::set;
+ using IntegralTypedArrayBase<short>::set;
+
+ PassRefPtr<Int16Array> slice(int start) const;
+ PassRefPtr<Int16Array> slice(int start, int end) const;
+
+private:
+ Int16Array(PassRefPtr<ArrayBuffer> buffer,
+ unsigned byteOffset,
+ unsigned length);
+ // Make constructor visible to superclass.
+ friend class TypedArrayBase<short>;
+
+ // Overridden from ArrayBufferView.
+ virtual bool isShortArray() const { return true; }
+};
+
+} // namespace WebCore
+
+#endif // Int16Array_h
diff --git a/Source/WebCore/html/canvas/Int16Array.idl b/Source/WebCore/html/canvas/Int16Array.idl
new file mode 100644
index 0000000..f1f5c8b
--- /dev/null
+++ b/Source/WebCore/html/canvas/Int16Array.idl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006, 2010 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
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=3D_CANVAS|BLOB,
+ CanBeConstructed,
+ CustomConstructFunction,
+ V8CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Int16Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 2;
+
+ readonly attribute unsigned long length;
+ Int16Array slice(in long start, in [Optional] long end);
+
+ // void set(in Int16Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/Int32Array.cpp b/Source/WebCore/html/canvas/Int32Array.cpp
new file mode 100644
index 0000000..266c941
--- /dev/null
+++ b/Source/WebCore/html/canvas/Int32Array.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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(3D_CANVAS) || ENABLE(BLOB)
+
+#include "Int32Array.h"
+
+namespace WebCore {
+
+PassRefPtr<Int32Array> Int32Array::create(unsigned length)
+{
+ return TypedArrayBase<int>::create<Int32Array>(length);
+}
+
+PassRefPtr<Int32Array> Int32Array::create(int* array, unsigned length)
+{
+ return TypedArrayBase<int>::create<Int32Array>(array, length);
+}
+
+PassRefPtr<Int32Array> Int32Array::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+{
+ return TypedArrayBase<int>::create<Int32Array>(buffer, byteOffset, length);
+}
+
+Int32Array::Int32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+ : IntegralTypedArrayBase<int>(buffer, byteOffset, length)
+{
+}
+
+PassRefPtr<Int32Array> Int32Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Int32Array> Int32Array::slice(int start, int end) const
+{
+ return sliceImpl<Int32Array>(start, end);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB)
diff --git a/Source/WebCore/html/canvas/Int32Array.h b/Source/WebCore/html/canvas/Int32Array.h
new file mode 100644
index 0000000..068a677
--- /dev/null
+++ b/Source/WebCore/html/canvas/Int32Array.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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 Int32Array_h
+#define Int32Array_h
+
+#include "IntegralTypedArrayBase.h"
+
+namespace WebCore {
+
+class Int32Array : public IntegralTypedArrayBase<int> {
+public:
+ static PassRefPtr<Int32Array> create(unsigned length);
+ static PassRefPtr<Int32Array> create(int* array, unsigned length);
+ static PassRefPtr<Int32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
+
+#if !COMPILER(RVCT)
+ using TypedArrayBase<int>::set;
+ using IntegralTypedArrayBase<int>::set;
+#endif
+
+ PassRefPtr<Int32Array> slice(int start) const;
+ PassRefPtr<Int32Array> slice(int start, int end) const;
+
+private:
+ Int32Array(PassRefPtr<ArrayBuffer> buffer,
+ unsigned byteOffset,
+ unsigned length);
+ // Make constructor visible to superclass.
+ friend class TypedArrayBase<int>;
+
+ // Overridden from ArrayBufferView.
+ virtual bool isIntArray() const { return true; }
+};
+
+} // namespace WebCore
+
+#endif // Int32Array_h
diff --git a/Source/WebCore/html/canvas/Int32Array.idl b/Source/WebCore/html/canvas/Int32Array.idl
new file mode 100644
index 0000000..f96b53c
--- /dev/null
+++ b/Source/WebCore/html/canvas/Int32Array.idl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * 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:
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=3D_CANVAS|BLOB,
+ CanBeConstructed,
+ CustomConstructFunction,
+ V8CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Int32Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 4;
+
+ readonly attribute unsigned long length;
+ Int32Array slice(in long start, in [Optional] long end);
+
+ // void set(in Int32Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/Int8Array.cpp b/Source/WebCore/html/canvas/Int8Array.cpp
new file mode 100644
index 0000000..89ed316
--- /dev/null
+++ b/Source/WebCore/html/canvas/Int8Array.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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(3D_CANVAS) || ENABLE(BLOB)
+
+#include "Int8Array.h"
+
+namespace WebCore {
+
+PassRefPtr<Int8Array> Int8Array::create(unsigned length)
+{
+ return TypedArrayBase<signed char>::create<Int8Array>(length);
+}
+
+PassRefPtr<Int8Array> Int8Array::create(signed char* array, unsigned length)
+{
+ return TypedArrayBase<signed char>::create<Int8Array>(array, length);
+}
+
+PassRefPtr<Int8Array> Int8Array::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+{
+ return TypedArrayBase<signed char>::create<Int8Array>(buffer, byteOffset, length);
+}
+
+Int8Array::Int8Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+ : IntegralTypedArrayBase<signed char>(buffer, byteOffset, length)
+{
+}
+
+PassRefPtr<Int8Array> Int8Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Int8Array> Int8Array::slice(int start, int end) const
+{
+ return sliceImpl<Int8Array>(start, end);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB)
diff --git a/Source/WebCore/html/canvas/Int8Array.h b/Source/WebCore/html/canvas/Int8Array.h
new file mode 100644
index 0000000..a5df302
--- /dev/null
+++ b/Source/WebCore/html/canvas/Int8Array.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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 Int8Array_h
+#define Int8Array_h
+
+#include "IntegralTypedArrayBase.h"
+
+namespace WebCore {
+
+class ArrayBuffer;
+
+class Int8Array : public IntegralTypedArrayBase<signed char> {
+public:
+ static PassRefPtr<Int8Array> create(unsigned length);
+ static PassRefPtr<Int8Array> create(signed char* array, unsigned length);
+ static PassRefPtr<Int8Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
+
+ using TypedArrayBase<signed char>::set;
+ using IntegralTypedArrayBase<signed char>::set;
+
+ PassRefPtr<Int8Array> slice(int start) const;
+ PassRefPtr<Int8Array> slice(int start, int end) const;
+
+private:
+ Int8Array(PassRefPtr<ArrayBuffer> buffer,
+ unsigned byteOffset,
+ unsigned length);
+ // Make constructor visible to superclass.
+ friend class TypedArrayBase<signed char>;
+
+ // Overridden from ArrayBufferView.
+ virtual bool isByteArray() const { return true; }
+};
+
+} // namespace WebCore
+
+#endif // Int8Array_h
diff --git a/Source/WebCore/html/canvas/Int8Array.idl b/Source/WebCore/html/canvas/Int8Array.idl
new file mode 100644
index 0000000..08a608b
--- /dev/null
+++ b/Source/WebCore/html/canvas/Int8Array.idl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * 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:
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=3D_CANVAS|BLOB,
+ CanBeConstructed,
+ CustomConstructFunction,
+ V8CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Int8Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 1;
+
+ readonly attribute unsigned long length;
+ Int8Array slice(in long start, in [Optional] long end);
+
+ // void set(in Int8Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/IntegralTypedArrayBase.h b/Source/WebCore/html/canvas/IntegralTypedArrayBase.h
new file mode 100644
index 0000000..b87d832
--- /dev/null
+++ b/Source/WebCore/html/canvas/IntegralTypedArrayBase.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 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
+ * 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 IntegralTypedArrayBase_h
+#define IntegralTypedArrayBase_h
+
+#include "TypedArrayBase.h"
+#include <limits>
+#include <wtf/MathExtras.h>
+
+// Base class for all WebGL<T>Array types holding integral
+// (non-floating-point) values.
+
+namespace WebCore {
+
+template <typename T>
+class IntegralTypedArrayBase : public TypedArrayBase<T> {
+ public:
+ void set(unsigned index, double value)
+ {
+ if (index >= TypedArrayBase<T>::m_length)
+ return;
+ if (isnan(value)) // Clamp NaN to 0
+ value = 0;
+ if (value < std::numeric_limits<T>::min())
+ value = std::numeric_limits<T>::min();
+ else if (value > std::numeric_limits<T>::max())
+ value = std::numeric_limits<T>::max();
+ TypedArrayBase<T>::data()[index] = static_cast<T>(value);
+ }
+
+ // Invoked by the indexed getter. Does not perform range checks; caller
+ // is responsible for doing so and returning undefined as necessary.
+ T item(unsigned index) const
+ {
+ ASSERT(index < TypedArrayBase<T>::m_length);
+ return TypedArrayBase<T>::data()[index];
+ }
+
+ protected:
+ IntegralTypedArrayBase(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+ : TypedArrayBase<T>(buffer, byteOffset, length)
+ {
+ }
+};
+
+} // namespace WebCore
+
+#endif // IntegralTypedArrayBase_h
diff --git a/Source/WebCore/html/canvas/OESTextureFloat.cpp b/Source/WebCore/html/canvas/OESTextureFloat.cpp
new file mode 100644
index 0000000..dab3caf
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESTextureFloat.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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 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(3D_CANVAS)
+
+#include "OESTextureFloat.h"
+
+namespace WebCore {
+
+OESTextureFloat::OESTextureFloat() : WebGLExtension()
+{
+}
+
+OESTextureFloat::~OESTextureFloat()
+{
+}
+
+WebGLExtension::ExtensionName OESTextureFloat::getName() const
+{
+ return OESTextureFloatName;
+}
+
+PassRefPtr<OESTextureFloat> OESTextureFloat::create()
+{
+ return adoptRef(new OESTextureFloat);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/OESTextureFloat.h b/Source/WebCore/html/canvas/OESTextureFloat.h
new file mode 100644
index 0000000..c99bb2f
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESTextureFloat.h
@@ -0,0 +1,48 @@
+/*
+ * 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 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 OESTextureFloat_h
+#define OESTextureFloat_h
+
+#include "WebGLExtension.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class OESTextureFloat : public WebGLExtension {
+public:
+ static PassRefPtr<OESTextureFloat> create();
+
+ virtual ~OESTextureFloat();
+ virtual ExtensionName getName() const;
+
+private:
+ OESTextureFloat();
+};
+
+} // namespace WebCore
+
+#endif // OESTextureFloat_h
diff --git a/Source/WebCore/html/canvas/OESTextureFloat.idl b/Source/WebCore/html/canvas/OESTextureFloat.idl
new file mode 100644
index 0000000..e255875
--- /dev/null
+++ b/Source/WebCore/html/canvas/OESTextureFloat.idl
@@ -0,0 +1,29 @@
+/*
+ * 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 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.
+ */
+
+module html {
+ interface [Conditional=3D_CANVAS, OmitConstructor] OESTextureFloat {
+ };
+}
diff --git a/Source/WebCore/html/canvas/TypedArrayBase.h b/Source/WebCore/html/canvas/TypedArrayBase.h
new file mode 100644
index 0000000..2bef6f0
--- /dev/null
+++ b/Source/WebCore/html/canvas/TypedArrayBase.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 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
+ * 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 TypedArrayBase_h
+#define TypedArrayBase_h
+
+#include "ArrayBuffer.h"
+#include "ArrayBufferView.h"
+
+namespace WebCore {
+
+template <typename T>
+class TypedArrayBase : public ArrayBufferView {
+ public:
+ T* data() const { return static_cast<T*>(baseAddress()); }
+
+ void set(TypedArrayBase<T>* array, unsigned offset, ExceptionCode& ec)
+ {
+ setImpl(array, offset * sizeof(T), ec);
+ }
+
+ void setRange(const T* data, size_t dataLength, unsigned offset, ExceptionCode& ec)
+ {
+ setRangeImpl(reinterpret_cast<const char*>(data), dataLength * sizeof(T), offset * sizeof(T), ec);
+ }
+
+ void zeroRange(unsigned offset, size_t length, ExceptionCode& ec)
+ {
+ zeroRangeImpl(offset * sizeof(T), length * sizeof(T), ec);
+ }
+
+ // Overridden from ArrayBufferView. This must be public because of
+ // rules about inheritance of members in template classes, and
+ // because it is accessed via pointers to subclasses.
+ unsigned length() const
+ {
+ return m_length;
+ }
+
+ protected:
+ TypedArrayBase(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+ : ArrayBufferView(buffer, byteOffset)
+ , m_length(length)
+ {
+ }
+
+ template <class Subclass>
+ static PassRefPtr<Subclass> create(unsigned length)
+ {
+ RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(length, sizeof(T));
+ if (!buffer.get())
+ return 0;
+ return create<Subclass>(buffer, 0, length);
+ }
+
+ template <class Subclass>
+ static PassRefPtr<Subclass> create(const T* array, unsigned length)
+ {
+ RefPtr<Subclass> a = create<Subclass>(length);
+ if (a)
+ for (unsigned i = 0; i < length; ++i)
+ a->set(i, array[i]);
+ return a;
+ }
+
+ template <class Subclass>
+ static PassRefPtr<Subclass> create(PassRefPtr<ArrayBuffer> buffer,
+ unsigned byteOffset,
+ unsigned length)
+ {
+ RefPtr<ArrayBuffer> buf(buffer);
+ if (!verifySubRange<T>(buf, byteOffset, length))
+ return 0;
+
+ return adoptRef(new Subclass(buf, byteOffset, length));
+ }
+
+ template <class Subclass>
+ PassRefPtr<Subclass> sliceImpl(int start, int end) const
+ {
+ unsigned offset, length;
+ calculateOffsetAndLength(start, end, m_length, &offset, &length);
+ clampOffsetAndNumElements<T>(buffer(), m_byteOffset, &offset, &length);
+ return create<Subclass>(buffer(), offset, length);
+ }
+
+ // We do not want to have to access this via a virtual function in subclasses,
+ // which is why it is protected rather than private.
+ unsigned m_length;
+
+ private:
+ // Overridden from ArrayBufferView.
+ virtual unsigned byteLength() const
+ {
+ return m_length * sizeof(T);
+ }
+};
+
+} // namespace WebCore
+
+#endif // TypedArrayBase_h
diff --git a/Source/WebCore/html/canvas/Uint16Array.cpp b/Source/WebCore/html/canvas/Uint16Array.cpp
new file mode 100644
index 0000000..5312888
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint16Array.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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(3D_CANVAS) || ENABLE(BLOB)
+
+#include "Uint16Array.h"
+
+namespace WebCore {
+
+PassRefPtr<Uint16Array> Uint16Array::create(unsigned length)
+{
+ return TypedArrayBase<unsigned short>::create<Uint16Array>(length);
+}
+
+PassRefPtr<Uint16Array> Uint16Array::create(unsigned short* array, unsigned length)
+{
+ return TypedArrayBase<unsigned short>::create<Uint16Array>(array, length);
+}
+
+PassRefPtr<Uint16Array> Uint16Array::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+{
+ return TypedArrayBase<unsigned short>::create<Uint16Array>(buffer, byteOffset, length);
+}
+
+Uint16Array::Uint16Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+ : IntegralTypedArrayBase<unsigned short>(buffer, byteOffset, length)
+{
+}
+
+PassRefPtr<Uint16Array> Uint16Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Uint16Array> Uint16Array::slice(int start, int end) const
+{
+ return sliceImpl<Uint16Array>(start, end);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB)
diff --git a/Source/WebCore/html/canvas/Uint16Array.h b/Source/WebCore/html/canvas/Uint16Array.h
new file mode 100644
index 0000000..f63b67d
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint16Array.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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 Uint16Array_h
+#define Uint16Array_h
+
+#include "IntegralTypedArrayBase.h"
+
+namespace WebCore {
+
+class ArrayBuffer;
+
+class Uint16Array : public IntegralTypedArrayBase<unsigned short> {
+public:
+ static PassRefPtr<Uint16Array> create(unsigned length);
+ static PassRefPtr<Uint16Array> create(unsigned short* array, unsigned length);
+ static PassRefPtr<Uint16Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
+
+ using TypedArrayBase<unsigned short>::set;
+ using IntegralTypedArrayBase<unsigned short>::set;
+
+ PassRefPtr<Uint16Array> slice(int start) const;
+ PassRefPtr<Uint16Array> slice(int start, int end) const;
+
+private:
+ Uint16Array(PassRefPtr<ArrayBuffer> buffer,
+ unsigned byteOffset,
+ unsigned length);
+ // Make constructor visible to superclass.
+ friend class TypedArrayBase<unsigned short>;
+
+ // Overridden from ArrayBufferView.
+ virtual bool isUnsignedShortArray() const { return true; }
+};
+
+} // namespace WebCore
+
+#endif // Uint16Array_h
diff --git a/Source/WebCore/html/canvas/Uint16Array.idl b/Source/WebCore/html/canvas/Uint16Array.idl
new file mode 100644
index 0000000..8e778b4
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint16Array.idl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * 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:
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=3D_CANVAS|BLOB,
+ CanBeConstructed,
+ CustomConstructFunction,
+ V8CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Uint16Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 2;
+
+ readonly attribute unsigned long length;
+ Uint16Array slice(in long start, in [Optional] long end);
+
+ // void set(in Uint16Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/Uint32Array.cpp b/Source/WebCore/html/canvas/Uint32Array.cpp
new file mode 100644
index 0000000..f5bd959
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint32Array.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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(3D_CANVAS) || ENABLE(BLOB)
+
+#include "Uint32Array.h"
+
+namespace WebCore {
+
+PassRefPtr<Uint32Array> Uint32Array::create(unsigned length)
+{
+ return TypedArrayBase<unsigned int>::create<Uint32Array>(length);
+}
+
+PassRefPtr<Uint32Array> Uint32Array::create(unsigned int* array, unsigned length)
+{
+ return TypedArrayBase<unsigned int>::create<Uint32Array>(array, length);
+}
+
+PassRefPtr<Uint32Array> Uint32Array::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+{
+ return TypedArrayBase<unsigned int>::create<Uint32Array>(buffer, byteOffset, length);
+}
+
+Uint32Array::Uint32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+ : IntegralTypedArrayBase<unsigned int>(buffer, byteOffset, length)
+{
+}
+
+PassRefPtr<Uint32Array> Uint32Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Uint32Array> Uint32Array::slice(int start, int end) const
+{
+ return sliceImpl<Uint32Array>(start, end);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB)
diff --git a/Source/WebCore/html/canvas/Uint32Array.h b/Source/WebCore/html/canvas/Uint32Array.h
new file mode 100644
index 0000000..9c0f137
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint32Array.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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 Uint32Array_h
+#define Uint32Array_h
+
+#include "IntegralTypedArrayBase.h"
+
+namespace WebCore {
+
+class ArrayBuffer;
+
+class Uint32Array : public IntegralTypedArrayBase<unsigned int> {
+public:
+ static PassRefPtr<Uint32Array> create(unsigned length);
+ static PassRefPtr<Uint32Array> create(unsigned int* array, unsigned length);
+ static PassRefPtr<Uint32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
+
+ using TypedArrayBase<unsigned int>::set;
+ using IntegralTypedArrayBase<unsigned int>::set;
+
+ PassRefPtr<Uint32Array> slice(int start) const;
+ PassRefPtr<Uint32Array> slice(int start, int end) const;
+
+private:
+ Uint32Array(PassRefPtr<ArrayBuffer> buffer,
+ unsigned byteOffset,
+ unsigned length);
+ // Make constructor visible to superclass.
+ friend class TypedArrayBase<unsigned int>;
+
+ // Overridden from ArrayBufferView.
+ virtual bool isUnsignedIntArray() const { return true; }
+};
+
+} // namespace WebCore
+
+#endif // Uint32Array_h
diff --git a/Source/WebCore/html/canvas/Uint32Array.idl b/Source/WebCore/html/canvas/Uint32Array.idl
new file mode 100644
index 0000000..9fbf30c
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint32Array.idl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * 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:
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=3D_CANVAS|BLOB,
+ CanBeConstructed,
+ CustomConstructFunction,
+ V8CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Uint32Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 4;
+
+ readonly attribute unsigned long length;
+ Uint32Array slice(in long start, in [Optional] long end);
+
+ // void set(in Uint32Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/Uint8Array.cpp b/Source/WebCore/html/canvas/Uint8Array.cpp
new file mode 100644
index 0000000..99b8a09
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint8Array.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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(3D_CANVAS) || ENABLE(BLOB)
+
+#include "Uint8Array.h"
+
+namespace WebCore {
+
+PassRefPtr<Uint8Array> Uint8Array::create(unsigned length)
+{
+ return TypedArrayBase<unsigned char>::create<Uint8Array>(length);
+}
+
+PassRefPtr<Uint8Array> Uint8Array::create(unsigned char* array, unsigned length)
+{
+ return TypedArrayBase<unsigned char>::create<Uint8Array>(array, length);
+}
+
+PassRefPtr<Uint8Array> Uint8Array::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+{
+ return TypedArrayBase<unsigned char>::create<Uint8Array>(buffer, byteOffset, length);
+}
+
+Uint8Array::Uint8Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+ : IntegralTypedArrayBase<unsigned char>(buffer, byteOffset, length)
+{
+}
+
+PassRefPtr<Uint8Array> Uint8Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Uint8Array> Uint8Array::slice(int start, int end) const
+{
+ return sliceImpl<Uint8Array>(start, end);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB)
diff --git a/Source/WebCore/html/canvas/Uint8Array.h b/Source/WebCore/html/canvas/Uint8Array.h
new file mode 100644
index 0000000..66154b5
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint8Array.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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 Uint8Array_h
+#define Uint8Array_h
+
+#include "IntegralTypedArrayBase.h"
+
+namespace WebCore {
+
+class ArrayBuffer;
+
+class Uint8Array : public IntegralTypedArrayBase<unsigned char> {
+public:
+ static PassRefPtr<Uint8Array> create(unsigned length);
+ static PassRefPtr<Uint8Array> create(unsigned char* array, unsigned length);
+ static PassRefPtr<Uint8Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
+
+#if !COMPILER(RVCT)
+ using TypedArrayBase<unsigned char>::set;
+ using IntegralTypedArrayBase<unsigned char>::set;
+#endif
+
+ PassRefPtr<Uint8Array> slice(int start) const;
+ PassRefPtr<Uint8Array> slice(int start, int end) const;
+
+private:
+ Uint8Array(PassRefPtr<ArrayBuffer> buffer,
+ unsigned byteOffset,
+ unsigned length);
+ // Make constructor visible to superclass.
+ friend class TypedArrayBase<unsigned char>;
+
+ // Overridden from ArrayBufferView.
+ virtual bool isUnsignedByteArray() const { return true; }
+};
+
+} // namespace WebCore
+
+#endif // Uint8Array_h
diff --git a/Source/WebCore/html/canvas/Uint8Array.idl b/Source/WebCore/html/canvas/Uint8Array.idl
new file mode 100644
index 0000000..7fe7e21
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint8Array.idl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * 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:
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=3D_CANVAS|BLOB,
+ CanBeConstructed,
+ CustomConstructFunction,
+ V8CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Uint8Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 1;
+
+ readonly attribute unsigned long length;
+ Uint8Array slice(in long start, in [Optional] long end);
+
+ // void set(in Uint8Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLActiveInfo.h b/Source/WebCore/html/canvas/WebGLActiveInfo.h
new file mode 100644
index 0000000..4650ea1
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLActiveInfo.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ * 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 WebGLActiveInfo_h
+#define WebGLActiveInfo_h
+
+#include "PlatformString.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLActiveInfo : public RefCounted<WebGLActiveInfo> {
+public:
+ static PassRefPtr<WebGLActiveInfo> create(const String& name, unsigned type, int size)
+ {
+ return adoptRef(new WebGLActiveInfo(name, type, size));
+ }
+ String name() const { return m_name; }
+ unsigned type() const { return m_type; }
+ int size() const { return m_size; }
+
+private:
+ WebGLActiveInfo(const String& name, unsigned type, int size)
+ : m_name(name)
+ , m_type(type)
+ , m_size(size)
+ {
+ ASSERT(name.length());
+ ASSERT(type);
+ ASSERT(size);
+ }
+ String m_name;
+ unsigned m_type;
+ int m_size;
+};
+
+}
+
+#endif // WebGLActiveInfo_h
diff --git a/Source/WebCore/html/canvas/WebGLActiveInfo.idl b/Source/WebCore/html/canvas/WebGLActiveInfo.idl
new file mode 100644
index 0000000..28f7136
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLActiveInfo.idl
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ * 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.
+ */
+
+module html {
+
+ interface [
+ Conditional=3D_CANVAS
+ ] WebGLActiveInfo {
+ readonly attribute int size;
+ readonly attribute unsigned int type;
+ readonly attribute DOMString name;
+ };
+
+}
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.cpp b/Source/WebCore/html/canvas/WebGLBuffer.cpp
new file mode 100644
index 0000000..f8c7b38
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLBuffer.cpp
@@ -0,0 +1,207 @@
+/*
+ * 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.
+ * 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(3D_CANVAS)
+
+#include "WebGLBuffer.h"
+
+#include "ArrayBufferView.h"
+#include "CheckedInt.h"
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContext* ctx)
+{
+ return adoptRef(new WebGLBuffer(ctx));
+}
+
+WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx)
+ : WebGLObject(ctx)
+ , m_target(0)
+ , m_byteLength(0)
+ , m_nextAvailableCacheEntry(0)
+{
+ setObject(context()->graphicsContext3D()->createBuffer());
+ clearCachedMaxIndices();
+}
+
+void WebGLBuffer::deleteObjectImpl(Platform3DObject object)
+{
+ context()->graphicsContext3D()->deleteBuffer(object);
+}
+
+bool WebGLBuffer::associateBufferDataImpl(ArrayBuffer* array, unsigned byteOffset, unsigned byteLength)
+{
+ if (array && byteLength) {
+ CheckedInt<uint32_t> checkedOffset(byteOffset);
+ CheckedInt<uint32_t> checkedLength(byteLength);
+ CheckedInt<uint32_t> checkedMax = checkedOffset + checkedLength;
+ if (!checkedMax.valid() || checkedMax.value() > array->byteLength())
+ return false;
+ }
+
+ switch (m_target) {
+ case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
+ m_byteLength = byteLength;
+ clearCachedMaxIndices();
+ if (byteLength) {
+ m_elementArrayBuffer = ArrayBuffer::create(byteLength, 1);
+ if (!m_elementArrayBuffer) {
+ m_byteLength = 0;
+ return false;
+ }
+ if (array) {
+ // We must always clone the incoming data because client-side
+ // modifications without calling bufferData or bufferSubData
+ // must never be able to change the validation results.
+ memcpy(static_cast<unsigned char*>(m_elementArrayBuffer->data()),
+ static_cast<unsigned char*>(array->data()) + byteOffset,
+ byteLength);
+ }
+ } else
+ m_elementArrayBuffer = 0;
+ return true;
+ case GraphicsContext3D::ARRAY_BUFFER:
+ m_byteLength = byteLength;
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool WebGLBuffer::associateBufferData(int size)
+{
+ if (size < 0)
+ return false;
+ return associateBufferDataImpl(0, 0, static_cast<unsigned>(size));
+}
+
+bool WebGLBuffer::associateBufferData(ArrayBuffer* array)
+{
+ if (!array)
+ return false;
+ return associateBufferDataImpl(array, 0, array->byteLength());
+}
+
+bool WebGLBuffer::associateBufferData(ArrayBufferView* array)
+{
+ if (!array)
+ return false;
+ return associateBufferDataImpl(array->buffer().get(), array->byteOffset(), array->byteLength());
+}
+
+bool WebGLBuffer::associateBufferSubDataImpl(long offset, ArrayBuffer* array, unsigned arrayByteOffset, unsigned byteLength)
+{
+ if (!array || offset < 0)
+ return false;
+
+ if (byteLength) {
+ CheckedInt<uint32_t> checkedBufferOffset(offset);
+ CheckedInt<uint32_t> checkedArrayOffset(arrayByteOffset);
+ CheckedInt<uint32_t> checkedLength(byteLength);
+ CheckedInt<uint32_t> checkedArrayMax = checkedArrayOffset + checkedLength;
+ CheckedInt<uint32_t> checkedBufferMax = checkedBufferOffset + checkedLength;
+ if (!checkedArrayMax.valid() || checkedArrayMax.value() > array->byteLength() || !checkedBufferMax.valid() || checkedBufferMax.value() > m_byteLength)
+ return false;
+ }
+
+ switch (m_target) {
+ case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
+ clearCachedMaxIndices();
+ if (byteLength) {
+ if (!m_elementArrayBuffer)
+ return false;
+ memcpy(static_cast<unsigned char*>(m_elementArrayBuffer->data()) + offset,
+ static_cast<unsigned char*>(array->data()) + arrayByteOffset,
+ byteLength);
+ }
+ return true;
+ case GraphicsContext3D::ARRAY_BUFFER:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool WebGLBuffer::associateBufferSubData(long offset, ArrayBuffer* array)
+{
+ if (!array)
+ return false;
+ return associateBufferSubDataImpl(offset, array, 0, array->byteLength());
+}
+
+bool WebGLBuffer::associateBufferSubData(long offset, ArrayBufferView* array)
+{
+ if (!array)
+ return false;
+ return associateBufferSubDataImpl(offset, array->buffer().get(), array->byteOffset(), array->byteLength());
+}
+
+unsigned WebGLBuffer::byteLength() const
+{
+ return m_byteLength;
+}
+
+long WebGLBuffer::getCachedMaxIndex(unsigned long type)
+{
+ for (size_t i = 0; i < WTF_ARRAY_LENGTH(m_maxIndexCache); ++i)
+ if (m_maxIndexCache[i].type == type)
+ return m_maxIndexCache[i].maxIndex;
+ return -1;
+}
+
+void WebGLBuffer::setCachedMaxIndex(unsigned long type, long value)
+{
+ size_t numEntries = WTF_ARRAY_LENGTH(m_maxIndexCache);
+ for (size_t i = 0; i < numEntries; ++i)
+ if (m_maxIndexCache[i].type == type) {
+ m_maxIndexCache[i].maxIndex = value;
+ return;
+ }
+ m_maxIndexCache[m_nextAvailableCacheEntry].type = type;
+ m_maxIndexCache[m_nextAvailableCacheEntry].maxIndex = value;
+ m_nextAvailableCacheEntry = (m_nextAvailableCacheEntry + 1) % numEntries;
+}
+
+void WebGLBuffer::setTarget(unsigned long target)
+{
+ // In WebGL, a buffer is bound to one target in its lifetime
+ if (m_target)
+ return;
+ if (target == GraphicsContext3D::ARRAY_BUFFER || target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
+ m_target = target;
+}
+
+void WebGLBuffer::clearCachedMaxIndices()
+{
+ memset(m_maxIndexCache, 0, sizeof(m_maxIndexCache));
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.h b/Source/WebCore/html/canvas/WebGLBuffer.h
new file mode 100644
index 0000000..af819a3
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLBuffer.h
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ * 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 WebGLBuffer_h
+#define WebGLBuffer_h
+
+#include "ArrayBuffer.h"
+#include "WebGLObject.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+class ArrayBufferView;
+
+class WebGLBuffer : public WebGLObject {
+public:
+ virtual ~WebGLBuffer() { deleteObject(); }
+
+ static PassRefPtr<WebGLBuffer> create(WebGLRenderingContext*);
+
+ bool associateBufferData(int size);
+ bool associateBufferData(ArrayBuffer* array);
+ bool associateBufferData(ArrayBufferView* array);
+ bool associateBufferSubData(long offset, ArrayBuffer* array);
+ bool associateBufferSubData(long offset, ArrayBufferView* array);
+
+ unsigned byteLength() const;
+ const ArrayBuffer* elementArrayBuffer() const { return m_elementArrayBuffer.get(); }
+
+ // Gets the cached max index for the given type. Returns -1 if
+ // none has been set.
+ long getCachedMaxIndex(unsigned long type);
+ // Sets the cached max index for the given type.
+ void setCachedMaxIndex(unsigned long type, long value);
+
+ unsigned long getTarget() const { return m_target; }
+ void setTarget(unsigned long);
+
+ bool hasEverBeenBound() const { return object() && m_target; }
+
+protected:
+ WebGLBuffer(WebGLRenderingContext*);
+
+ virtual void deleteObjectImpl(Platform3DObject o);
+
+private:
+ virtual bool isBuffer() const { return true; }
+
+ unsigned long m_target;
+
+ RefPtr<ArrayBuffer> m_elementArrayBuffer;
+ unsigned m_byteLength;
+
+ // Optimization for index validation. For each type of index
+ // (i.e., UNSIGNED_SHORT), cache the maximum index in the
+ // entire buffer.
+ //
+ // This is sufficient to eliminate a lot of work upon each
+ // draw call as long as all bound array buffers are at least
+ // that size.
+ struct MaxIndexCacheEntry {
+ unsigned long type;
+ long maxIndex;
+ };
+ // OpenGL ES 2.0 only has two valid index types (UNSIGNED_BYTE
+ // and UNSIGNED_SHORT), but might as well leave open the
+ // possibility of adding others.
+ MaxIndexCacheEntry m_maxIndexCache[4];
+ unsigned m_nextAvailableCacheEntry;
+
+ // Clears all of the cached max indices.
+ void clearCachedMaxIndices();
+
+ // Helper function called by the three associateBufferData().
+ bool associateBufferDataImpl(ArrayBuffer* array, unsigned byteOffset, unsigned byteLength);
+ // Helper function called by the two associateBufferSubData().
+ bool associateBufferSubDataImpl(long offset, ArrayBuffer* array, unsigned arrayByteOffset, unsigned byteLength);
+};
+
+} // namespace WebCore
+
+#endif // WebGLBuffer_h
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.idl b/Source/WebCore/html/canvas/WebGLBuffer.idl
new file mode 100644
index 0000000..30b7606
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLBuffer.idl
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ * 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.
+ */
+
+module html {
+ interface [Conditional=3D_CANVAS] WebGLBuffer {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.cpp b/Source/WebCore/html/canvas/WebGLContextAttributes.cpp
new file mode 100644
index 0000000..a0725ca
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextAttributes.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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:
+ * * 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.
+ *
+ * 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(3D_CANVAS)
+
+#include "WebGLContextAttributes.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create()
+{
+ return adoptRef(new WebGLContextAttributes());
+}
+
+PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create(GraphicsContext3D::Attributes attributes)
+{
+ return adoptRef(new WebGLContextAttributes(attributes));
+}
+
+WebGLContextAttributes::WebGLContextAttributes()
+ : CanvasContextAttributes()
+{
+}
+
+WebGLContextAttributes::WebGLContextAttributes(GraphicsContext3D::Attributes attributes)
+ : CanvasContextAttributes()
+ , m_attrs(attributes)
+{
+}
+
+WebGLContextAttributes::~WebGLContextAttributes()
+{
+}
+
+bool WebGLContextAttributes::alpha() const
+{
+ return m_attrs.alpha;
+}
+
+void WebGLContextAttributes::setAlpha(bool alpha)
+{
+ m_attrs.alpha = alpha;
+}
+
+bool WebGLContextAttributes::depth() const
+{
+ return m_attrs.depth;
+}
+
+void WebGLContextAttributes::setDepth(bool depth)
+{
+ m_attrs.depth = depth;
+}
+
+bool WebGLContextAttributes::stencil() const
+{
+ return m_attrs.stencil;
+}
+
+void WebGLContextAttributes::setStencil(bool stencil)
+{
+ m_attrs.stencil = stencil;
+}
+
+bool WebGLContextAttributes::antialias() const
+{
+ return m_attrs.antialias;
+}
+
+void WebGLContextAttributes::setAntialias(bool antialias)
+{
+ m_attrs.antialias = antialias;
+}
+
+bool WebGLContextAttributes::premultipliedAlpha() const
+{
+ return m_attrs.premultipliedAlpha;
+}
+
+void WebGLContextAttributes::setPremultipliedAlpha(bool premultipliedAlpha)
+{
+ m_attrs.premultipliedAlpha = premultipliedAlpha;
+}
+
+GraphicsContext3D::Attributes WebGLContextAttributes::attributes() const
+{
+ return m_attrs;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.h b/Source/WebCore/html/canvas/WebGLContextAttributes.h
new file mode 100644
index 0000000..a108605
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextAttributes.h
@@ -0,0 +1,82 @@
+/*
+ * 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:
+ * * 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.
+ *
+ * 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 WebGLContextAttributes_h
+#define WebGLContextAttributes_h
+
+#include "CanvasContextAttributes.h"
+#include "GraphicsContext3D.h"
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class WebGLContextAttributes : public CanvasContextAttributes {
+ public:
+ virtual ~WebGLContextAttributes();
+
+ // Create a new attributes object
+ static PassRefPtr<WebGLContextAttributes> create();
+
+ // Create a new attributes object initialized with preexisting attributes
+ static PassRefPtr<WebGLContextAttributes> create(GraphicsContext3D::Attributes attributes);
+
+ // Whether or not the drawing buffer has an alpha channel; default=true
+ bool alpha() const;
+ void setAlpha(bool alpha);
+
+ // Whether or not the drawing buffer has a depth buffer; default=true
+ bool depth() const;
+ void setDepth(bool depth);
+
+ // Whether or not the drawing buffer has a stencil buffer; default=true
+ bool stencil() const;
+ void setStencil(bool stencil);
+
+ // Whether or not the drawing buffer is antialiased; default=true
+ bool antialias() const;
+ void setAntialias(bool antialias);
+
+ // Whether or not to treat the values in the drawing buffer as
+ // though their alpha channel has already been multiplied into the
+ // color channels; default=true
+ bool premultipliedAlpha() const;
+ void setPremultipliedAlpha(bool premultipliedAlpha);
+
+ // Fetches a copy of the attributes stored in this object in a
+ // form that can be used to initialize a GraphicsContext3D.
+ GraphicsContext3D::Attributes attributes() const;
+
+ protected:
+ WebGLContextAttributes();
+ WebGLContextAttributes(GraphicsContext3D::Attributes attributes);
+
+ private:
+ GraphicsContext3D::Attributes m_attrs;
+};
+
+} // namespace WebCore
+
+#endif // WebGLContextAttributes_h
diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.idl b/Source/WebCore/html/canvas/WebGLContextAttributes.idl
new file mode 100644
index 0000000..be2b20c
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextAttributes.idl
@@ -0,0 +1,38 @@
+/*
+ * 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:
+ * * 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.
+ *
+ * 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.
+ */
+
+module html {
+ interface [
+ Conditional=3D_CANVAS,
+ OmitConstructor
+ ] WebGLContextAttributes {
+ attribute boolean alpha;
+ attribute boolean depth;
+ attribute boolean stencil;
+ attribute boolean antialias;
+ attribute boolean premultipliedAlpha;
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLContextEvent.cpp b/Source/WebCore/html/canvas/WebGLContextEvent.cpp
new file mode 100644
index 0000000..b7a277f
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextEvent.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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 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"
+#include "WebGLContextEvent.h"
+
+namespace WebCore {
+
+WebGLContextEvent::WebGLContextEvent()
+{
+}
+
+WebGLContextEvent::WebGLContextEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
+ : Event(type, canBubble, cancelable)
+ , m_statusMessage(statusMessage)
+{
+}
+
+WebGLContextEvent::~WebGLContextEvent()
+{
+}
+
+void WebGLContextEvent::initEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
+{
+ if (dispatched())
+ return;
+
+ Event::initEvent(type, canBubble, cancelable);
+ m_statusMessage = statusMessage;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLContextEvent.h b/Source/WebCore/html/canvas/WebGLContextEvent.h
new file mode 100644
index 0000000..348769b
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextEvent.h
@@ -0,0 +1,58 @@
+/*
+ * 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 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 WebGLContextEvent_h
+#define WebGLContextEvent_h
+
+#include "Event.h"
+
+namespace WebCore {
+
+class WebGLContextEvent : public Event {
+public:
+ static PassRefPtr<WebGLContextEvent> create()
+ {
+ return adoptRef(new WebGLContextEvent);
+ }
+ static PassRefPtr<WebGLContextEvent> create(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
+ {
+ return adoptRef(new WebGLContextEvent(type, canBubble, cancelable, statusMessage));
+ }
+ virtual ~WebGLContextEvent();
+
+ void initEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage);
+
+ const String& statusMessage() const { return m_statusMessage; }
+
+private:
+ WebGLContextEvent();
+ WebGLContextEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage);
+
+ String m_statusMessage;
+};
+
+} // namespace WebCore
+
+#endif // WebGLContextEvent_h
diff --git a/Source/WebCore/html/canvas/WebGLContextEvent.idl b/Source/WebCore/html/canvas/WebGLContextEvent.idl
new file mode 100644
index 0000000..30973a9
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextEvent.idl
@@ -0,0 +1,36 @@
+/*
+ * 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 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.
+ */
+
+module html {
+ interface [
+ Conditional=3D_CANVAS,
+ ] WebGLContextEvent : Event {
+ readonly attribute DOMString statusMessage;
+ [StrictTypeChecking] void initEvent(in DOMString eventTypeArg,
+ in boolean canBubbleArg,
+ in boolean cancelableArg,
+ in DOMString statusMessageArg);
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLExtension.cpp b/Source/WebCore/html/canvas/WebGLExtension.cpp
new file mode 100644
index 0000000..580e635
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLExtension.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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 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(3D_CANVAS)
+
+#include "WebGLExtension.h"
+
+namespace WebCore {
+
+WebGLExtension::WebGLExtension()
+{
+}
+
+WebGLExtension::~WebGLExtension()
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebGLExtension.h b/Source/WebCore/html/canvas/WebGLExtension.h
new file mode 100644
index 0000000..f2d6b7b
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLExtension.h
@@ -0,0 +1,50 @@
+/*
+ * 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 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 WebGLExtension_h
+#define WebGLExtension_h
+
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLExtension : public RefCounted<WebGLExtension> {
+public:
+ // Extension names are needed to properly wrap instances in JavaScript objects.
+ enum ExtensionName {
+ WebKitLoseContextName,
+ OESTextureFloatName,
+ };
+
+ virtual ~WebGLExtension();
+ virtual ExtensionName getName() const = 0;
+
+protected:
+ WebGLExtension();
+};
+
+} // namespace WebCore
+
+#endif // WebGLExtension_h
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
new file mode 100644
index 0000000..a1c3a9a
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -0,0 +1,357 @@
+/*
+ * 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.
+ * 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(3D_CANVAS)
+
+#include "WebGLFramebuffer.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+namespace {
+
+ // This function is only for depth/stencil/depth_stencil attachment.
+ // Currently we assume these attachments are all renderbuffers.
+ unsigned long getInternalFormat(WebGLObject* buffer)
+ {
+ ASSERT(buffer && buffer->isRenderbuffer());
+ return (reinterpret_cast<WebGLRenderbuffer*>(buffer))->getInternalFormat();
+ }
+
+ bool isUninitialized(WebGLObject* attachedObject)
+ {
+ if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()
+ && !(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isInitialized())
+ return true;
+ return false;
+ }
+
+ void setInitialized(WebGLObject* attachedObject)
+ {
+ if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer())
+ (reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->setInitialized();
+ }
+
+ bool isValid(WebGLObject* attachedObject)
+ {
+ if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()) {
+ if (!(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isValid())
+ return false;
+ }
+ return true;
+ }
+
+} // anonymous namespace
+
+PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx)
+{
+ return adoptRef(new WebGLFramebuffer(ctx));
+}
+
+WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
+ : WebGLObject(ctx)
+ , m_hasEverBeenBound(false)
+ , m_texTarget(0)
+ , m_texLevel(-1)
+{
+ setObject(context()->graphicsContext3D()->createFramebuffer());
+}
+
+void WebGLFramebuffer::setAttachment(unsigned long attachment, unsigned long texTarget, WebGLTexture* texture, int level)
+{
+ if (!object())
+ return;
+ if (texture && !texture->object())
+ texture = 0;
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ m_colorAttachment = texture;
+ if (texture) {
+ m_texTarget = texTarget;
+ m_texLevel = level;
+ }
+ break;
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ m_depthAttachment = texture;
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ m_stencilAttachment = texture;
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ m_depthStencilAttachment = texture;
+ break;
+ default:
+ return;
+ }
+}
+
+void WebGLFramebuffer::setAttachment(unsigned long attachment, WebGLRenderbuffer* renderbuffer)
+{
+ if (!object())
+ return;
+ if (renderbuffer && !renderbuffer->object())
+ renderbuffer = 0;
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ m_colorAttachment = renderbuffer;
+ break;
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ m_depthAttachment = renderbuffer;
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ m_stencilAttachment = renderbuffer;
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ m_depthStencilAttachment = renderbuffer;
+ break;
+ default:
+ return;
+ }
+}
+
+WebGLObject* WebGLFramebuffer::getAttachment(unsigned long attachment) const
+{
+ if (!object())
+ return 0;
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ return m_colorAttachment.get();
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ return m_depthAttachment.get();
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ return m_stencilAttachment.get();
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ return m_depthStencilAttachment.get();
+ default:
+ return 0;
+ }
+}
+
+void WebGLFramebuffer::removeAttachment(WebGLObject* attachment)
+{
+ if (!object())
+ return;
+ if (attachment == m_colorAttachment.get())
+ m_colorAttachment = 0;
+ else if (attachment == m_depthAttachment.get())
+ m_depthAttachment = 0;
+ else if (attachment == m_stencilAttachment.get())
+ m_stencilAttachment = 0;
+ else if (attachment == m_depthStencilAttachment.get())
+ m_depthStencilAttachment = 0;
+ else
+ return;
+}
+
+int WebGLFramebuffer::getWidth() const
+{
+ if (!object() || !isColorAttached())
+ return 0;
+ if (m_colorAttachment->isRenderbuffer())
+ return (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment.get()))->getWidth();
+ if (m_colorAttachment->isTexture())
+ return (reinterpret_cast<WebGLTexture*>(m_colorAttachment.get()))->getWidth(m_texTarget, m_texLevel);
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+int WebGLFramebuffer::getHeight() const
+{
+ if (!object() || !isColorAttached())
+ return 0;
+ if (m_colorAttachment->isRenderbuffer())
+ return (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment.get()))->getHeight();
+ if (m_colorAttachment->isTexture())
+ return (reinterpret_cast<WebGLTexture*>(m_colorAttachment.get()))->getHeight(m_texTarget, m_texLevel);
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+unsigned long WebGLFramebuffer::getColorBufferFormat() const
+{
+ if (!object() || !isColorAttached())
+ return 0;
+ if (m_colorAttachment->isRenderbuffer()) {
+ unsigned long format = (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment.get()))->getInternalFormat();
+ switch (format) {
+ case GraphicsContext3D::RGBA4:
+ case GraphicsContext3D::RGB5_A1:
+ return GraphicsContext3D::RGBA;
+ case GraphicsContext3D::RGB565:
+ return GraphicsContext3D::RGB;
+ }
+ return 0;
+ }
+ if (m_colorAttachment->isTexture())
+ return (reinterpret_cast<WebGLTexture*>(m_colorAttachment.get()))->getInternalFormat(m_texTarget, m_texLevel);
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+bool WebGLFramebuffer::isIncomplete(bool checkInternalFormat) const
+{
+ unsigned int count = 0;
+ if (isDepthAttached()) {
+ if (checkInternalFormat && getInternalFormat(m_depthAttachment.get()) != GraphicsContext3D::DEPTH_COMPONENT16)
+ return true;
+ count++;
+ }
+ if (isStencilAttached()) {
+ if (checkInternalFormat && getInternalFormat(m_stencilAttachment.get()) != GraphicsContext3D::STENCIL_INDEX8)
+ return true;
+ count++;
+ }
+ if (isDepthStencilAttached()) {
+ if (checkInternalFormat && getInternalFormat(m_depthStencilAttachment.get()) != GraphicsContext3D::DEPTH_STENCIL)
+ return true;
+ if (!isValid(m_depthStencilAttachment.get()))
+ return true;
+ count++;
+ }
+ if (count > 1)
+ return true;
+ return false;
+}
+
+bool WebGLFramebuffer::onAccess(bool needToInitializeRenderbuffers)
+{
+ if (isIncomplete(true))
+ return false;
+ if (needToInitializeRenderbuffers)
+ return initializeRenderbuffers();
+ return true;
+}
+
+void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
+{
+ context()->graphicsContext3D()->deleteFramebuffer(object);
+ m_colorAttachment = 0;
+ m_depthAttachment = 0;
+ m_stencilAttachment = 0;
+ m_depthStencilAttachment = 0;
+}
+
+bool WebGLFramebuffer::initializeRenderbuffers()
+{
+ ASSERT(object());
+ bool initColor = false, initDepth = false, initStencil = false;
+ unsigned long mask = 0;
+ if (isUninitialized(m_colorAttachment.get())) {
+ initColor = true;
+ mask |= GraphicsContext3D::COLOR_BUFFER_BIT;
+ }
+ if (isUninitialized(m_depthAttachment.get())) {
+ initDepth = true;
+ mask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
+ }
+ if (isUninitialized(m_stencilAttachment.get())) {
+ initStencil = true;
+ mask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
+ }
+ if (isUninitialized(m_depthStencilAttachment.get())) {
+ initDepth = true;
+ initStencil = true;
+ mask |= (GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT);
+ }
+ if (!initColor && !initDepth && !initStencil)
+ return true;
+
+ // We only clear un-initialized renderbuffers when they are ready to be
+ // read, i.e., when the framebuffer is complete.
+ GraphicsContext3D* g3d = context()->graphicsContext3D();
+ if (g3d->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
+ return false;
+
+ float colorClearValue[] = {0, 0, 0, 0}, depthClearValue = 0;
+ int stencilClearValue = 0;
+ unsigned char colorMask[] = {0, 0, 0, 0}, depthMask = 0;
+ unsigned int stencilMask = 0xffffffff;
+ bool isScissorEnabled = false;
+ bool isDitherEnabled = false;
+ if (initColor) {
+ g3d->getFloatv(GraphicsContext3D::COLOR_CLEAR_VALUE, colorClearValue);
+ g3d->getBooleanv(GraphicsContext3D::COLOR_WRITEMASK, colorMask);
+ g3d->clearColor(0, 0, 0, 0);
+ g3d->colorMask(true, true, true, true);
+ }
+ if (initDepth) {
+ g3d->getFloatv(GraphicsContext3D::DEPTH_CLEAR_VALUE, &depthClearValue);
+ g3d->getBooleanv(GraphicsContext3D::DEPTH_WRITEMASK, &depthMask);
+ g3d->clearDepth(0);
+ g3d->depthMask(true);
+ }
+ if (initStencil) {
+ g3d->getIntegerv(GraphicsContext3D::STENCIL_CLEAR_VALUE, &stencilClearValue);
+ g3d->getIntegerv(GraphicsContext3D::STENCIL_WRITEMASK, reinterpret_cast<int*>(&stencilMask));
+ g3d->clearStencil(0);
+ g3d->stencilMask(0xffffffff);
+ }
+ isScissorEnabled = g3d->isEnabled(GraphicsContext3D::SCISSOR_TEST);
+ g3d->disable(GraphicsContext3D::SCISSOR_TEST);
+ isDitherEnabled = g3d->isEnabled(GraphicsContext3D::DITHER);
+ g3d->disable(GraphicsContext3D::DITHER);
+
+ g3d->clear(mask);
+
+ if (initColor) {
+ g3d->clearColor(colorClearValue[0], colorClearValue[1], colorClearValue[2], colorClearValue[3]);
+ g3d->colorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
+ }
+ if (initDepth) {
+ g3d->clearDepth(depthClearValue);
+ g3d->depthMask(depthMask);
+ }
+ if (initStencil) {
+ g3d->clearStencil(stencilClearValue);
+ g3d->stencilMask(stencilMask);
+ }
+ if (isScissorEnabled)
+ g3d->enable(GraphicsContext3D::SCISSOR_TEST);
+ else
+ g3d->disable(GraphicsContext3D::SCISSOR_TEST);
+ if (isDitherEnabled)
+ g3d->enable(GraphicsContext3D::DITHER);
+ else
+ g3d->disable(GraphicsContext3D::DITHER);
+
+ if (initColor)
+ setInitialized(m_colorAttachment.get());
+ if (initDepth && initStencil && m_depthStencilAttachment)
+ setInitialized(m_depthStencilAttachment.get());
+ else {
+ if (initDepth)
+ setInitialized(m_depthAttachment.get());
+ if (initStencil)
+ setInitialized(m_stencilAttachment.get());
+ }
+ return true;
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.h b/Source/WebCore/html/canvas/WebGLFramebuffer.h
new file mode 100644
index 0000000..d801904
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.h
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ * 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 WebGLFramebuffer_h
+#define WebGLFramebuffer_h
+
+#include "WebGLObject.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLRenderbuffer;
+class WebGLTexture;
+
+class WebGLFramebuffer : public WebGLObject {
+public:
+ virtual ~WebGLFramebuffer() { deleteObject(); }
+
+ static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
+
+ void setAttachment(unsigned long attachment, unsigned long texTarget, WebGLTexture*, int level);
+ void setAttachment(unsigned long attachment, WebGLRenderbuffer*);
+ // If an object is attached to the framebuffer, remove it.
+ void removeAttachment(WebGLObject*);
+ WebGLObject* getAttachment(unsigned long) const;
+
+ unsigned long getColorBufferFormat() const;
+ int getWidth() const;
+ int getHeight() const;
+
+ // This should always be called before drawArray, drawElements, clear,
+ // readPixels, copyTexImage2D, copyTexSubImage2D if this framebuffer is
+ // currently bound.
+ // Return false if the framebuffer is incomplete; otherwise initialize
+ // the buffers if they haven't been initialized and
+ // needToInitializeRenderbuffers is true.
+ bool onAccess(bool needToInitializeRenderbuffers);
+
+ // Return false does not mean COMPLETE, might still be INCOMPLETE.
+ bool isIncomplete(bool checkInternalFormat) const;
+
+ bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
+
+ void setHasEverBeenBound() { m_hasEverBeenBound = true; }
+
+protected:
+ WebGLFramebuffer(WebGLRenderingContext*);
+
+ virtual void deleteObjectImpl(Platform3DObject);
+
+private:
+ virtual bool isFramebuffer() const { return true; }
+
+ // Return false if framebuffer is incomplete.
+ bool initializeRenderbuffers();
+
+ bool isColorAttached() const { return (m_colorAttachment && m_colorAttachment->object()); }
+ bool isDepthAttached() const { return (m_depthAttachment && m_depthAttachment->object()); }
+ bool isStencilAttached() const { return (m_stencilAttachment && m_stencilAttachment->object()); }
+ bool isDepthStencilAttached() const { return (m_depthStencilAttachment && m_depthStencilAttachment->object()); }
+
+ RefPtr<WebGLObject> m_colorAttachment;
+ RefPtr<WebGLObject> m_depthAttachment;
+ RefPtr<WebGLObject> m_stencilAttachment;
+ RefPtr<WebGLObject> m_depthStencilAttachment;
+
+ bool m_hasEverBeenBound;
+
+ unsigned long m_texTarget;
+ int m_texLevel;
+};
+
+} // namespace WebCore
+
+#endif // WebGLFramebuffer_h
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.idl b/Source/WebCore/html/canvas/WebGLFramebuffer.idl
new file mode 100644
index 0000000..8c1d9fd
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.idl
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ * 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.
+ */
+
+module html {
+ interface [Conditional=3D_CANVAS] WebGLFramebuffer {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.cpp b/Source/WebCore/html/canvas/WebGLGetInfo.cpp
new file mode 100644
index 0000000..6aff82f
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLGetInfo.cpp
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ * 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:
+ * 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(3D_CANVAS)
+
+#include "WebGLGetInfo.h"
+
+#include "Float32Array.h"
+#include "Int32Array.h"
+#include "Uint8Array.h"
+#include "WebGLBuffer.h"
+#include "WebGLFramebuffer.h"
+#include "WebGLProgram.h"
+#include "WebGLRenderbuffer.h"
+#include "WebGLTexture.h"
+
+namespace WebCore {
+
+WebGLGetInfo::WebGLGetInfo(bool value)
+ : m_type(kTypeBool)
+ , m_bool(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(const bool* value, int size)
+ : m_type(kTypeBoolArray)
+{
+ if (!value || size <=0)
+ return;
+ m_boolArray.resize(size);
+ for (int ii = 0; ii < size; ++ii)
+ m_boolArray[ii] = value[ii];
+}
+
+WebGLGetInfo::WebGLGetInfo(float value)
+ : m_type(kTypeFloat)
+ , m_float(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(long value)
+ : m_type(kTypeLong)
+ , m_long(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo()
+ : m_type(kTypeNull)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(const String& value)
+ : m_type(kTypeString)
+ , m_string(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(unsigned long value)
+ : m_type(kTypeUnsignedLong)
+ , m_unsignedLong(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLBuffer> value)
+ : m_type(kTypeWebGLBuffer)
+ , m_webglBuffer(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<Float32Array> value)
+ : m_type(kTypeWebGLFloatArray)
+ , m_webglFloatArray(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLFramebuffer> value)
+ : m_type(kTypeWebGLFramebuffer)
+ , m_webglFramebuffer(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<Int32Array> value)
+ : m_type(kTypeWebGLIntArray)
+ , m_webglIntArray(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLProgram> value)
+ : m_type(kTypeWebGLProgram)
+ , m_webglProgram(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLRenderbuffer> value)
+ : m_type(kTypeWebGLRenderbuffer)
+ , m_webglRenderbuffer(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLTexture> value)
+ : m_type(kTypeWebGLTexture)
+ , m_webglTexture(value)
+{
+}
+
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<Uint8Array> value)
+ : m_type(kTypeWebGLUnsignedByteArray)
+ , m_webglUnsignedByteArray(value)
+{
+}
+
+WebGLGetInfo::~WebGLGetInfo()
+{
+}
+
+WebGLGetInfo::Type WebGLGetInfo::getType() const
+{
+ return m_type;
+}
+
+bool WebGLGetInfo::getBool() const
+{
+ ASSERT(getType() == kTypeBool);
+ return m_bool;
+}
+
+const Vector<bool>& WebGLGetInfo::getBoolArray() const
+{
+ ASSERT(getType() == kTypeBoolArray);
+ return m_boolArray;
+}
+
+float WebGLGetInfo::getFloat() const
+{
+ ASSERT(getType() == kTypeFloat);
+ return m_float;
+}
+
+long WebGLGetInfo::getLong() const
+{
+ ASSERT(getType() == kTypeLong);
+ return m_long;
+}
+
+const String& WebGLGetInfo::getString() const
+{
+ ASSERT(getType() == kTypeString);
+ return m_string;
+}
+
+unsigned long WebGLGetInfo::getUnsignedLong() const
+{
+ ASSERT(getType() == kTypeUnsignedLong);
+ return m_unsignedLong;
+}
+
+PassRefPtr<WebGLBuffer> WebGLGetInfo::getWebGLBuffer() const
+{
+ ASSERT(getType() == kTypeWebGLBuffer);
+ return m_webglBuffer;
+}
+
+PassRefPtr<Float32Array> WebGLGetInfo::getWebGLFloatArray() const
+{
+ ASSERT(getType() == kTypeWebGLFloatArray);
+ return m_webglFloatArray;
+}
+
+PassRefPtr<WebGLFramebuffer> WebGLGetInfo::getWebGLFramebuffer() const
+{
+ ASSERT(getType() == kTypeWebGLFramebuffer);
+ return m_webglFramebuffer;
+}
+
+PassRefPtr<Int32Array> WebGLGetInfo::getWebGLIntArray() const
+{
+ ASSERT(getType() == kTypeWebGLIntArray);
+ return m_webglIntArray;
+}
+
+PassRefPtr<WebGLProgram> WebGLGetInfo::getWebGLProgram() const
+{
+ ASSERT(getType() == kTypeWebGLProgram);
+ return m_webglProgram;
+}
+
+PassRefPtr<WebGLRenderbuffer> WebGLGetInfo::getWebGLRenderbuffer() const
+{
+ ASSERT(getType() == kTypeWebGLRenderbuffer);
+ return m_webglRenderbuffer;
+}
+
+PassRefPtr<WebGLTexture> WebGLGetInfo::getWebGLTexture() const
+{
+ ASSERT(getType() == kTypeWebGLTexture);
+ return m_webglTexture;
+}
+
+PassRefPtr<Uint8Array> WebGLGetInfo::getWebGLUnsignedByteArray() const
+{
+ ASSERT(getType() == kTypeWebGLUnsignedByteArray);
+ return m_webglUnsignedByteArray;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.h b/Source/WebCore/html/canvas/WebGLGetInfo.h
new file mode 100644
index 0000000..caee520
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLGetInfo.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ * 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:
+ * 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 WebGLGetInfo_h
+#define WebGLGetInfo_h
+
+#include "Float32Array.h"
+#include "Int32Array.h"
+#include "PlatformString.h"
+#include "Uint8Array.h"
+#include "WebGLBuffer.h"
+#include "WebGLFramebuffer.h"
+#include "WebGLProgram.h"
+#include "WebGLRenderbuffer.h"
+#include "WebGLTexture.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+// A tagged union representing the result of get queries like
+// getParameter (encompassing getBooleanv, getIntegerv, getFloatv) and
+// similar variants. For reference counted types, increments and
+// decrements the reference count of the target object.
+
+class WebGLGetInfo {
+public:
+ enum Type {
+ kTypeBool,
+ kTypeBoolArray,
+ kTypeFloat,
+ kTypeLong,
+ kTypeNull,
+ kTypeString,
+ kTypeUnsignedLong,
+ kTypeWebGLBuffer,
+ kTypeWebGLFloatArray,
+ kTypeWebGLFramebuffer,
+ kTypeWebGLIntArray,
+ kTypeWebGLObjectArray,
+ kTypeWebGLProgram,
+ kTypeWebGLRenderbuffer,
+ kTypeWebGLTexture,
+ kTypeWebGLUnsignedByteArray
+ };
+
+ WebGLGetInfo(bool value);
+ WebGLGetInfo(const bool* value, int size);
+ WebGLGetInfo(float value);
+ WebGLGetInfo(long value);
+ // Represents the null value and type.
+ WebGLGetInfo();
+ WebGLGetInfo(const String& value);
+ WebGLGetInfo(unsigned long value);
+ WebGLGetInfo(PassRefPtr<WebGLBuffer> value);
+ WebGLGetInfo(PassRefPtr<Float32Array> value);
+ WebGLGetInfo(PassRefPtr<WebGLFramebuffer> value);
+ WebGLGetInfo(PassRefPtr<Int32Array> value);
+ // FIXME: implement WebGLObjectArray
+ // WebGLGetInfo(PassRefPtr<WebGLObjectArray> value);
+ WebGLGetInfo(PassRefPtr<WebGLProgram> value);
+ WebGLGetInfo(PassRefPtr<WebGLRenderbuffer> value);
+ WebGLGetInfo(PassRefPtr<WebGLTexture> value);
+ WebGLGetInfo(PassRefPtr<Uint8Array> value);
+
+ virtual ~WebGLGetInfo();
+
+ Type getType() const;
+
+ bool getBool() const;
+ const Vector<bool>& getBoolArray() const;
+ float getFloat() const;
+ long getLong() const;
+ const String& getString() const;
+ unsigned long getUnsignedLong() const;
+ PassRefPtr<WebGLBuffer> getWebGLBuffer() const;
+ PassRefPtr<Float32Array> getWebGLFloatArray() const;
+ PassRefPtr<WebGLFramebuffer> getWebGLFramebuffer() const;
+ PassRefPtr<Int32Array> getWebGLIntArray() const;
+ // FIXME: implement WebGLObjectArray
+ // PassRefPtr<WebGLObjectArray> getWebGLObjectArray() const;
+ PassRefPtr<WebGLProgram> getWebGLProgram() const;
+ PassRefPtr<WebGLRenderbuffer> getWebGLRenderbuffer() const;
+ PassRefPtr<WebGLTexture> getWebGLTexture() const;
+ PassRefPtr<Uint8Array> getWebGLUnsignedByteArray() const;
+
+private:
+ Type m_type;
+ bool m_bool;
+ Vector<bool> m_boolArray;
+ float m_float;
+ long m_long;
+ String m_string;
+ unsigned long m_unsignedLong;
+ RefPtr<WebGLBuffer> m_webglBuffer;
+ RefPtr<Float32Array> m_webglFloatArray;
+ RefPtr<WebGLFramebuffer> m_webglFramebuffer;
+ RefPtr<Int32Array> m_webglIntArray;
+ // FIXME: implement WebGLObjectArray
+ // RefPtr<WebGLObjectArray> m_webglObjectArray;
+ RefPtr<WebGLProgram> m_webglProgram;
+ RefPtr<WebGLRenderbuffer> m_webglRenderbuffer;
+ RefPtr<WebGLTexture> m_webglTexture;
+ RefPtr<Uint8Array> m_webglUnsignedByteArray;
+};
+
+} // namespace WebCore
+
+#endif // WebGLGetInfo_h
diff --git a/Source/WebCore/html/canvas/WebGLObject.cpp b/Source/WebCore/html/canvas/WebGLObject.cpp
new file mode 100644
index 0000000..41ad0f1
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLObject.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ * 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(3D_CANVAS)
+
+#include "WebGLObject.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+WebGLObject::WebGLObject(WebGLRenderingContext* context)
+ : m_object(0)
+ , m_context(context)
+ , m_attachmentCount(0)
+ , m_deleted(false)
+{
+}
+
+WebGLObject::~WebGLObject()
+{
+ if (m_context)
+ m_context->removeObject(this);
+}
+
+void WebGLObject::setObject(Platform3DObject object)
+{
+ // object==0 && m_deleted==false indicating an uninitialized state;
+ ASSERT(!m_object && !m_deleted);
+ m_object = object;
+}
+
+void WebGLObject::deleteObject()
+{
+ m_deleted = true;
+ if (!m_context || !m_object)
+ return;
+ if (!m_attachmentCount) {
+ m_context->graphicsContext3D()->makeContextCurrent();
+ deleteObjectImpl(m_object);
+ m_object = 0;
+ }
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebGLObject.h b/Source/WebCore/html/canvas/WebGLObject.h
new file mode 100644
index 0000000..3bb9f29
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLObject.h
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ * 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 WebGLObject_h
+#define WebGLObject_h
+
+#include "GraphicsContext3D.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLRenderingContext;
+
+class WebGLObject : public RefCounted<WebGLObject> {
+public:
+ virtual ~WebGLObject();
+
+ Platform3DObject object() const { return m_object; }
+
+ // deleteObject may not always delete the OpenGL resource. For programs and
+ // shaders, deletion is delayed until they are no longer attached.
+ // FIXME: revisit this when resource sharing between contexts are implemented.
+ void deleteObject();
+
+ void detachContext()
+ {
+ m_attachmentCount = 0; // Make sure OpenGL resource is deleted.
+ deleteObject();
+ m_context = 0;
+ }
+
+ WebGLRenderingContext* context() const { return m_context; }
+
+ virtual bool isBuffer() const { return false; }
+ virtual bool isFramebuffer() const { return false; }
+ virtual bool isProgram() const { return false; }
+ virtual bool isRenderbuffer() const { return false; }
+ virtual bool isShader() const { return false; }
+ virtual bool isTexture() const { return false; }
+
+ void onAttached() { ++m_attachmentCount; }
+ void onDetached()
+ {
+ if (m_attachmentCount)
+ --m_attachmentCount;
+ if (m_deleted)
+ deleteObject();
+ }
+
+ // This indicates whether the client side issue a delete call already, not
+ // whether the OpenGL resource is deleted.
+ // object()==0 indicates the OpenGL resource is deleted.
+ bool isDeleted() { return m_deleted; }
+
+protected:
+ WebGLObject(WebGLRenderingContext*);
+
+ // setObject should be only called once right after creating a WebGLObject.
+ void setObject(Platform3DObject);
+
+ // deleteObjectImpl should be only called once to delete the OpenGL resource.
+ virtual void deleteObjectImpl(Platform3DObject) = 0;
+
+private:
+ Platform3DObject m_object;
+ WebGLRenderingContext* m_context;
+ unsigned m_attachmentCount;
+ bool m_deleted;
+};
+
+} // namespace WebCore
+
+#endif // WebGLObject_h
diff --git a/Source/WebCore/html/canvas/WebGLProgram.cpp b/Source/WebCore/html/canvas/WebGLProgram.cpp
new file mode 100644
index 0000000..b2c2086
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLProgram.cpp
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ * 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(3D_CANVAS)
+
+#include "WebGLProgram.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContext* ctx)
+{
+ return adoptRef(new WebGLProgram(ctx));
+}
+
+WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
+ : WebGLObject(ctx)
+ , m_linkStatus(false)
+ , m_linkCount(0)
+{
+ setObject(context()->graphicsContext3D()->createProgram());
+}
+
+void WebGLProgram::deleteObjectImpl(Platform3DObject obj)
+{
+ context()->graphicsContext3D()->deleteProgram(obj);
+ if (m_vertexShader) {
+ m_vertexShader->onDetached();
+ m_vertexShader = 0;
+ }
+ if (m_fragmentShader) {
+ m_fragmentShader->onDetached();
+ m_fragmentShader = 0;
+ }
+}
+
+bool WebGLProgram::cacheActiveAttribLocations()
+{
+ m_activeAttribLocations.clear();
+ if (!object())
+ return false;
+ GraphicsContext3D* context3d = context()->graphicsContext3D();
+
+ // Assume link status has already been cached.
+ if (!m_linkStatus)
+ return false;
+
+ int numAttribs = 0;
+ context3d->getProgramiv(object(), GraphicsContext3D::ACTIVE_ATTRIBUTES, &numAttribs);
+ m_activeAttribLocations.resize(static_cast<size_t>(numAttribs));
+ for (int i = 0; i < numAttribs; ++i) {
+ ActiveInfo info;
+ context3d->getActiveAttrib(object(), i, info);
+ m_activeAttribLocations[i] = context3d->getAttribLocation(object(), info.name.charactersWithNullTermination());
+ }
+
+ return true;
+}
+
+int WebGLProgram::numActiveAttribLocations() const
+{
+ return static_cast<int>(m_activeAttribLocations.size());
+}
+
+int WebGLProgram::getActiveAttribLocation(int index) const
+{
+ if (index < 0 || index >= numActiveAttribLocations())
+ return -1;
+ return m_activeAttribLocations[static_cast<size_t>(index)];
+}
+
+bool WebGLProgram::isUsingVertexAttrib0() const
+{
+ for (int ii = 0; ii < numActiveAttribLocations(); ++ii) {
+ if (!getActiveAttribLocation(ii))
+ return true;
+ }
+ return false;
+}
+
+WebGLShader* WebGLProgram::getAttachedShader(GraphicsContext3D::WebGLEnumType type)
+{
+ switch (type) {
+ case GraphicsContext3D::VERTEX_SHADER:
+ return m_vertexShader.get();
+ case GraphicsContext3D::FRAGMENT_SHADER:
+ return m_fragmentShader.get();
+ default:
+ return 0;
+ }
+}
+
+bool WebGLProgram::attachShader(WebGLShader* shader)
+{
+ if (!shader || !shader->object())
+ return false;
+ switch (shader->getType()) {
+ case GraphicsContext3D::VERTEX_SHADER:
+ if (m_vertexShader)
+ return false;
+ m_vertexShader = shader;
+ return true;
+ case GraphicsContext3D::FRAGMENT_SHADER:
+ if (m_fragmentShader)
+ return false;
+ m_fragmentShader = shader;
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool WebGLProgram::detachShader(WebGLShader* shader)
+{
+ if (!shader || !shader->object())
+ return false;
+ switch (shader->getType()) {
+ case GraphicsContext3D::VERTEX_SHADER:
+ if (m_vertexShader != shader)
+ return false;
+ m_vertexShader = 0;
+ return true;
+ case GraphicsContext3D::FRAGMENT_SHADER:
+ if (m_fragmentShader != shader)
+ return false;
+ m_fragmentShader = 0;
+ return true;
+ default:
+ return false;
+ }
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebGLProgram.h b/Source/WebCore/html/canvas/WebGLProgram.h
new file mode 100644
index 0000000..6b89ae5
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLProgram.h
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ * 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 WebGLProgram_h
+#define WebGLProgram_h
+
+#include "WebGLObject.h"
+
+#include "WebGLShader.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class WebGLProgram : public WebGLObject {
+public:
+ virtual ~WebGLProgram() { deleteObject(); }
+
+ static PassRefPtr<WebGLProgram> create(WebGLRenderingContext*);
+
+ // cacheActiveAttribLocation() is only called once after linkProgram()
+ // succeeds.
+ bool cacheActiveAttribLocations();
+ int numActiveAttribLocations() const;
+ int getActiveAttribLocation(int index) const;
+
+ bool isUsingVertexAttrib0() const;
+
+ bool getLinkStatus() const { return m_linkStatus; }
+ void setLinkStatus(bool status) { m_linkStatus = status; }
+
+ unsigned long getLinkCount() const { return m_linkCount; }
+
+ // This is to be called everytime after the program is successfully linked.
+ // We don't deal with integer overflow here, assuming in reality a program
+ // will never be linked so many times.
+ void increaseLinkCount() { ++m_linkCount; }
+
+ WebGLShader* getAttachedShader(GraphicsContext3D::WebGLEnumType);
+ bool attachShader(WebGLShader*);
+ bool detachShader(WebGLShader*);
+
+protected:
+ WebGLProgram(WebGLRenderingContext*);
+
+ virtual void deleteObjectImpl(Platform3DObject);
+
+private:
+ virtual bool isProgram() const { return true; }
+
+ Vector<int> m_activeAttribLocations;
+
+ bool m_linkStatus;
+
+ // This is used to track whether a WebGLUniformLocation belongs to this
+ // program or not.
+ unsigned long m_linkCount;
+
+ RefPtr<WebGLShader> m_vertexShader;
+ RefPtr<WebGLShader> m_fragmentShader;
+};
+
+} // namespace WebCore
+
+#endif // WebGLProgram_h
diff --git a/Source/WebCore/html/canvas/WebGLProgram.idl b/Source/WebCore/html/canvas/WebGLProgram.idl
new file mode 100644
index 0000000..562fa3a
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLProgram.idl
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ * 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.
+ */
+
+module html {
+ interface [Conditional=3D_CANVAS] WebGLProgram {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp b/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
new file mode 100644
index 0000000..03a419a
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ * 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(3D_CANVAS)
+
+#include "WebGLRenderbuffer.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContext* ctx)
+{
+ return adoptRef(new WebGLRenderbuffer(ctx));
+}
+
+WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
+ : WebGLObject(ctx)
+ , m_internalFormat(GraphicsContext3D::RGBA4)
+ , m_initialized(false)
+ , m_width(0)
+ , m_height(0)
+ , m_isValid(true)
+ , m_hasEverBeenBound(false)
+{
+ setObject(context()->graphicsContext3D()->createRenderbuffer());
+}
+
+void WebGLRenderbuffer::deleteObjectImpl(Platform3DObject object)
+{
+ context()->graphicsContext3D()->deleteRenderbuffer(object);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.h b/Source/WebCore/html/canvas/WebGLRenderbuffer.h
new file mode 100644
index 0000000..a432f9d
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.h
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ * 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 WebGLRenderbuffer_h
+#define WebGLRenderbuffer_h
+
+#include "WebGLObject.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLRenderbuffer : public WebGLObject {
+public:
+ virtual ~WebGLRenderbuffer() { deleteObject(); }
+
+ static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContext*);
+
+ void setInternalFormat(unsigned long internalformat)
+ {
+ m_internalFormat = internalformat;
+ m_initialized = false;
+ }
+ unsigned long getInternalFormat() const { return m_internalFormat; }
+
+ void setSize(unsigned long width, unsigned long height)
+ {
+ m_width = width;
+ m_height = height;
+ }
+ unsigned long getWidth() const { return m_width; }
+ unsigned long getHeight() const { return m_height; }
+
+ void setIsValid(bool isValid) { m_isValid = isValid; }
+ bool isValid() const { return m_isValid; }
+
+ bool isInitialized() const { return m_initialized; }
+ void setInitialized() { m_initialized = true; }
+
+ bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
+
+ void setHasEverBeenBound() { m_hasEverBeenBound = true; }
+
+protected:
+ WebGLRenderbuffer(WebGLRenderingContext*);
+
+ virtual void deleteObjectImpl(Platform3DObject);
+
+private:
+ virtual bool isRenderbuffer() const { return true; }
+
+ unsigned long m_internalFormat;
+ bool m_initialized;
+ unsigned long m_width, m_height;
+ bool m_isValid; // This is only false if internalFormat is DEPTH_STENCIL and packed_depth_stencil is not supported.
+
+ bool m_hasEverBeenBound;
+};
+
+} // namespace WebCore
+
+#endif // WebGLRenderbuffer_h
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.idl b/Source/WebCore/html/canvas/WebGLRenderbuffer.idl
new file mode 100644
index 0000000..2524433
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.idl
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ * 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.
+ */
+
+module html {
+ interface [Conditional=3D_CANVAS] WebGLRenderbuffer {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
new file mode 100644
index 0000000..4ffd400
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -0,0 +1,4424 @@
+/*
+ * 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.
+ * 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(3D_CANVAS)
+
+#include "WebGLRenderingContext.h"
+
+#include "CachedImage.h"
+#include "CanvasPixelArray.h"
+#include "CheckedInt.h"
+#include "WebKitLoseContext.h"
+#include "Console.h"
+#include "DOMWindow.h"
+#include "Extensions3D.h"
+#include "FrameView.h"
+#include "HTMLCanvasElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLVideoElement.h"
+#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "IntSize.h"
+#include "NotImplemented.h"
+#include "OESTextureFloat.h"
+#include "RenderBox.h"
+#include "RenderLayer.h"
+#include "Uint16Array.h"
+#include "WebGLActiveInfo.h"
+#include "WebGLBuffer.h"
+#include "WebGLContextAttributes.h"
+#include "WebGLContextEvent.h"
+#include "WebGLFramebuffer.h"
+#include "WebGLProgram.h"
+#include "WebGLRenderbuffer.h"
+#include "WebGLShader.h"
+#include "WebGLTexture.h"
+#include "WebGLUniformLocation.h"
+
+#include <wtf/ByteArray.h>
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/PassOwnArrayPtr.h>
+
+namespace WebCore {
+
+const double secondsBetweenRestoreAttempts = 1.0;
+
+namespace {
+
+ Platform3DObject objectOrZero(WebGLObject* object)
+ {
+ return object ? object->object() : 0;
+ }
+
+ void clip1D(long start, long range, long sourceRange, long* clippedStart, long* clippedRange)
+ {
+ ASSERT(clippedStart && clippedRange);
+ if (start < 0) {
+ range += start;
+ start = 0;
+ }
+ long 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(long x, long y, long width, long height,
+ long sourceWidth, long sourceHeight,
+ long* clippedX, long* clippedY, long* clippedWidth, long*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);
+ }
+
+ // 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;
+ }
+
+} // 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;
+};
+
+void WebGLRenderingContext::WebGLRenderingContextRestoreTimer::fired()
+{
+ // Timer is started when m_contextLost is false. It will first call
+ // onLostContext, which will set m_contextLost to true. Then it will keep
+ // calling restoreContext and reschedule itself until m_contextLost is back
+ // to false.
+ if (!m_context->m_contextLost) {
+ m_context->onLostContext();
+ startOneShot(secondsBetweenRestoreAttempts);
+ } else {
+ // The rendering context is not restored if there is no handler for
+ // the context restored event.
+ if (!m_context->canvas()->hasEventListeners(eventNames().webglcontextrestoredEvent))
+ return;
+
+ m_context->restoreContext();
+ if (m_context->m_contextLost)
+ startOneShot(secondsBetweenRestoreAttempts);
+ }
+}
+
+PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
+{
+ HostWindow* hostWindow = canvas->document()->view()->root()->hostWindow();
+ GraphicsContext3D::Attributes attributes = attrs ? attrs->attributes() : GraphicsContext3D::Attributes();
+ RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes, hostWindow));
+
+ if (!context) {
+ canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Could not create a WebGL context."));
+ return 0;
+ }
+
+ return new WebGLRenderingContext(canvas, context, attributes);
+}
+
+WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context,
+ GraphicsContext3D::Attributes attributes)
+ : CanvasRenderingContext(passedCanvas)
+ , m_context(context)
+ , m_restoreTimer(this)
+ , m_videoCache(4)
+ , m_contextLost(false)
+ , m_attributes(attributes)
+{
+ ASSERT(m_context);
+ setupFlags();
+ initializeNewContext();
+}
+
+void WebGLRenderingContext::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 = 0;
+ m_boundElementArrayBuffer = 0;
+ m_currentProgram = 0;
+ m_framebufferBinding = 0;
+ m_renderbufferBinding = 0;
+ m_stencilMask = 0xFFFFFFFF;
+ m_stencilMaskBack = 0xFFFFFFFF;
+ m_stencilFuncRef = 0;
+ m_stencilFuncRefBack = 0;
+ m_stencilFuncMask = 0xFFFFFFFF;
+ m_stencilFuncMaskBack = 0xFFFFFFFF;
+ m_vertexAttribState.clear();
+
+ int numCombinedTextureImageUnits = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
+ m_textureUnits.clear();
+ m_textureUnits.resize(numCombinedTextureImageUnits);
+
+ int 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);
+
+ if (!isGLES2NPOTStrict())
+ createFallbackBlackTextures1x1();
+ if (!isGLES2Compliant())
+ initVertexAttrib0();
+
+ m_context->reshape(canvas()->width(), canvas()->height());
+ m_context->viewport(0, 0, canvas()->width(), canvas()->height());
+}
+
+void WebGLRenderingContext::setupFlags()
+{
+ ASSERT(m_context);
+
+ m_isGLES2Compliant = m_context->isGLES2Compliant();
+ m_isErrorGeneratedOnOutOfBoundsAccesses = m_context->getExtensions()->supports("GL_CHROMIUM_strict_attribs");
+ m_isResourceSafe = m_context->getExtensions()->supports("GL_CHROMIUM_resource_safe");
+ if (m_isGLES2Compliant) {
+ m_isGLES2NPOTStrict = !m_context->getExtensions()->supports("GL_OES_texture_npot");
+ m_isDepthStencilSupported = m_context->getExtensions()->supports("GL_OES_packed_depth_stencil");
+ } else {
+ m_isGLES2NPOTStrict = !m_context->getExtensions()->supports("GL_ARB_texture_non_power_of_two");
+ m_isDepthStencilSupported = m_context->getExtensions()->supports("GL_EXT_packed_depth_stencil");
+ }
+}
+
+WebGLRenderingContext::~WebGLRenderingContext()
+{
+ detachAndRemoveAllObjects();
+}
+
+void WebGLRenderingContext::markContextChanged()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
+ renderBox->layer()->contentChanged(RenderLayer::CanvasChanged);
+ else {
+#endif
+ if (!m_markedCanvasDirty)
+ canvas()->didDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
+#if USE(ACCELERATED_COMPOSITING)
+ }
+#endif
+ m_markedCanvasDirty = true;
+}
+
+void WebGLRenderingContext::paintRenderingResultsToCanvas()
+{
+ if (!m_markedCanvasDirty)
+ return;
+ canvas()->clearCopiedImage();
+ m_markedCanvasDirty = false;
+ m_context->paintRenderingResultsToCanvas(this);
+}
+
+bool WebGLRenderingContext::paintsIntoCanvasBuffer() const
+{
+ return m_context->paintsIntoCanvasBuffer();
+}
+
+void WebGLRenderingContext::reshape(int width, int height)
+{
+ if (m_needsUpdate) {
+#if USE(ACCELERATED_COMPOSITING)
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasLayer())
+ renderBox->layer()->contentChanged(RenderLayer::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).
+ m_context->reshape(width, height);
+}
+
+int WebGLRenderingContext::sizeInBytes(int type)
+{
+ return m_context->sizeInBytes(type);
+}
+
+void WebGLRenderingContext::activeTexture(unsigned long texture, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0;
+ m_context->activeTexture(texture);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(program) || !validateWebGLObject(shader))
+ return;
+ if (!program->attachShader(shader)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ m_context->attachShader(objectOrZero(program), objectOrZero(shader));
+ shader->onAttached();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(program))
+ return;
+ if (!validateString(name))
+ return;
+ m_context->bindAttribLocation(objectOrZero(program), index, name);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ if (buffer && buffer->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ if (target == GraphicsContext3D::ARRAY_BUFFER)
+ m_boundArrayBuffer = buffer;
+ else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
+ m_boundElementArrayBuffer = buffer;
+ else {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+
+ m_context->bindBuffer(target, objectOrZero(buffer));
+ if (buffer)
+ buffer->setTarget(target);
+ cleanupAfterGraphicsCall(false);
+}
+
+
+void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ if (buffer && buffer->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ m_framebufferBinding = buffer;
+ m_context->bindFramebuffer(target, objectOrZero(buffer));
+ if (buffer)
+ buffer->setHasEverBeenBound();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ if (renderBuffer && renderBuffer->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (target != GraphicsContext3D::RENDERBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ m_renderbufferBinding = renderBuffer;
+ m_context->bindRenderbuffer(target, objectOrZero(renderBuffer));
+ if (renderBuffer)
+ renderBuffer->setHasEverBeenBound();
+ cleanupAfterGraphicsCall(false);
+}
+
+
+void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* texture, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ if (texture && texture->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ int maxLevel = 0;
+ if (target == GraphicsContext3D::TEXTURE_2D) {
+ m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
+ maxLevel = m_maxTextureLevel;
+ } else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
+ m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
+ maxLevel = m_maxCubeMapTextureLevel;
+ } else {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ 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(float red, float green, float blue, float alpha)
+{
+ if (isContextLost())
+ return;
+ m_context->blendColor(red, green, blue, alpha);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::blendEquation(unsigned long mode)
+{
+ if (isContextLost() || !validateBlendEquation(mode))
+ return;
+ m_context->blendEquation(mode);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha)
+{
+ if (isContextLost() || !validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha))
+ return;
+ m_context->blendEquationSeparate(modeRGB, modeAlpha);
+ cleanupAfterGraphicsCall(false);
+}
+
+
+void WebGLRenderingContext::blendFunc(unsigned long sfactor, unsigned long dfactor)
+{
+ if (isContextLost() || !validateBlendFuncFactors(sfactor, dfactor))
+ return;
+ m_context->blendFunc(sfactor, dfactor);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha)
+{
+ if (isContextLost() || !validateBlendFuncFactors(srcRGB, dstRGB))
+ return;
+ m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned long usage, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
+ if (!buffer)
+ return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferData(size)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ }
+
+ m_context->bufferData(target, size, usage);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferData(unsigned long target, ArrayBuffer* data, unsigned long usage, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
+ if (!buffer)
+ return;
+ if (!data) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferData(data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ }
+
+ m_context->bufferData(target, data->byteLength(), data->data(), usage);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
+ if (!buffer)
+ return;
+ if (!data) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferData(data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ }
+
+ m_context->bufferData(target, data->byteLength(), data->baseAddress(), usage);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBuffer* data, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
+ if (!buffer)
+ return;
+ if (!data)
+ return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferSubData(offset, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ }
+
+ m_context->bufferSubData(target, offset, data->byteLength(), data->data());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBufferView* data, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
+ if (!buffer)
+ return;
+ if (!data)
+ return;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ if (!buffer->associateBufferSubData(offset, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ }
+
+ m_context->bufferSubData(target, offset, data->byteLength(), data->baseAddress());
+ cleanupAfterGraphicsCall(false);
+}
+
+unsigned long WebGLRenderingContext::checkFramebufferStatus(unsigned long target)
+{
+ if (isContextLost())
+ return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+ if (!m_framebufferBinding || !m_framebufferBinding->object())
+ return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
+ if (m_framebufferBinding->isIncomplete(true))
+ return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
+ unsigned long result = m_context->checkFramebufferStatus(target);
+ cleanupAfterGraphicsCall(false);
+ return result;
+}
+
+void WebGLRenderingContext::clear(unsigned long mask)
+{
+ if (isContextLost())
+ return;
+ if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
+ m_context->clear(mask);
+ cleanupAfterGraphicsCall(true);
+}
+
+void WebGLRenderingContext::clearColor(float r, float g, float b, float a)
+{
+ if (isContextLost())
+ return;
+ if (isnan(r))
+ r = 0;
+ if (isnan(g))
+ g = 0;
+ if (isnan(b))
+ b = 0;
+ if (isnan(a))
+ a = 1;
+ m_context->clearColor(r, g, b, a);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::clearDepth(float depth)
+{
+ if (isContextLost())
+ return;
+ m_context->clearDepth(depth);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::clearStencil(long s)
+{
+ if (isContextLost())
+ return;
+ m_context->clearStencil(s);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::colorMask(bool red, bool green, bool blue, bool alpha)
+{
+ if (isContextLost())
+ return;
+ m_context->colorMask(red, green, blue, alpha);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(shader))
+ return;
+ m_context->compileShader(objectOrZero(shader));
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, long width, long height, long border)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncParameters(target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
+ return;
+ WebGLTexture* tex = validateTextureBinding(target, true);
+ if (!tex)
+ return;
+ if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
+ if (isResourceSafe())
+ m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ else {
+ long clippedX, clippedY, 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);
+ 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(unsigned long target, long level, long xoffset, long yoffset, long x, long y, long width, long height)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncLevel(target, level))
+ return;
+ WebGLTexture* tex = validateTextureBinding(target, true);
+ if (!tex)
+ return;
+ if (!validateSize(xoffset, yoffset) || !validateSize(width, height))
+ return;
+ if (xoffset + width > tex->getWidth(target, level) || yoffset + height > tex->getHeight(target, level)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (!isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(target, level), getBoundFramebufferColorFormat())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
+ if (isResourceSafe())
+ m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+ else {
+ long clippedX, clippedY, clippedWidth, clippedHeight;
+ if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
+ unsigned long format = tex->getInternalFormat(target, level);
+ unsigned long type = tex->getType(target, level);
+ unsigned int componentsPerPixel = 0;
+ unsigned int bytesPerComponent = 0;
+ bool valid = m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent);
+ if (!valid) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ OwnArrayPtr<unsigned char> zero;
+ if (width && height) {
+ unsigned long size = componentsPerPixel * bytesPerComponent * width * height;
+ zero = adoptArrayPtr(new unsigned char[size]);
+ if (!zero) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ memset(zero.get(), 0, size);
+ }
+ if (zero)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+ m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, zero.get());
+ if (zero)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+ 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);
+ }
+ cleanupAfterGraphicsCall(false);
+}
+
+PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
+ addObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
+ addObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLTexture> o = WebGLTexture::create(this);
+ addObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLProgram> o = WebGLProgram::create(this);
+ addObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
+{
+ if (isContextLost())
+ return 0;
+ RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
+ addObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(unsigned long type, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return 0;
+ if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+
+ RefPtr<WebGLShader> o = WebGLShader::create(this, static_cast<GraphicsContext3D::WebGLEnumType>(type));
+ addObject(o.get());
+ return o;
+}
+
+void WebGLRenderingContext::cullFace(unsigned long mode)
+{
+ if (isContextLost())
+ return;
+ m_context->cullFace(mode);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
+{
+ if (isContextLost() || !buffer)
+ return;
+
+ buffer->deleteObject();
+
+ if (!isGLES2Compliant()) {
+ VertexAttribState& state = m_vertexAttribState[0];
+ if (buffer == state.bufferBinding) {
+ state.bufferBinding = m_vertexAttrib0Buffer;
+ state.bytesPerElement = 0;
+ state.size = 4;
+ state.type = GraphicsContext3D::FLOAT;
+ state.normalized = false;
+ state.stride = 16;
+ state.originalStride = 0;
+ state.offset = 0;
+ }
+ }
+}
+
+void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
+{
+ if (isContextLost() || !framebuffer)
+ return;
+ if (framebuffer == m_framebufferBinding) {
+ m_framebufferBinding = 0;
+ // Have to call bindFramebuffer here to bind back to internal fbo.
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
+ }
+ framebuffer->deleteObject();
+}
+
+void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
+{
+ if (isContextLost() || !program)
+ return;
+ if (program->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (!program->object())
+ return;
+ program->deleteObject();
+}
+
+void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
+{
+ if (isContextLost() || !renderbuffer)
+ return;
+ if (renderbuffer == m_renderbufferBinding)
+ m_renderbufferBinding = 0;
+ renderbuffer->deleteObject();
+ if (m_framebufferBinding)
+ m_framebufferBinding->removeAttachment(renderbuffer);
+}
+
+void WebGLRenderingContext::deleteShader(WebGLShader* shader)
+{
+ if (isContextLost() || !shader)
+ return;
+
+ shader->deleteObject();
+}
+
+void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
+{
+ if (isContextLost() || !texture)
+ return;
+
+ texture->deleteObject();
+ if (m_framebufferBinding)
+ m_framebufferBinding->removeAttachment(texture);
+}
+
+void WebGLRenderingContext::depthFunc(unsigned long func)
+{
+ if (isContextLost())
+ return;
+ m_context->depthFunc(func);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::depthMask(bool flag)
+{
+ if (isContextLost())
+ return;
+ m_context->depthMask(flag);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::depthRange(float zNear, float zFar)
+{
+ if (isContextLost())
+ return;
+ if (zNear > zFar) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ m_context->depthRange(zNear, zFar);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(program) || !validateWebGLObject(shader))
+ return;
+ if (!program->detachShader(shader)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ m_context->detachShader(objectOrZero(program), objectOrZero(shader));
+ shader->onDetached();
+ cleanupAfterGraphicsCall(false);
+}
+
+
+void WebGLRenderingContext::disable(unsigned long cap)
+{
+ if (isContextLost() || !validateCapability(cap))
+ return;
+ m_context->disable(cap);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::disableVertexAttribArray(unsigned long index, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+
+ if (index < m_vertexAttribState.size())
+ m_vertexAttribState[index].enabled = false;
+
+ if (index > 0 || isGLES2Compliant()) {
+ m_context->disableVertexAttribArray(index);
+ cleanupAfterGraphicsCall(false);
+ }
+}
+
+bool WebGLRenderingContext::validateElementArraySize(unsigned long count, unsigned long type, long offset)
+{
+ if (!m_boundElementArrayBuffer)
+ return false;
+
+ if (offset < 0)
+ return false;
+
+ unsigned long uoffset = static_cast<unsigned long>(offset);
+
+ if (type == GraphicsContext3D::UNSIGNED_SHORT) {
+ // For an unsigned short array, offset must be divisible by 2 for alignment reasons.
+ if (uoffset & 1)
+ return false;
+
+ // Make uoffset an element offset.
+ uoffset /= 2;
+
+ unsigned long n = m_boundElementArrayBuffer->byteLength() / 2;
+ if (uoffset > n || count > n - uoffset)
+ return false;
+ } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
+ unsigned long n = m_boundElementArrayBuffer->byteLength();
+ if (uoffset > n || count > n - uoffset)
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateIndexArrayConservative(unsigned long type, long& 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.
+
+ if (!m_boundElementArrayBuffer)
+ return false;
+
+ unsigned numElements = m_boundElementArrayBuffer->byteLength();
+ // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
+ if (!numElements)
+ return false;
+ const ArrayBuffer* buffer = m_boundElementArrayBuffer->elementArrayBuffer();
+ ASSERT(buffer);
+
+ long maxIndex = m_boundElementArrayBuffer->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 unsigned char* p = static_cast<const unsigned char*>(buffer->data());
+ for (unsigned i = 0; i < numElements; i++)
+ maxIndex = max(maxIndex, static_cast<long>(p[i]));
+ break;
+ }
+ case GraphicsContext3D::UNSIGNED_SHORT: {
+ numElements /= sizeof(unsigned short);
+ const unsigned short* p = static_cast<const unsigned short*>(buffer->data());
+ for (unsigned i = 0; i < numElements; i++)
+ maxIndex = max(maxIndex, static_cast<long>(p[i]));
+ break;
+ }
+ default:
+ return false;
+ }
+ m_boundElementArrayBuffer->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(unsigned long count, unsigned long type, long offset, long& numElementsRequired)
+{
+ long lastIndex = -1;
+
+ if (!m_boundElementArrayBuffer)
+ return false;
+
+ if (!count) {
+ numElementsRequired = 0;
+ return true;
+ }
+
+ if (!m_boundElementArrayBuffer->elementArrayBuffer())
+ return false;
+
+ unsigned long uoffset = static_cast<unsigned long>(offset);
+ unsigned long n = count;
+
+ if (type == GraphicsContext3D::UNSIGNED_SHORT) {
+ // Make uoffset an element offset.
+ uoffset /= 2;
+ const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
+ while (n-- > 0) {
+ if (*p > lastIndex)
+ lastIndex = *p;
+ ++p;
+ }
+ } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
+ const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->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 WebGLRenderingContext::validateRenderingState(long numElementsRequired)
+{
+ if (!m_currentProgram)
+ return false;
+
+ int numAttribStates = static_cast<int>(m_vertexAttribState.size());
+
+ // Look in each enabled vertex attrib and check if they've been bound to a buffer.
+ for (int i = 0; i < numAttribStates; ++i) {
+ if (m_vertexAttribState[i].enabled
+ && (!m_vertexAttribState[i].bufferBinding || !m_vertexAttribState[i].bufferBinding->object()))
+ return false;
+ }
+
+ if (numElementsRequired <= 0)
+ return true;
+
+ // Look in each consumed vertex attrib (by the current program) and find the smallest buffer size
+ long smallestNumElements = LONG_MAX;
+ int numActiveAttribLocations = m_currentProgram->numActiveAttribLocations();
+ for (int i = 0; i < numActiveAttribLocations; ++i) {
+ int loc = m_currentProgram->getActiveAttribLocation(i);
+ if (loc >=0 && loc < numAttribStates) {
+ const VertexAttribState& state = m_vertexAttribState[loc];
+ if (state.enabled) {
+ // 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.
+ long bytesRemaining = state.bufferBinding->byteLength() - state.offset;
+ long numElements = 0;
+ if (bytesRemaining >= state.bytesPerElement)
+ numElements = 1 + (bytesRemaining - state.bytesPerElement) / state.stride;
+ if (numElements < smallestNumElements)
+ smallestNumElements = numElements;
+ }
+ }
+ }
+
+ if (smallestNumElements == LONG_MAX)
+ smallestNumElements = 0;
+
+ return numElementsRequired <= smallestNumElements;
+}
+
+bool WebGLRenderingContext::validateWebGLObject(WebGLObject* object)
+{
+ if (!object || !object->object()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ if (object->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ return true;
+}
+
+void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long count, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+
+ if (isContextLost() || !validateDrawMode(mode))
+ return;
+
+ if (!validateStencilSettings())
+ return;
+
+ if (first < 0 || count < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+
+ if (!count)
+ return;
+
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ // Ensure we have a valid rendering state
+ CheckedInt<int32_t> checkedFirst(first);
+ CheckedInt<int32_t> checkedCount(count);
+ CheckedInt<int32_t> checkedSum = checkedFirst + checkedCount;
+ if (!checkedSum.valid() || !validateRenderingState(checkedSum.value())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ } else {
+ if (!validateRenderingState(0)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ }
+
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
+
+ bool vertexAttrib0Simulated = false;
+ if (!isGLES2Compliant())
+ vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
+ if (!isGLES2NPOTStrict())
+ handleNPOTTextures(true);
+ m_context->drawArrays(mode, first, count);
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (!isGLES2NPOTStrict())
+ handleNPOTTextures(false);
+ cleanupAfterGraphicsCall(true);
+}
+
+void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigned long type, long offset, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+
+ if (isContextLost() || !validateDrawMode(mode))
+ return;
+
+ if (!validateStencilSettings())
+ return;
+
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+
+ if (count < 0 || offset < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+
+ if (!count)
+ return;
+
+ long numElements = 0;
+ if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+ // Ensure we have a valid rendering state
+ if (!validateElementArraySize(count, type, offset)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (!count)
+ return;
+ if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements)) {
+ if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ }
+ } else {
+ if (!validateRenderingState(0)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ }
+
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
+
+ bool vertexAttrib0Simulated = false;
+ if (!isGLES2Compliant()) {
+ if (!numElements)
+ validateIndexArrayPrecise(count, type, offset, numElements);
+ vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
+ }
+ if (!isGLES2NPOTStrict())
+ handleNPOTTextures(true);
+ m_context->drawElements(mode, count, type, offset);
+ if (!isGLES2Compliant() && vertexAttrib0Simulated)
+ restoreStatesAfterVertexAttrib0Simulation();
+ if (!isGLES2NPOTStrict())
+ handleNPOTTextures(false);
+ cleanupAfterGraphicsCall(true);
+}
+
+void WebGLRenderingContext::enable(unsigned long cap)
+{
+ if (isContextLost() || !validateCapability(cap))
+ return;
+ m_context->enable(cap);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::enableVertexAttribArray(unsigned long index, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+
+ if (index >= m_vertexAttribState.size())
+ m_vertexAttribState.resize(index + 1);
+
+ m_vertexAttribState[index].enabled = true;
+
+ m_context->enableVertexAttribArray(index);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::finish()
+{
+ if (isContextLost())
+ return;
+ m_context->finish();
+ cleanupAfterGraphicsCall(true);
+}
+
+
+void WebGLRenderingContext::flush()
+{
+ if (isContextLost())
+ return;
+ m_context->flush();
+ cleanupAfterGraphicsCall(true);
+}
+
+void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateFramebufferFuncParameters(target, attachment))
+ return;
+ if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if (buffer && buffer->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ Platform3DObject bufferObject = objectOrZero(buffer);
+ bool reattachDepth = false;
+ bool reattachStencil = false;
+ bool reattachDepthStencilDepth = false;
+ bool reattachDepthStencilStencil = false;
+ 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);
+ if (!bufferObject) {
+ reattachDepth = true;
+ reattachStencil = true;
+ }
+ break;
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
+ if (!bufferObject)
+ reattachDepthStencilDepth = true;
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
+ if (!bufferObject)
+ reattachDepthStencilStencil = true;
+ break;
+ default:
+ m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
+ }
+ m_framebufferBinding->setAttachment(attachment, buffer);
+ if (reattachDepth) {
+ Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_ATTACHMENT));
+ if (object)
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, object);
+ }
+ if (reattachStencil) {
+ Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::STENCIL_ATTACHMENT));
+ if (object)
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, object);
+ }
+ if (reattachDepthStencilDepth) {
+ Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT));
+ if (object)
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, object);
+ }
+ if (reattachDepthStencilStencil) {
+ Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT));
+ if (object)
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, object);
+ }
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture* texture, long level, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateFramebufferFuncParameters(target, attachment))
+ return;
+ if (level) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (texture && texture->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ m_context->framebufferTexture2D(target, attachment, textarget, objectOrZero(texture), level);
+ m_framebufferBinding->setAttachment(attachment, textarget, texture, level);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::frontFace(unsigned long mode)
+{
+ if (isContextLost())
+ return;
+ m_context->frontFace(mode);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::generateMipmap(unsigned long target)
+{
+ if (isContextLost())
+ return;
+ WebGLTexture* tex = validateTextureBinding(target, false);
+ if (!tex)
+ return;
+ if (!tex->canGenerateMipmaps()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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, unsigned long index, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(program))
+ return 0;
+ ActiveInfo info;
+ if (!m_context->getActiveAttrib(objectOrZero(program), index, info))
+ return 0;
+ return WebGLActiveInfo::create(info.name, info.type, info.size);
+}
+
+PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, unsigned long index, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(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]");
+ return WebGLActiveInfo::create(info.name, info.type, info.size);
+}
+
+bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<WebGLShader*>& shaderObjects, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ shaderObjects.clear();
+ if (isContextLost() || !validateWebGLObject(program))
+ return false;
+ int numShaders = 0;
+ m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::ATTACHED_SHADERS, &numShaders);
+ if (numShaders) {
+ OwnArrayPtr<unsigned int> shaders(new unsigned int[numShaders]);
+ int count = 0;
+ m_context->getAttachedShaders(objectOrZero(program), numShaders, &count, shaders.get());
+ if (count != numShaders)
+ return false;
+ shaderObjects.resize(numShaders);
+ for (int ii = 0; ii < numShaders; ++ii) {
+ WebGLShader* shader = findShader(shaders[ii]);
+ if (!shader) {
+ shaderObjects.clear();
+ return false;
+ }
+ shaderObjects[ii] = shader;
+ }
+ }
+ return true;
+}
+
+int WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name)
+{
+ if (isContextLost())
+ return -1;
+ if (!validateString(name))
+ return -1;
+ return m_context->getAttribLocation(objectOrZero(program), name);
+}
+
+WebGLGetInfo WebGLRenderingContext::getBufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
+ if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+
+ if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+
+ WebGLStateRestorer(this, false);
+ int value = 0;
+ m_context->getBufferParameteriv(target, pname, &value);
+ if (pname == GraphicsContext3D::BUFFER_SIZE)
+ return WebGLGetInfo(static_cast<long>(value));
+ return WebGLGetInfo(static_cast<unsigned long>(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.
+ return WebGLContextAttributes::create(m_context->getContextAttributes());
+}
+
+unsigned long WebGLRenderingContext::getError()
+{
+ return m_context->getError();
+}
+
+WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
+{
+ if (isContextLost())
+ return 0;
+
+ 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 = OESTextureFloat::create();
+ }
+ return m_oesTextureFloat.get();
+ } else if (equalIgnoringCase(name, "WEBKIT_lose_context")) {
+ if (!m_webkitLoseContext)
+ m_webkitLoseContext = WebKitLoseContext::create(this);
+ return m_webkitLoseContext.get();
+ }
+
+ return 0;
+}
+
+WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, unsigned long pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateFramebufferFuncParameters(target, attachment))
+ return WebGLGetInfo();
+ switch (pname) {
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+
+ if (!m_framebufferBinding || !m_framebufferBinding->object() || m_framebufferBinding->isIncomplete(false)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return WebGLGetInfo();
+ }
+
+ if (pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
+ WebGLStateRestorer(this, false);
+ int value = 0;
+ m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
+ if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
+ return WebGLGetInfo(static_cast<unsigned long>(value));
+ return WebGLGetInfo(static_cast<long>(value));
+ }
+
+ WebGLStateRestorer(this, false);
+ int type = 0;
+ m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
+ if (!type)
+ return WebGLGetInfo();
+ int value = 0;
+ m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &value);
+ switch (type) {
+ case GraphicsContext3D::RENDERBUFFER:
+ return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(findRenderbuffer(static_cast<Platform3DObject>(value))));
+ case GraphicsContext3D::TEXTURE:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(findTexture(static_cast<Platform3DObject>(value))));
+ default:
+ // FIXME: raise exception?
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
+ WebGLStateRestorer(this, false);
+ switch (pname) {
+ case GraphicsContext3D::ACTIVE_TEXTURE:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::ALPHA_BITS:
+ return getLongParameter(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 getUnsignedLongParameter(pname);
+ case GraphicsContext3D::BLEND_DST_RGB:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::BLEND_EQUATION_ALPHA:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::BLEND_EQUATION_RGB:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::BLEND_SRC_ALPHA:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::BLEND_SRC_RGB:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::BLUE_BITS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::COLOR_CLEAR_VALUE:
+ return getWebGLFloatArrayParameter(pname);
+ case GraphicsContext3D::COLOR_WRITEMASK:
+ return getBooleanArrayParameter(pname);
+ case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS:
+ // Defined as null in the spec
+ return WebGLGetInfo();
+ case GraphicsContext3D::CULL_FACE:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::CULL_FACE_MODE:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::CURRENT_PROGRAM:
+ return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
+ case GraphicsContext3D::DEPTH_BITS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::DEPTH_CLEAR_VALUE:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::DEPTH_FUNC:
+ return getUnsignedLongParameter(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_boundElementArrayBuffer));
+ case GraphicsContext3D::FRAMEBUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
+ case GraphicsContext3D::FRONT_FACE:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::GENERATE_MIPMAP_HINT:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::GREEN_BITS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::LINE_WIDTH:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE:
+ return getLongParameter(pname);
+ case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::MAX_RENDERBUFFER_SIZE:
+ return getLongParameter(pname);
+ case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::MAX_TEXTURE_SIZE:
+ return getLongParameter(pname);
+ case GraphicsContext3D::MAX_VARYING_VECTORS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::MAX_VERTEX_ATTRIBS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::MAX_VIEWPORT_DIMS:
+ return getWebGLIntArrayParameter(pname);
+ case GraphicsContext3D::NUM_COMPRESSED_TEXTURE_FORMATS:
+ // WebGL 1.0 specifies that there are no compressed texture formats.
+ return WebGLGetInfo(static_cast<long>(0));
+ case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
+ // FIXME: should we always return 0 for this?
+ return getLongParameter(pname);
+ case GraphicsContext3D::PACK_ALIGNMENT:
+ return getLongParameter(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 getLongParameter(pname);
+ case GraphicsContext3D::RENDERBUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
+ case GraphicsContext3D::RENDERER:
+ return WebGLGetInfo(m_context->getString(GraphicsContext3D::RENDERER));
+ case GraphicsContext3D::SAMPLE_BUFFERS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::SAMPLE_COVERAGE_INVERT:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::SAMPLE_COVERAGE_VALUE:
+ return getFloatParameter(pname);
+ case GraphicsContext3D::SAMPLES:
+ return getLongParameter(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 getUnsignedLongParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_FUNC:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_REF:
+ return getLongParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_VALUE_MASK:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::STENCIL_BACK_WRITEMASK:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::STENCIL_BITS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::STENCIL_CLEAR_VALUE:
+ return getLongParameter(pname);
+ case GraphicsContext3D::STENCIL_FAIL:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::STENCIL_FUNC:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::STENCIL_REF:
+ return getLongParameter(pname);
+ case GraphicsContext3D::STENCIL_TEST:
+ return getBooleanParameter(pname);
+ case GraphicsContext3D::STENCIL_VALUE_MASK:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::STENCIL_WRITEMASK:
+ return getUnsignedLongParameter(pname);
+ case GraphicsContext3D::SUBPIXEL_BITS:
+ return getLongParameter(pname);
+ case GraphicsContext3D::TEXTURE_BINDING_2D:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding));
+ case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding));
+ case GraphicsContext3D::UNPACK_ALIGNMENT:
+ // FIXME: should this be "long" in the spec?
+ 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("Webkit (" + m_context->getString(GraphicsContext3D::VENDOR) + ")");
+ case GraphicsContext3D::VERSION:
+ return WebGLGetInfo("WebGL 1.0 (" + m_context->getString(GraphicsContext3D::VERSION) + ")");
+ case GraphicsContext3D::VIEWPORT:
+ return getWebGLIntArrayParameter(pname);
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, unsigned long pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(program))
+ return WebGLGetInfo();
+
+ WebGLStateRestorer(this, false);
+ int 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::INFO_LOG_LENGTH:
+ case GraphicsContext3D::ATTACHED_SHADERS:
+ case GraphicsContext3D::ACTIVE_ATTRIBUTES:
+ case GraphicsContext3D::ACTIVE_ATTRIBUTE_MAX_LENGTH:
+ case GraphicsContext3D::ACTIVE_UNIFORMS:
+ case GraphicsContext3D::ACTIVE_UNIFORM_MAX_LENGTH:
+ m_context->getProgramiv(objectOrZero(program), pname, &value);
+ return WebGLGetInfo(static_cast<long>(value));
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+}
+
+String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject(program))
+ return "";
+ WebGLStateRestorer(this, false);
+ return m_context->getProgramInfoLog(objectOrZero(program));
+}
+
+WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
+ if (target != GraphicsContext3D::RENDERBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return WebGLGetInfo();
+ }
+
+ if (m_renderbufferBinding->getInternalFormat() == GraphicsContext3D::DEPTH_STENCIL
+ && !m_renderbufferBinding->isValid()) {
+ ASSERT(!isDepthStencilSupported());
+ long value = 0;
+ switch (pname) {
+ case GraphicsContext3D::RENDERBUFFER_WIDTH:
+ value = static_cast<long>(m_renderbufferBinding->getWidth());
+ break;
+ case GraphicsContext3D::RENDERBUFFER_HEIGHT:
+ value = static_cast<long>(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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+ return WebGLGetInfo(value);
+ }
+
+ WebGLStateRestorer(this, false);
+ int 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(static_cast<long>(value));
+ case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
+ return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsigned long pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(shader))
+ return WebGLGetInfo();
+ WebGLStateRestorer(this, false);
+ int 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 long>(value));
+ case GraphicsContext3D::INFO_LOG_LENGTH:
+ case GraphicsContext3D::SHADER_SOURCE_LENGTH:
+ m_context->getShaderiv(objectOrZero(shader), pname, &value);
+ return WebGLGetInfo(static_cast<long>(value));
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+}
+
+String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject(shader))
+ return "";
+ WebGLStateRestorer(this, false);
+ return m_context->getShaderInfoLog(objectOrZero(shader));
+}
+
+String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject(shader))
+ return "";
+ WebGLStateRestorer(this, false);
+ return m_context->getShaderSource(objectOrZero(shader));
+}
+
+Vector<String> WebGLRenderingContext::getSupportedExtensions()
+{
+ Vector<String> result;
+ if (m_context->getExtensions()->supports("GL_OES_texture_float"))
+ result.append("OES_texture_float");
+ result.append("WEBKIT_lose_context");
+ return result;
+}
+
+WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
+ WebGLTexture* tex = validateTextureBinding(target, false);
+ if (!tex)
+ return WebGLGetInfo();
+ WebGLStateRestorer(this, false);
+ int 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 long>(value));
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(program))
+ return WebGLGetInfo();
+ if (!uniformLocation || uniformLocation->program() != program) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return WebGLGetInfo();
+ }
+ long location = uniformLocation->location();
+
+ WebGLStateRestorer(this, false);
+ // FIXME: make this more efficient using WebGLUniformLocation and caching types in it
+ int activeUniforms = 0;
+ m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::ACTIVE_UNIFORMS, &activeUniforms);
+ for (int i = 0; i < activeUniforms; i++) {
+ ActiveInfo info;
+ if (!m_context->getActiveUniform(objectOrZero(program), i, info))
+ return WebGLGetInfo();
+ // Strip "[0]" from the name if it's an array.
+ if (info.size > 1)
+ 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 (int index = 0; index < info.size; ++index) {
+ String name = info.name;
+ if (info.size > 1 && index >= 1) {
+ name.append('[');
+ name.append(String::number(index));
+ name.append(']');
+ }
+ // Now need to look this up by name again to find its location
+ long loc = m_context->getUniformLocation(objectOrZero(program), name);
+ if (loc == location) {
+ // Found it. Use the type in the ActiveInfo to determine the return type.
+ GraphicsContext3D::WebGLEnumType baseType;
+ unsigned length;
+ switch (info.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;
+ default:
+ // Can't handle this type
+ // FIXME: what to do about samplers?
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return WebGLGetInfo();
+ }
+ switch (baseType) {
+ case GraphicsContext3D::FLOAT: {
+ float value[16] = {0};
+ m_context->getUniformfv(objectOrZero(program), location, value);
+ if (length == 1)
+ return WebGLGetInfo(value[0]);
+ return WebGLGetInfo(Float32Array::create(value, length));
+ }
+ case GraphicsContext3D::INT: {
+ int value[4] = {0};
+ m_context->getUniformiv(objectOrZero(program), location, value);
+ if (length == 1)
+ return WebGLGetInfo(static_cast<long>(value[0]));
+ return WebGLGetInfo(Int32Array::create(value, length));
+ }
+ case GraphicsContext3D::BOOL: {
+ int value[4] = {0};
+ 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
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return WebGLGetInfo();
+}
+
+PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(program))
+ return 0;
+ if (!validateString(name))
+ return 0;
+ WebGLStateRestorer(this, false);
+ long uniformLocation = m_context->getUniformLocation(objectOrZero(program), name);
+ if (uniformLocation == -1)
+ return 0;
+ return WebGLUniformLocation::create(program, uniformLocation);
+}
+
+WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigned long pname, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
+ WebGLStateRestorer(this, false);
+ if (index >= m_maxVertexAttribs) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return WebGLGetInfo();
+ }
+ switch (pname) {
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+ if ((!isGLES2Compliant() && !index && m_vertexAttribState[0].bufferBinding == m_vertexAttrib0Buffer)
+ || index >= m_vertexAttribState.size()
+ || !m_vertexAttribState[index].bufferBinding
+ || !m_vertexAttribState[index].bufferBinding->object())
+ return WebGLGetInfo();
+ return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_vertexAttribState[index].bufferBinding));
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_ENABLED:
+ if (index >= m_vertexAttribState.size())
+ return WebGLGetInfo(false);
+ return WebGLGetInfo(m_vertexAttribState[index].enabled);
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_NORMALIZED:
+ if (index >= m_vertexAttribState.size())
+ return WebGLGetInfo(false);
+ return WebGLGetInfo(m_vertexAttribState[index].normalized);
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE:
+ if (index >= m_vertexAttribState.size())
+ return WebGLGetInfo(static_cast<long>(4));
+ return WebGLGetInfo(m_vertexAttribState[index].size);
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE:
+ if (index >= m_vertexAttribState.size())
+ return WebGLGetInfo(static_cast<long>(0));
+ return WebGLGetInfo(m_vertexAttribState[index].originalStride);
+ case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE:
+ if (index >= m_vertexAttribState.size())
+ return WebGLGetInfo(static_cast<unsigned long>(GraphicsContext3D::FLOAT));
+ return WebGLGetInfo(m_vertexAttribState[index].type);
+ case GraphicsContext3D::CURRENT_VERTEX_ATTRIB:
+ if (index >= m_vertexAttribState.size()) {
+ float value[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
+ return WebGLGetInfo(Float32Array::create(value, 4));
+ }
+ return WebGLGetInfo(Float32Array::create(m_vertexAttribState[index].value, 4));
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+}
+
+long WebGLRenderingContext::getVertexAttribOffset(unsigned long index, unsigned long pname)
+{
+ if (isContextLost())
+ return 0;
+ long result = m_context->getVertexAttribOffset(index, pname);
+ cleanupAfterGraphicsCall(false);
+ return result;
+}
+
+void WebGLRenderingContext::hint(unsigned long target, unsigned long mode)
+{
+ if (isContextLost())
+ return;
+ if (target != GraphicsContext3D::GENERATE_MIPMAP_HINT) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ m_context->hint(target, mode);
+ cleanupAfterGraphicsCall(false);
+}
+
+bool WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
+{
+ if (!buffer || isContextLost())
+ return false;
+
+ if (!buffer->hasEverBeenBound())
+ return false;
+
+ return m_context->isBuffer(buffer->object());
+}
+
+bool WebGLRenderingContext::isContextLost()
+{
+ if (m_restoreTimer.isActive())
+ return true;
+
+ bool newContextLost = m_context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR;
+
+ if (newContextLost != m_contextLost)
+ m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
+
+ return m_contextLost;
+}
+
+bool WebGLRenderingContext::isEnabled(unsigned long cap)
+{
+ if (!validateCapability(cap) || isContextLost())
+ return false;
+ return m_context->isEnabled(cap);
+}
+
+bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
+{
+ if (!framebuffer || isContextLost())
+ return false;
+
+ if (!framebuffer->hasEverBeenBound())
+ return false;
+
+ return m_context->isFramebuffer(framebuffer->object());
+}
+
+bool WebGLRenderingContext::isProgram(WebGLProgram* program)
+{
+ if (!program || isContextLost())
+ return false;
+
+ return m_context->isProgram(program->object());
+}
+
+bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
+{
+ if (!renderbuffer || isContextLost())
+ return false;
+
+ if (!renderbuffer->hasEverBeenBound())
+ return false;
+
+ return m_context->isRenderbuffer(renderbuffer->object());
+}
+
+bool WebGLRenderingContext::isShader(WebGLShader* shader)
+{
+ if (!shader || isContextLost())
+ return false;
+
+ return m_context->isShader(shader->object());
+}
+
+bool WebGLRenderingContext::isTexture(WebGLTexture* texture)
+{
+ if (!texture || isContextLost())
+ return false;
+
+ if (!texture->hasEverBeenBound())
+ return false;
+
+ return m_context->isTexture(texture->object());
+}
+
+void WebGLRenderingContext::lineWidth(float width)
+{
+ if (isContextLost())
+ return;
+ m_context->lineWidth((float) width);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(program))
+ return;
+ if (!isGLES2Compliant()) {
+ if (!program->getAttachedShader(GraphicsContext3D::VERTEX_SHADER) || !program->getAttachedShader(GraphicsContext3D::FRAGMENT_SHADER)) {
+ program->setLinkStatus(false);
+ return;
+ }
+ }
+
+ m_context->linkProgram(objectOrZero(program));
+ program->increaseLinkCount();
+ // cache link status
+ int value = 0;
+ m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::LINK_STATUS, &value);
+ program->setLinkStatus(static_cast<bool>(value));
+ // Need to cache link status before caching active attribute locations.
+ program->cacheActiveAttribLocations();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::pixelStorei(unsigned long pname, long 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<unsigned long>(param);
+ else {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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 = static_cast<int>(param);
+ else // GraphicsContext3D::UNPACK_ALIGNMENT:
+ m_unpackAlignment = static_cast<int>(param);
+ m_context->pixelStorei(pname, param);
+ cleanupAfterGraphicsCall(false);
+ } else {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+}
+
+void WebGLRenderingContext::polygonOffset(float factor, float units)
+{
+ if (isContextLost())
+ return;
+ m_context->polygonOffset((float) factor, (float) units);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels, ExceptionCode& ec)
+{
+ if (isContextLost())
+ return;
+ if (!canvas()->originClean()) {
+ ec = SECURITY_ERR;
+ return;
+ }
+ // Validate input parameters.
+ unsigned int componentsPerPixel, bytesPerComponent;
+ if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if (!pixels) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (width < 0 || height < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (format != GraphicsContext3D::RGBA && type != GraphicsContext3D::UNSIGNED_BYTE) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ // Validate array type against pixel type.
+ if ((type == GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedByteArray())
+ || (type != GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedShortArray())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
+ // Calculate array size, taking into consideration of PACK_ALIGNMENT.
+ unsigned long bytesPerRow = componentsPerPixel * bytesPerComponent * width;
+ unsigned long padding = 0;
+ unsigned long residualBytes = bytesPerRow % m_packAlignment;
+ if (residualBytes) {
+ padding = m_packAlignment - residualBytes;
+ bytesPerRow += padding;
+ }
+ // The last row needs no padding.
+ unsigned long totalBytes = bytesPerRow * height - padding;
+ unsigned long num = totalBytes / bytesPerComponent;
+ if (pixels->byteLength() / bytesPerComponent < num) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ void* data = pixels->baseAddress();
+ m_context->readPixels(x, y, width, height, format, type, data);
+#if PLATFORM(CG)
+ // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
+ // when alpha is off, readPixels should set alpha to 255 instead of 0.
+ if ((format == GraphicsContext3D::ALPHA || format == GraphicsContext3D::RGBA) && !m_context->getContextAttributes().alpha) {
+ if (type == GraphicsContext3D::UNSIGNED_BYTE) {
+ unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
+ for (long iy = 0; iy < height; ++iy) {
+ for (long ix = 0; ix < width; ++ix) {
+ pixels[componentsPerPixel - 1] = 255;
+ pixels += componentsPerPixel;
+ }
+ pixels += padding;
+ }
+ }
+ // FIXME: check whether we need to do the same with UNSIGNED_SHORT.
+ }
+#endif
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::releaseShaderCompiler()
+{
+ if (isContextLost())
+ return;
+ m_context->releaseShaderCompiler();
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned long internalformat, long width, long height)
+{
+ if (isContextLost())
+ return;
+ if (target != GraphicsContext3D::RENDERBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (!validateSize(width, height))
+ return;
+ switch (internalformat) {
+ case GraphicsContext3D::DEPTH_COMPONENT16:
+ case GraphicsContext3D::RGBA4:
+ case GraphicsContext3D::RGB5_A1:
+ case GraphicsContext3D::RGB565:
+ case GraphicsContext3D::STENCIL_INDEX8:
+ 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()) {
+ m_context->renderbufferStorage(target, Extensions3D::DEPTH24_STENCIL8, width, height);
+ cleanupAfterGraphicsCall(false);
+ }
+ m_renderbufferBinding->setSize(width, height);
+ m_renderbufferBinding->setIsValid(isDepthStencilSupported());
+ m_renderbufferBinding->setInternalFormat(internalformat);
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ }
+}
+
+void WebGLRenderingContext::sampleCoverage(float value, bool invert)
+{
+ if (isContextLost())
+ return;
+ m_context->sampleCoverage((float) value, invert);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::scissor(long x, long y, long width, long height)
+{
+ if (isContextLost())
+ return;
+ if (!validateSize(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(shader))
+ return;
+ if (!validateString(string))
+ return;
+ m_context->shaderSource(objectOrZero(shader), string);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::stencilFunc(unsigned long func, long ref, unsigned long mask)
+{
+ if (isContextLost())
+ return;
+ if (!validateStencilFunc(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(unsigned long face, unsigned long func, long ref, unsigned long mask)
+{
+ if (isContextLost())
+ return;
+ if (!validateStencilFunc(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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ m_context->stencilFuncSeparate(face, func, ref, mask);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::stencilMask(unsigned long mask)
+{
+ if (isContextLost())
+ return;
+ m_stencilMask = mask;
+ m_stencilMaskBack = mask;
+ m_context->stencilMask(mask);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::stencilMaskSeparate(unsigned long face, unsigned long 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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ m_context->stencilMaskSeparate(face, mask);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass)
+{
+ if (isContextLost())
+ return;
+ m_context->stencilOp(fail, zfail, zpass);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass)
+{
+ if (isContextLost())
+ return;
+ m_context->stencilOpSeparate(face, fail, zfail, zpass);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsigned internalformat,
+ int width, int height, unsigned border,
+ unsigned format, unsigned type, void* pixels, ExceptionCode& ec)
+{
+ // FIXME: For now we ignore any errors returned
+ ec = 0;
+ if (!validateTexFuncParameters(target, level, internalformat, width, height, border, format, type))
+ return;
+ WebGLTexture* tex = validateTextureBinding(target, true);
+ if (!tex)
+ return;
+ if (!isGLES2NPOTStrict()) {
+ if (level && WebGLTexture::isNPOT(width, height)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ }
+ if (!pixels && !isResourceSafe()) {
+ bool succeed = m_context->texImage2DResourceSafe(target, level, internalformat, width, height,
+ border, format, type);
+ if (!succeed)
+ return;
+ } else {
+ m_context->texImage2D(target, level, internalformat, width, height,
+ border, format, type, pixels);
+ }
+ tex->setLevelInfo(target, level, internalformat, width, height, type);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::texImage2DImpl(unsigned target, unsigned level, unsigned internalformat,
+ unsigned format, unsigned type, Image* image,
+ bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
+{
+ ec = 0;
+ Vector<uint8_t> data;
+ if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, image->width(), image->height(), 0,
+ format, type, data.data(), ec);
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
+ int width, int height, unsigned border,
+ unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
+{
+ if (isContextLost() || !validateTexFuncData(width, height, format, type, pixels))
+ 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 WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
+ unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ Vector<uint8_t> data;
+ if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0,
+ format, type, data.data(), ec);
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
+ unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ if (!image || !image->cachedImage()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ checkOrigin(image);
+ texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(),
+ m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
+ unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ if (!canvas || !canvas->buffer()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ checkOrigin(canvas);
+ texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(),
+ m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video)
+{
+ if (!video || !video->videoWidth() || !video->videoHeight()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return 0;
+ }
+ IntSize size(video->videoWidth(), video->videoHeight());
+ ImageBuffer* buf = m_videoCache.imageBuffer(size);
+ if (!buf) {
+ m_context->synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY);
+ return 0;
+ }
+ checkOrigin(video);
+ 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();
+}
+
+void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
+ unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ RefPtr<Image> image = videoFrameToImage(video);
+ if (!video)
+ return;
+ texImage2DImpl(target, level, internalformat, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+void WebGLRenderingContext::texParameter(unsigned long target, unsigned long pname, float paramf, int parami, bool isFloat)
+{
+ if (isContextLost())
+ return;
+ WebGLTexture* tex = validateTextureBinding(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)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if (isFloat) {
+ tex->setParameterf(pname, paramf);
+ m_context->texParameterf(target, pname, paramf);
+ } else {
+ tex->setParameteri(pname, parami);
+ m_context->texParameteri(target, pname, parami);
+ }
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::texParameterf(unsigned target, unsigned pname, float param)
+{
+ texParameter(target, pname, param, 0, true);
+}
+
+void WebGLRenderingContext::texParameteri(unsigned target, unsigned pname, int param)
+{
+ texParameter(target, pname, 0, param, false);
+}
+
+void WebGLRenderingContext::texSubImage2DBase(unsigned target, unsigned level, int xoffset, int yoffset,
+ int width, int height,
+ unsigned format, unsigned type, void* pixels, ExceptionCode& ec)
+{
+ // FIXME: For now we ignore any errors returned
+ ec = 0;
+ if (isContextLost())
+ return;
+ if (!validateTexFuncFormatAndType(format, type))
+ return;
+ if (!validateTextureBinding(target, true))
+ return;
+ if (!validateSize(xoffset, yoffset) || !validateSize(width, height))
+ return;
+ m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::texSubImage2DImpl(unsigned target, unsigned level, int xoffset, int yoffset,
+ unsigned format, unsigned type,
+ Image* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ Vector<uint8_t> data;
+ if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(),
+ format, type, data.data(), ec);
+}
+
+void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, int xoffset, int yoffset,
+ int width, int height,
+ unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
+{
+ if (isContextLost() || !validateTexFuncData(width, height, format, type, pixels))
+ 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);
+ texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, ec);
+ if (changeUnpackAlignment)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, int xoffset, int yoffset,
+ unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ Vector<uint8_t> data;
+ if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(),
+ format, type, data.data(), ec);
+}
+
+void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, int xoffset, int yoffset,
+ unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ if (!image || !image->cachedImage()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ checkOrigin(image);
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(),
+ m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, int xoffset, int yoffset,
+ unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ if (!canvas || !canvas->buffer()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ checkOrigin(canvas);
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(),
+ m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, int xoffset, int yoffset,
+ unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLost())
+ return;
+ RefPtr<Image> image = videoFrameToImage(video);
+ if (!video)
+ return;
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ m_context->uniform1f(location->location(), x);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, 1))
+ return;
+
+ m_context->uniform1fv(location->location(), v->data(), v->length());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 1))
+ return;
+
+ m_context->uniform1fv(location->location(), v, size);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, int x, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 1))
+ return;
+
+ m_context->uniform1iv(location->location(), v->data(), v->length());
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 1))
+ return;
+
+ m_context->uniform1iv(location->location(), v, size);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, float x, float y, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 2))
+ return;
+
+ m_context->uniform2fv(location->location(), v->data(), v->length() / 2);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 2))
+ return;
+
+ m_context->uniform2fv(location->location(), v, size / 2);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, int x, int y, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 2))
+ return;
+
+ m_context->uniform2iv(location->location(), v->data(), v->length() / 2);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 2))
+ return;
+
+ m_context->uniform2iv(location->location(), v, size / 2);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, float x, float y, float z, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 3))
+ return;
+
+ m_context->uniform3fv(location->location(), v->data(), v->length() / 3);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 3))
+ return;
+
+ m_context->uniform3fv(location->location(), v, size / 3);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, int x, int y, int z, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 3))
+ return;
+
+ m_context->uniform3iv(location->location(), v->data(), v->length() / 3);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 3))
+ return;
+
+ m_context->uniform3iv(location->location(), v, size / 3);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, float x, float y, float z, float w, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 4))
+ return;
+
+ m_context->uniform4fv(location->location(), v->data(), v->length() / 4);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 4))
+ return;
+
+ m_context->uniform4fv(location->location(), v, size / 4);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, int x, int y, int z, int w, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ 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(location, v, 4))
+ return;
+
+ m_context->uniform4iv(location->location(), v->data(), v->length() / 4);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformParameters(location, v, size, 4))
+ return;
+
+ m_context->uniform4iv(location->location(), v, size / 4);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 4))
+ return;
+ m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 4))
+ return;
+ m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 9))
+ return;
+ m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 9))
+ return;
+ m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 16))
+ return;
+ m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 16))
+ return;
+ m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
+ if (program && program->context() != this) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ if (program && program->object() && !program->getLinkStatus()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ cleanupAfterGraphicsCall(false);
+ return;
+ }
+ if (m_currentProgram != program) {
+ if (m_currentProgram)
+ m_currentProgram->onDetached();
+ m_currentProgram = program;
+ m_context->useProgram(objectOrZero(program));
+ if (program && program->object())
+ program->onAttached();
+ }
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec)
+{
+ UNUSED_PARAM(ec);
+ if (isContextLost() || !validateWebGLObject(program))
+ return;
+ m_context->validateProgram(objectOrZero(program));
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::vertexAttrib1f(unsigned long index, float v0)
+{
+ vertexAttribfImpl(index, 1, v0, 0.0f, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContext::vertexAttrib1fv(unsigned long index, Float32Array* v)
+{
+ vertexAttribfvImpl(index, v, 1);
+}
+
+void WebGLRenderingContext::vertexAttrib1fv(unsigned long index, float* v, int size)
+{
+ vertexAttribfvImpl(index, v, size, 1);
+}
+
+void WebGLRenderingContext::vertexAttrib2f(unsigned long index, float v0, float v1)
+{
+ vertexAttribfImpl(index, 2, v0, v1, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContext::vertexAttrib2fv(unsigned long index, Float32Array* v)
+{
+ vertexAttribfvImpl(index, v, 2);
+}
+
+void WebGLRenderingContext::vertexAttrib2fv(unsigned long index, float* v, int size)
+{
+ vertexAttribfvImpl(index, v, size, 2);
+}
+
+void WebGLRenderingContext::vertexAttrib3f(unsigned long index, float v0, float v1, float v2)
+{
+ vertexAttribfImpl(index, 3, v0, v1, v2, 1.0f);
+}
+
+void WebGLRenderingContext::vertexAttrib3fv(unsigned long index, Float32Array* v)
+{
+ vertexAttribfvImpl(index, v, 3);
+}
+
+void WebGLRenderingContext::vertexAttrib3fv(unsigned long index, float* v, int size)
+{
+ vertexAttribfvImpl(index, v, size, 3);
+}
+
+void WebGLRenderingContext::vertexAttrib4f(unsigned long index, float v0, float v1, float v2, float v3)
+{
+ vertexAttribfImpl(index, 4, v0, v1, v2, v3);
+}
+
+void WebGLRenderingContext::vertexAttrib4fv(unsigned long index, Float32Array* v)
+{
+ vertexAttribfvImpl(index, v, 4);
+}
+
+void WebGLRenderingContext::vertexAttrib4fv(unsigned long index, float* v, int size)
+{
+ vertexAttribfvImpl(index, v, size, 4);
+}
+
+void WebGLRenderingContext::vertexAttribPointer(unsigned long index, long size, unsigned long type, bool normalized, long stride, 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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (!m_boundArrayBuffer) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
+ long typeSize = sizeInBytes(type);
+ if (typeSize <= 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if ((stride % typeSize) || (offset % typeSize)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+ long bytesPerElement = size * typeSize;
+
+ if (index >= m_vertexAttribState.size())
+ m_vertexAttribState.resize(index + 1);
+
+ long validatedStride = stride ? stride : bytesPerElement;
+
+ m_vertexAttribState[index].bufferBinding = m_boundArrayBuffer;
+ m_vertexAttribState[index].bytesPerElement = bytesPerElement;
+ m_vertexAttribState[index].size = size;
+ m_vertexAttribState[index].type = type;
+ m_vertexAttribState[index].normalized = normalized;
+ m_vertexAttribState[index].stride = validatedStride;
+ m_vertexAttribState[index].originalStride = stride;
+ m_vertexAttribState[index].offset = offset;
+ m_context->vertexAttribPointer(index, size, type, normalized, stride, offset);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::viewport(long x, long y, long width, long height)
+{
+ if (isContextLost())
+ return;
+ if (isnan(x))
+ x = 0;
+ if (isnan(y))
+ y = 0;
+ if (isnan(width))
+ width = 100;
+ if (isnan(height))
+ height = 100;
+ if (!validateSize(width, height))
+ return;
+ m_context->viewport(x, y, width, height);
+ cleanupAfterGraphicsCall(false);
+}
+
+void WebGLRenderingContext::forceLostContext()
+{
+ if (isContextLost()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ m_restoreTimer.startOneShot(0);
+}
+
+void WebGLRenderingContext::onLostContext()
+{
+ m_contextLost = true;
+
+ 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;
+ }
+ m_context->synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL);
+
+ canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, ""));
+}
+
+void WebGLRenderingContext::restoreContext()
+{
+ RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, canvas()->document()->view()->root()->hostWindow()));
+ if (!context)
+ return;
+
+ m_context = context;
+ m_contextLost = false;
+ initializeNewContext();
+ canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, false, true, ""));
+}
+
+void WebGLRenderingContext::removeObject(WebGLObject* object)
+{
+ m_canvasObjects.remove(object);
+}
+
+void WebGLRenderingContext::addObject(WebGLObject* object)
+{
+ ASSERT(!isContextLost());
+ removeObject(object);
+ m_canvasObjects.add(object);
+}
+
+void WebGLRenderingContext::detachAndRemoveAllObjects()
+{
+ HashSet<RefPtr<WebGLObject> >::iterator pend = m_canvasObjects.end();
+ for (HashSet<RefPtr<WebGLObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it)
+ (*it)->detachContext();
+
+ m_canvasObjects.clear();
+}
+
+WebGLTexture* WebGLRenderingContext::findTexture(Platform3DObject obj)
+{
+ if (!obj)
+ return 0;
+ HashSet<RefPtr<WebGLObject> >::iterator pend = m_canvasObjects.end();
+ for (HashSet<RefPtr<WebGLObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
+ if ((*it)->isTexture() && (*it)->object() == obj)
+ return reinterpret_cast<WebGLTexture*>((*it).get());
+ }
+ return 0;
+}
+
+WebGLRenderbuffer* WebGLRenderingContext::findRenderbuffer(Platform3DObject obj)
+{
+ if (!obj)
+ return 0;
+ HashSet<RefPtr<WebGLObject> >::iterator pend = m_canvasObjects.end();
+ for (HashSet<RefPtr<WebGLObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
+ if ((*it)->isRenderbuffer() && (*it)->object() == obj)
+ return reinterpret_cast<WebGLRenderbuffer*>((*it).get());
+ }
+ return 0;
+}
+
+WebGLBuffer* WebGLRenderingContext::findBuffer(Platform3DObject obj)
+{
+ if (!obj)
+ return 0;
+ HashSet<RefPtr<WebGLObject> >::iterator pend = m_canvasObjects.end();
+ for (HashSet<RefPtr<WebGLObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
+ if ((*it)->isBuffer() && (*it)->object() == obj)
+ return reinterpret_cast<WebGLBuffer*>((*it).get());
+ }
+ return 0;
+}
+
+WebGLShader* WebGLRenderingContext::findShader(Platform3DObject obj)
+{
+ if (!obj)
+ return 0;
+ HashSet<RefPtr<WebGLObject> >::iterator pend = m_canvasObjects.end();
+ for (HashSet<RefPtr<WebGLObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
+ if ((*it)->isShader() && (*it)->object() == obj)
+ return reinterpret_cast<WebGLShader*>((*it).get());
+ }
+ return 0;
+}
+
+WebGLGetInfo WebGLRenderingContext::getBooleanParameter(unsigned long pname)
+{
+ unsigned char value = 0;
+ m_context->getBooleanv(pname, &value);
+ return WebGLGetInfo(static_cast<bool>(value));
+}
+
+WebGLGetInfo WebGLRenderingContext::getBooleanArrayParameter(unsigned long pname)
+{
+ if (pname != GraphicsContext3D::COLOR_WRITEMASK) {
+ notImplemented();
+ return WebGLGetInfo(0, 0);
+ }
+ unsigned char 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(unsigned long pname)
+{
+ float value = 0;
+ m_context->getFloatv(pname, &value);
+ return WebGLGetInfo(static_cast<float>(value));
+}
+
+WebGLGetInfo WebGLRenderingContext::getIntParameter(unsigned long pname)
+{
+ return getLongParameter(pname);
+}
+
+WebGLGetInfo WebGLRenderingContext::getLongParameter(unsigned long pname)
+{
+ int value = 0;
+ m_context->getIntegerv(pname, &value);
+ return WebGLGetInfo(static_cast<long>(value));
+}
+
+WebGLGetInfo WebGLRenderingContext::getUnsignedLongParameter(unsigned long pname)
+{
+ int value = 0;
+ m_context->getIntegerv(pname, &value);
+ unsigned int uValue = static_cast<unsigned int>(value);
+ return WebGLGetInfo(static_cast<unsigned long>(uValue));
+}
+
+WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(unsigned long pname)
+{
+ float 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(unsigned long pname)
+{
+ int 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::handleNPOTTextures(bool prepareToDraw)
+{
+ bool resetActiveUnit = false;
+ for (unsigned ii = 0; ii < m_textureUnits.size(); ++ii) {
+ if ((m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture())
+ || (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture())) {
+ 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) {
+ tex2D = m_blackTexture2D.get();
+ texCubeMap = m_blackTextureCubeMap.get();
+ } else {
+ tex2D = m_textureUnits[ii].m_texture2DBinding.get();
+ texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get();
+ }
+ if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture())
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(tex2D));
+ if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture())
+ 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(unsigned long texInternalFormat,
+ unsigned long colorBufferFormat)
+{
+ switch (colorBufferFormat) {
+ case GraphicsContext3D::ALPHA:
+ if (texInternalFormat == GraphicsContext3D::ALPHA)
+ return true;
+ break;
+ case GraphicsContext3D::RGB:
+ if (texInternalFormat == GraphicsContext3D::LUMINANCE
+ || texInternalFormat == GraphicsContext3D::RGB)
+ return true;
+ break;
+ case GraphicsContext3D::RGBA:
+ return true;
+ }
+ return false;
+}
+
+unsigned long 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->getWidth();
+ return m_context->getInternalFramebufferSize().width();
+}
+
+int WebGLRenderingContext::getBoundFramebufferHeight()
+{
+ if (m_framebufferBinding && m_framebufferBinding->object())
+ return m_framebufferBinding->getHeight();
+ return m_context->getInternalFramebufferSize().height();
+}
+
+WebGLTexture* WebGLRenderingContext::validateTextureBinding(unsigned long target, bool useSixEnumsForCubeMap)
+{
+ WebGLTexture* tex = 0;
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ tex = m_textureUnits[m_activeTextureUnit].m_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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+ tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP:
+ if (useSixEnumsForCubeMap) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+ tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+ if (!tex)
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return tex;
+}
+
+bool WebGLRenderingContext::validateSize(long x, long y)
+{
+ if (x < 0 || y < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateString(const String& string)
+{
+ for (size_t i = 0; i < string.length(); ++i) {
+ if (!validateCharacter(string[i])) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateTexFuncFormatAndType(unsigned long format, unsigned long type)
+{
+ switch (format) {
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::RGBA:
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+
+ 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;
+ case GraphicsContext3D::FLOAT:
+ if (m_oesTextureFloat)
+ break;
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+
+ // Verify that the combination of format and type is supported.
+ switch (format) {
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ if (type != GraphicsContext3D::UNSIGNED_BYTE
+ && type != GraphicsContext3D::FLOAT) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ break;
+ case GraphicsContext3D::RGB:
+ if (type != GraphicsContext3D::UNSIGNED_BYTE
+ && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5
+ && type != GraphicsContext3D::FLOAT) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ break;
+ case GraphicsContext3D::RGBA:
+ if (type != GraphicsContext3D::UNSIGNED_BYTE
+ && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
+ && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1
+ && type != GraphicsContext3D::FLOAT) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContext::validateTexFuncLevel(unsigned long target, long level)
+{
+ if (level < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ if (level > m_maxTextureLevel) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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(unsigned long target, long level,
+ unsigned long internalformat,
+ long width, long height, long border,
+ unsigned long format, unsigned long 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(format, type) || !validateTexFuncLevel(target, level))
+ return false;
+
+ if (width < 0 || height < 0) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ if (width > m_maxTextureSize || height > m_maxTextureSize) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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 (width != height || width > m_maxCubeMapTextureSize) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+
+ if (format != internalformat) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+
+ if (border) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContext::validateTexFuncData(long width, long height,
+ unsigned long format, unsigned long type,
+ ArrayBufferView* pixels)
+{
+ if (!pixels)
+ return true;
+
+ if (!validateTexFuncFormatAndType(format, type))
+ return false;
+
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ if (!pixels->isUnsignedByteArray()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ break;
+ 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->isUnsignedShortArray()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ break;
+ case GraphicsContext3D::FLOAT: // OES_texture_float
+ if (!pixels->isFloatArray()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ unsigned int componentsPerPixel, bytesPerComponent;
+ if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+
+ if (!width || !height)
+ return true;
+ unsigned int validRowBytes = width * componentsPerPixel * bytesPerComponent;
+ unsigned int totalRowBytes = validRowBytes;
+ unsigned int remainder = validRowBytes % m_unpackAlignment;
+ if (remainder)
+ totalRowBytes += (m_unpackAlignment - remainder);
+ unsigned int totalBytesRequired = (height - 1) * totalRowBytes + validRowBytes;
+ if (pixels->byteLength() < totalBytesRequired) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateDrawMode(unsigned long 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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+}
+
+bool WebGLRenderingContext::validateStencilSettings()
+{
+ if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateStencilFunc(unsigned long 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:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+}
+
+void WebGLRenderingContext::printWarningToConsole(const String& message)
+{
+ canvas()->document()->frame()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel,
+ message, 0, canvas()->document()->url().string());
+}
+
+bool WebGLRenderingContext::validateFramebufferFuncParameters(unsigned long target, unsigned long attachment)
+{
+ if (target != GraphicsContext3D::FRAMEBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateBlendEquation(unsigned long mode)
+{
+ switch (mode) {
+ case GraphicsContext3D::FUNC_ADD:
+ case GraphicsContext3D::FUNC_SUBTRACT:
+ case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
+ return true;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+}
+
+bool WebGLRenderingContext::validateBlendFuncFactors(unsigned long src, unsigned long 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))) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContext::validateCapability(unsigned long 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:
+ return true;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+}
+
+bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Float32Array* v, int requiredMinSize)
+{
+ if (!v) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Int32Array* v, int requiredMinSize)
+{
+ if (!v) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, void* v, int size, int requiredMinSize)
+{
+ return validateUniformMatrixParameters(location, false, v, size, requiredMinSize);
+}
+
+bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, bool transpose, Float32Array* v, int requiredMinSize)
+{
+ if (!v) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return validateUniformMatrixParameters(location, transpose, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, bool transpose, void* v, int size, int requiredMinSize)
+{
+ if (!location)
+ return false;
+ if (location->program() != m_currentProgram) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ if (!v) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ if (transpose) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ if (size < requiredMinSize) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return true;
+}
+
+WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(unsigned long target, unsigned long usage)
+{
+ WebGLBuffer* buffer = 0;
+ switch (target) {
+ case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
+ buffer = m_boundElementArrayBuffer.get();
+ break;
+ case GraphicsContext3D::ARRAY_BUFFER:
+ buffer = m_boundArrayBuffer.get();
+ break;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+ }
+ if (!buffer) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return 0;
+ }
+ switch (usage) {
+ case GraphicsContext3D::STREAM_DRAW:
+ case GraphicsContext3D::STATIC_DRAW:
+ case GraphicsContext3D::DYNAMIC_DRAW:
+ return buffer;
+ }
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return 0;
+}
+
+void WebGLRenderingContext::vertexAttribfImpl(unsigned long index, int expectedSize, float v0, float v1, float v2, float v3)
+{
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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);
+ }
+ if (index >= m_vertexAttribState.size())
+ m_vertexAttribState.resize(index + 1);
+ m_vertexAttribState[index].value[0] = v0;
+ m_vertexAttribState[index].value[1] = v1;
+ m_vertexAttribState[index].value[2] = v2;
+ m_vertexAttribState[index].value[3] = v3;
+}
+
+void WebGLRenderingContext::vertexAttribfvImpl(unsigned long index, Float32Array* v, int expectedSize)
+{
+ if (isContextLost())
+ return;
+ if (!v) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ vertexAttribfvImpl(index, v->data(), v->length(), expectedSize);
+}
+
+void WebGLRenderingContext::vertexAttribfvImpl(unsigned long index, float* v, int size, int expectedSize)
+{
+ if (isContextLost())
+ return;
+ if (!v) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (size < expectedSize) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ 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);
+ }
+ if (index >= m_vertexAttribState.size())
+ m_vertexAttribState.resize(index + 1);
+ m_vertexAttribState[index].initValue();
+ for (int ii = 0; ii < expectedSize; ++ii)
+ m_vertexAttribState[index].value[ii] = v[ii];
+}
+
+void WebGLRenderingContext::initVertexAttrib0()
+{
+ m_vertexAttribState.resize(1);
+ 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);
+ m_vertexAttribState[0].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;
+}
+
+bool WebGLRenderingContext::simulateVertexAttrib0(long numVertex)
+{
+ const VertexAttribState& state = m_vertexAttribState[0];
+ if (state.enabled || !m_currentProgram || !m_currentProgram->object()
+ || !m_currentProgram->isUsingVertexAttrib0())
+ return false;
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer->object());
+ long bufferDataSize = (numVertex + 1) * 4 * sizeof(float);
+ if (bufferDataSize > m_vertexAttrib0BufferSize
+ || state.value[0] != m_vertexAttrib0BufferValue[0]
+ || state.value[1] != m_vertexAttrib0BufferValue[1]
+ || state.value[2] != m_vertexAttrib0BufferValue[2]
+ || state.value[3] != m_vertexAttrib0BufferValue[3]) {
+ OwnArrayPtr<float> bufferData(new float[(numVertex + 1) * 4]);
+ for (long ii = 0; ii < numVertex + 1; ++ii) {
+ bufferData[ii * 4] = state.value[0];
+ bufferData[ii * 4 + 1] = state.value[1];
+ bufferData[ii * 4 + 2] = state.value[2];
+ bufferData[ii * 4 + 3] = state.value[3];
+ }
+ m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, bufferDataSize, bufferData.get(), GraphicsContext3D::DYNAMIC_DRAW);
+ m_vertexAttrib0BufferSize = bufferDataSize;
+ m_vertexAttrib0BufferValue[0] = state.value[0];
+ m_vertexAttrib0BufferValue[1] = state.value[1];
+ m_vertexAttrib0BufferValue[2] = state.value[2];
+ m_vertexAttrib0BufferValue[3] = state.value[3];
+ }
+ m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, false, 0, 0);
+ return true;
+}
+
+void WebGLRenderingContext::restoreStatesAfterVertexAttrib0Simulation()
+{
+ const VertexAttribState& state = m_vertexAttribState[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()));
+}
+
+int WebGLRenderingContext::getNumberOfExtensions()
+{
+ return (m_webkitLoseContext ? 1 : 0) + (m_oesTextureFloat ? 1 : 0);
+}
+
+WebGLExtension* WebGLRenderingContext::getExtensionNumber(int i)
+{
+ if (m_webkitLoseContext) {
+ if (!i)
+ return m_webkitLoseContext.get();
+ --i;
+ }
+ if (m_oesTextureFloat) {
+ if (!i)
+ return m_oesTextureFloat.get();
+ --i;
+ }
+ // Similar tests for other extensions would go here.
+ return 0;
+}
+
+WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache(int capacity)
+ : m_buffers(new OwnPtr<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->size() != size)
+ continue;
+ bubbleToFront(i);
+ return buf;
+ }
+
+ OwnPtr<ImageBuffer> temp = ImageBuffer::create(size);
+ if (!temp)
+ return 0;
+ i = std::min(m_capacity - 1, i);
+ m_buffers[i] = temp.release();
+
+ 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 WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h
new file mode 100644
index 0000000..c40847f
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h
@@ -0,0 +1,607 @@
+/*
+ * 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.
+ * 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 WebGLRenderingContext_h
+#define WebGLRenderingContext_h
+
+#include "CanvasRenderingContext.h"
+#include "ExceptionCode.h"
+#include "Float32Array.h"
+#include "GraphicsContext3D.h"
+#include "Int32Array.h"
+#include "PlatformString.h"
+#include "Timer.h"
+#include "Uint8Array.h"
+#include "WebGLGetInfo.h"
+
+#include <wtf/OwnArrayPtr.h>
+
+namespace WebCore {
+
+class WebGLActiveInfo;
+class WebGLBuffer;
+class WebGLContextAttributes;
+class WebGLExtension;
+class WebGLFramebuffer;
+class WebGLObject;
+class WebGLProgram;
+class WebGLRenderbuffer;
+class WebGLShader;
+class WebGLTexture;
+class WebGLUniformLocation;
+class WebKitLoseContext;
+class HTMLImageElement;
+class HTMLVideoElement;
+class ImageBuffer;
+class ImageData;
+class IntSize;
+class OESTextureFloat;
+
+class WebGLRenderingContext : public CanvasRenderingContext {
+public:
+ static PassOwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*);
+ virtual ~WebGLRenderingContext();
+
+ virtual bool is3d() const { return true; }
+ virtual bool isAccelerated() const { return true; }
+ virtual bool paintsIntoCanvasBuffer() const;
+
+ void activeTexture(unsigned long texture, ExceptionCode& ec);
+ void attachShader(WebGLProgram*, WebGLShader*, ExceptionCode& ec);
+ void bindAttribLocation(WebGLProgram*, unsigned long index, const String& name, ExceptionCode& ec);
+ void bindBuffer(unsigned long target, WebGLBuffer*, ExceptionCode& ec);
+ void bindFramebuffer(unsigned long target, WebGLFramebuffer*, ExceptionCode& ec);
+ void bindRenderbuffer(unsigned long target, WebGLRenderbuffer*, ExceptionCode& ec);
+ void bindTexture(unsigned long target, WebGLTexture*, ExceptionCode& ec);
+ void blendColor(float red, float green, float blue, float alpha);
+ void blendEquation(unsigned long mode);
+ void blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha);
+ void blendFunc(unsigned long sfactor, unsigned long dfactor);
+ void blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha);
+
+ void bufferData(unsigned long target, int size, unsigned long usage, ExceptionCode&);
+ void bufferData(unsigned long target, ArrayBuffer* data, unsigned long usage, ExceptionCode&);
+ void bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage, ExceptionCode&);
+ void bufferSubData(unsigned long target, long offset, ArrayBuffer* data, ExceptionCode&);
+ void bufferSubData(unsigned long target, long offset, ArrayBufferView* data, ExceptionCode&);
+
+ unsigned long checkFramebufferStatus(unsigned long target);
+ void clear(unsigned long mask);
+ void clearColor(float red, float green, float blue, float alpha);
+ void clearDepth(float);
+ void clearStencil(long);
+ void colorMask(bool red, bool green, bool blue, bool alpha);
+ void compileShader(WebGLShader*, ExceptionCode& ec);
+
+ // void compressedTexImage2D(unsigned long target, long level, unsigned long internalformat, unsigned long width, unsigned long height, long border, unsigned long imageSize, const void* data);
+ // void compressedTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, unsigned long width, unsigned long height, unsigned long format, unsigned long imageSize, const void* data);
+
+ void copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, long width, long height, long border);
+ void copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, long width, long height);
+
+ PassRefPtr<WebGLBuffer> createBuffer();
+ PassRefPtr<WebGLFramebuffer> createFramebuffer();
+ PassRefPtr<WebGLProgram> createProgram();
+ PassRefPtr<WebGLRenderbuffer> createRenderbuffer();
+ PassRefPtr<WebGLShader> createShader(unsigned long type, ExceptionCode&);
+ PassRefPtr<WebGLTexture> createTexture();
+
+ void cullFace(unsigned long mode);
+
+ void deleteBuffer(WebGLBuffer*);
+ void deleteFramebuffer(WebGLFramebuffer*);
+ void deleteProgram(WebGLProgram*);
+ void deleteRenderbuffer(WebGLRenderbuffer*);
+ void deleteShader(WebGLShader*);
+ void deleteTexture(WebGLTexture*);
+
+ void depthFunc(unsigned long);
+ void depthMask(bool);
+ void depthRange(float zNear, float zFar);
+ void detachShader(WebGLProgram*, WebGLShader*, ExceptionCode&);
+ void disable(unsigned long cap);
+ void disableVertexAttribArray(unsigned long index, ExceptionCode&);
+ void drawArrays(unsigned long mode, long first, long count, ExceptionCode&);
+ void drawElements(unsigned long mode, long count, unsigned long type, long offset, ExceptionCode&);
+
+ void enable(unsigned long cap);
+ void enableVertexAttribArray(unsigned long index, ExceptionCode&);
+ void finish();
+ void flush();
+ void framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer*, ExceptionCode& ec);
+ void framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture*, long level, ExceptionCode& ec);
+ void frontFace(unsigned long mode);
+ void generateMipmap(unsigned long target);
+
+ PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, unsigned long index, ExceptionCode&);
+ PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, unsigned long index, ExceptionCode&);
+
+ bool getAttachedShaders(WebGLProgram*, Vector<WebGLShader*>&, ExceptionCode&);
+
+ int getAttribLocation(WebGLProgram*, const String& name);
+
+ WebGLGetInfo getBufferParameter(unsigned long target, unsigned long pname, ExceptionCode&);
+
+ PassRefPtr<WebGLContextAttributes> getContextAttributes();
+
+ unsigned long getError();
+
+ WebGLExtension* getExtension(const String& name);
+
+ WebGLGetInfo getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, unsigned long pname, ExceptionCode&);
+
+ WebGLGetInfo getParameter(unsigned long pname, ExceptionCode&);
+
+ WebGLGetInfo getProgramParameter(WebGLProgram*, unsigned long pname, ExceptionCode&);
+
+ String getProgramInfoLog(WebGLProgram*, ExceptionCode& ec);
+
+ WebGLGetInfo getRenderbufferParameter(unsigned long target, unsigned long pname, ExceptionCode&);
+
+ WebGLGetInfo getShaderParameter(WebGLShader*, unsigned long pname, ExceptionCode& ec);
+
+ String getShaderInfoLog(WebGLShader*, ExceptionCode& ec);
+
+ // TBD
+ // void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+
+ String getShaderSource(WebGLShader*, ExceptionCode&);
+
+ Vector<String> getSupportedExtensions();
+
+ WebGLGetInfo getTexParameter(unsigned long target, unsigned long pname, ExceptionCode&);
+
+ WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*, ExceptionCode&);
+
+ PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&, ExceptionCode&);
+
+ WebGLGetInfo getVertexAttrib(unsigned long index, unsigned long pname, ExceptionCode&);
+
+ long getVertexAttribOffset(unsigned long index, unsigned long pname);
+
+ void hint(unsigned long target, unsigned long mode);
+ bool isBuffer(WebGLBuffer*);
+ bool isContextLost();
+ bool isEnabled(unsigned long cap);
+ bool isFramebuffer(WebGLFramebuffer*);
+ bool isProgram(WebGLProgram*);
+ bool isRenderbuffer(WebGLRenderbuffer*);
+ bool isShader(WebGLShader*);
+ bool isTexture(WebGLTexture*);
+ void lineWidth(float);
+ void linkProgram(WebGLProgram*, ExceptionCode&);
+ void pixelStorei(unsigned long pname, long param);
+ void polygonOffset(float factor, float units);
+ void readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels, ExceptionCode&);
+ void releaseShaderCompiler();
+ void renderbufferStorage(unsigned long target, unsigned long internalformat, long width, long height);
+ void sampleCoverage(float value, bool invert);
+ void scissor(long x, long y, long width, long height);
+ void shaderSource(WebGLShader*, const String&, ExceptionCode&);
+ void stencilFunc(unsigned long func, long ref, unsigned long mask);
+ void stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask);
+ void stencilMask(unsigned long);
+ void stencilMaskSeparate(unsigned long face, unsigned long mask);
+ void stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass);
+ void stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass);
+
+ void texImage2D(unsigned target, unsigned level, unsigned internalformat,
+ int width, int height, unsigned border,
+ unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode&);
+ void texImage2D(unsigned target, unsigned level, unsigned internalformat,
+ unsigned format, unsigned type, ImageData* pixels, ExceptionCode&);
+ void texImage2D(unsigned target, unsigned level, unsigned internalformat,
+ unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode&);
+ void texImage2D(unsigned target, unsigned level, unsigned internalformat,
+ unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode&);
+ void texImage2D(unsigned target, unsigned level, unsigned internalformat,
+ unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode&);
+
+ void texParameterf(unsigned target, unsigned pname, float param);
+ void texParameteri(unsigned target, unsigned pname, int param);
+
+ void texSubImage2D(unsigned target, unsigned level, int xoffset, int yoffset,
+ int width, int height,
+ unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode&);
+ void texSubImage2D(unsigned target, unsigned level, int xoffset, int yoffset,
+ unsigned format, unsigned type, ImageData* pixels, ExceptionCode&);
+ void texSubImage2D(unsigned target, unsigned level, int xoffset, int yoffset,
+ unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode&);
+ void texSubImage2D(unsigned target, unsigned level, int xoffset, int yoffset,
+ unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode&);
+ void texSubImage2D(unsigned target, unsigned level, int xoffset, int yoffset,
+ unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode&);
+
+ void uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode&);
+ void uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
+ void uniform1fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode&);
+ void uniform1i(const WebGLUniformLocation* location, int x, ExceptionCode&);
+ void uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
+ void uniform1iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode&);
+ void uniform2f(const WebGLUniformLocation* location, float x, float y, ExceptionCode&);
+ void uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
+ void uniform2fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode&);
+ void uniform2i(const WebGLUniformLocation* location, int x, int y, ExceptionCode&);
+ void uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
+ void uniform2iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode&);
+ void uniform3f(const WebGLUniformLocation* location, float x, float y, float z, ExceptionCode&);
+ void uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
+ void uniform3fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode&);
+ void uniform3i(const WebGLUniformLocation* location, int x, int y, int z, ExceptionCode&);
+ void uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
+ void uniform3iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode&);
+ void uniform4f(const WebGLUniformLocation* location, float x, float y, float z, float w, ExceptionCode&);
+ void uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&);
+ void uniform4fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode&);
+ void uniform4i(const WebGLUniformLocation* location, int x, int y, int z, int w, ExceptionCode&);
+ void uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode&);
+ void uniform4iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode&);
+ void uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, Float32Array* value, ExceptionCode&);
+ void uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, float* value, int size, ExceptionCode&);
+ void uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, Float32Array* value, ExceptionCode&);
+ void uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, float* value, int size, ExceptionCode&);
+ void uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, Float32Array* value, ExceptionCode&);
+ void uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, float* value, int size, ExceptionCode&);
+
+ void useProgram(WebGLProgram*, ExceptionCode&);
+ void validateProgram(WebGLProgram*, ExceptionCode&);
+
+ void vertexAttrib1f(unsigned long index, float x);
+ void vertexAttrib1fv(unsigned long index, Float32Array* values);
+ void vertexAttrib1fv(unsigned long index, float* values, int size);
+ void vertexAttrib2f(unsigned long index, float x, float y);
+ void vertexAttrib2fv(unsigned long index, Float32Array* values);
+ void vertexAttrib2fv(unsigned long index, float* values, int size);
+ void vertexAttrib3f(unsigned long index, float x, float y, float z);
+ void vertexAttrib3fv(unsigned long index, Float32Array* values);
+ void vertexAttrib3fv(unsigned long index, float* values, int size);
+ void vertexAttrib4f(unsigned long index, float x, float y, float z, float w);
+ void vertexAttrib4fv(unsigned long index, Float32Array* values);
+ void vertexAttrib4fv(unsigned long index, float* values, int size);
+ void vertexAttribPointer(unsigned long index, long size, unsigned long type, bool normalized,
+ long stride, long offset, ExceptionCode&);
+
+ void viewport(long x, long y, long width, long height);
+
+ void forceLostContext();
+ void onLostContext();
+ void restoreContext();
+
+ GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
+#if USE(ACCELERATED_COMPOSITING)
+ virtual PlatformLayer* platformLayer() const { return m_context->platformLayer(); }
+#endif
+
+ void reshape(int width, int height);
+
+ virtual void paintRenderingResultsToCanvas();
+
+ void removeObject(WebGLObject*);
+
+ // Helpers for JSC bindings.
+ int getNumberOfExtensions();
+ WebGLExtension* getExtensionNumber(int i);
+
+ private:
+ friend class WebGLObject;
+
+ WebGLRenderingContext(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>, GraphicsContext3D::Attributes);
+ void initializeNewContext();
+ void setupFlags();
+
+ void addObject(WebGLObject*);
+ void detachAndRemoveAllObjects();
+ WebGLTexture* findTexture(Platform3DObject);
+ WebGLRenderbuffer* findRenderbuffer(Platform3DObject);
+ WebGLBuffer* findBuffer(Platform3DObject);
+ WebGLShader* findShader(Platform3DObject);
+
+ 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.
+ int sizeInBytes(int type);
+
+ // Basic validation of count and offset against number of elements in element array buffer
+ bool validateElementArraySize(unsigned long count, unsigned long type, long offset);
+
+ // Conservative but quick index validation
+ bool validateIndexArrayConservative(unsigned long type, long& numElementsRequired);
+
+ // Precise but slow index validation -- only done if conservative checks fail
+ bool validateIndexArrayPrecise(unsigned long count, unsigned long type, long offset, long& numElementsRequired);
+ // If numElements <= 0, we only check if each enabled vertex attribute is bound to a buffer.
+ bool validateRenderingState(long numElements);
+
+ bool validateWebGLObject(WebGLObject* object);
+
+ PassRefPtr<Image> videoFrameToImage(HTMLVideoElement* video);
+
+ RefPtr<GraphicsContext3D> m_context;
+
+ class WebGLRenderingContextRestoreTimer : public TimerBase {
+ public:
+ WebGLRenderingContextRestoreTimer(WebGLRenderingContext* context) : m_context(context) { }
+ private:
+ virtual void fired();
+ WebGLRenderingContext* m_context;
+ };
+
+ WebGLRenderingContextRestoreTimer m_restoreTimer;
+
+ bool m_needsUpdate;
+ bool m_markedCanvasDirty;
+ HashSet<RefPtr<WebGLObject> > m_canvasObjects;
+
+ // 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<WebGLBuffer> m_boundElementArrayBuffer;
+
+ // Cached values for vertex attrib range checks
+ class VertexAttribState {
+ public:
+ VertexAttribState()
+ : enabled(false)
+ , bytesPerElement(0)
+ , size(4)
+ , type(GraphicsContext3D::FLOAT)
+ , normalized(false)
+ , stride(16)
+ , originalStride(0)
+ , offset(0)
+ {
+ initValue();
+ }
+
+ void initValue()
+ {
+ value[0] = 0.0f;
+ value[1] = 0.0f;
+ value[2] = 0.0f;
+ value[3] = 1.0f;
+ }
+
+ bool enabled;
+ RefPtr<WebGLBuffer> bufferBinding;
+ long bytesPerElement;
+ long size;
+ unsigned long type;
+ bool normalized;
+ long stride;
+ long originalStride;
+ long offset;
+ float value[4];
+ };
+
+ Vector<VertexAttribState> m_vertexAttribState;
+ unsigned m_maxVertexAttribs;
+ RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
+ long m_vertexAttrib0BufferSize;
+ float m_vertexAttrib0BufferValue[4];
+
+ RefPtr<WebGLProgram> m_currentProgram;
+ RefPtr<WebGLFramebuffer> m_framebufferBinding;
+ RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
+ class TextureUnitState {
+ public:
+ RefPtr<WebGLTexture> m_texture2DBinding;
+ RefPtr<WebGLTexture> m_textureCubeMapBinding;
+ };
+ Vector<TextureUnitState> m_textureUnits;
+ unsigned long m_activeTextureUnit;
+
+ RefPtr<WebGLTexture> m_blackTexture2D;
+ RefPtr<WebGLTexture> m_blackTextureCubeMap;
+
+ // 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);
+ OwnArrayPtr<OwnPtr<ImageBuffer> > m_buffers;
+ int m_capacity;
+ };
+ LRUImageBufferCache m_videoCache;
+
+ int m_maxTextureSize;
+ int m_maxCubeMapTextureSize;
+ int m_maxTextureLevel;
+ int m_maxCubeMapTextureLevel;
+
+ int m_packAlignment;
+ int m_unpackAlignment;
+ bool m_unpackFlipY;
+ bool m_unpackPremultiplyAlpha;
+ unsigned long m_unpackColorspaceConversion;
+ bool m_contextLost;
+ GraphicsContext3D::Attributes m_attributes;
+
+ long m_stencilBits;
+ unsigned long m_stencilMask, m_stencilMaskBack;
+ long m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
+ unsigned long m_stencilFuncMask, m_stencilFuncMaskBack;
+
+ bool m_isGLES2Compliant;
+ bool m_isGLES2NPOTStrict;
+ bool m_isErrorGeneratedOnOutOfBoundsAccesses;
+ bool m_isResourceSafe;
+ bool m_isDepthStencilSupported;
+
+ // Enabled extension objects.
+ RefPtr<OESTextureFloat> m_oesTextureFloat;
+ RefPtr<WebKitLoseContext> m_webkitLoseContext;
+
+ // Helpers for getParameter and others
+ WebGLGetInfo getBooleanParameter(unsigned long pname);
+ WebGLGetInfo getBooleanArrayParameter(unsigned long pname);
+ WebGLGetInfo getFloatParameter(unsigned long pname);
+ WebGLGetInfo getIntParameter(unsigned long pname);
+ WebGLGetInfo getLongParameter(unsigned long pname);
+ WebGLGetInfo getUnsignedLongParameter(unsigned long pname);
+ WebGLGetInfo getWebGLFloatArrayParameter(unsigned long pname);
+ WebGLGetInfo getWebGLIntArrayParameter(unsigned long pname);
+
+ void texImage2DBase(unsigned target, unsigned level, unsigned internalformat,
+ int width, int height, unsigned border,
+ unsigned format, unsigned type, void* pixels, ExceptionCode&);
+ void texImage2DImpl(unsigned target, unsigned level, unsigned internalformat,
+ unsigned format, unsigned type, Image* image,
+ bool flipY, bool premultiplyAlpha, ExceptionCode&);
+ void texSubImage2DBase(unsigned target, unsigned level, int xoffset, int yoffset,
+ int width, int height,
+ unsigned format, unsigned type, void* pixels, ExceptionCode&);
+ void texSubImage2DImpl(unsigned target, unsigned level, int xoffset, int yoffset,
+ unsigned format, unsigned type,
+ Image* image, bool flipY, bool premultiplyAlpha, ExceptionCode&);
+
+ void handleNPOTTextures(bool prepareToDraw);
+
+ 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(unsigned long texInternalFormat,
+ unsigned long colorBufferFormat);
+
+ // Helper function to get the bound framebuffer's color buffer format.
+ unsigned long 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 check if size is non-negative.
+ // Generate GL error and return false for negative inputs; otherwise, return true.
+ bool validateSize(long x, long 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 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(unsigned long 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(unsigned long format, unsigned long type);
+
+ // Helper function to check input level for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if level is invalid.
+ bool validateTexFuncLevel(unsigned long target, long level);
+
+ // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if parameters are invalid.
+ bool validateTexFuncParameters(unsigned long target, long level,
+ unsigned long internalformat,
+ long width, long height, long border,
+ unsigned long format, unsigned long type);
+
+ // 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(long width, long height,
+ unsigned long format, unsigned long type,
+ ArrayBufferView* pixels);
+
+ // Helper function to validate mode for draw{Arrays/Elements}.
+ bool validateDrawMode(unsigned long);
+
+ // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
+ bool validateStencilSettings();
+
+ // Helper function to validate stencil func.
+ bool validateStencilFunc(unsigned long);
+
+ // Helper function for texParameterf and texParameteri.
+ void texParameter(unsigned long target, unsigned long pname, float parami, int paramf, bool isFloat);
+
+ // Helper function to print warnings to console. Currently
+ // used only to warn about use of obsolete functions.
+ void printWarningToConsole(const String& message);
+
+ // Helper function to validate input parameters for framebuffer functions.
+ // Generate GL error if parameters are illegal.
+ bool validateFramebufferFuncParameters(unsigned long target, unsigned long attachment);
+
+ // Helper function to validate blend equation mode.
+ bool validateBlendEquation(unsigned long);
+
+ // Helper function to validate blend func factors.
+ bool validateBlendFuncFactors(unsigned long src, unsigned long dst);
+
+ // Helper function to validate a GL capability.
+ bool validateCapability(unsigned long);
+
+ // Helper function to validate input parameters for uniform functions.
+ bool validateUniformParameters(const WebGLUniformLocation* location, Float32Array* v, int mod);
+ bool validateUniformParameters(const WebGLUniformLocation* location, Int32Array* v, int mod);
+ bool validateUniformParameters(const WebGLUniformLocation* location, void* v, int size, int mod);
+ bool validateUniformMatrixParameters(const WebGLUniformLocation* location, bool transpose, Float32Array* v, int mod);
+ bool validateUniformMatrixParameters(const WebGLUniformLocation* location, bool transpose, void* v, int size, int mod);
+
+ // Helper function to validate parameters for bufferData.
+ // Return the current bound buffer to target, or 0 if parameters are invalid.
+ WebGLBuffer* validateBufferDataParameters(unsigned long target, unsigned long usage);
+
+ // Helper functions for vertexAttribNf{v}.
+ void vertexAttribfImpl(unsigned long index, int expectedSize, float v0, float v1, float v2, float v3);
+ void vertexAttribfvImpl(unsigned long index, Float32Array* v, int expectedSize);
+ void vertexAttribfvImpl(unsigned long index, float* v, int size, int expectedSize);
+
+ // Helpers for simulating vertexAttrib0
+ void initVertexAttrib0();
+ bool simulateVertexAttrib0(long numVertex);
+ void restoreStatesAfterVertexAttrib0Simulation();
+
+ friend class WebGLStateRestorer;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.idl b/Source/WebCore/html/canvas/WebGLRenderingContext.idl
new file mode 100644
index 0000000..40b9bb0
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.idl
@@ -0,0 +1,669 @@
+/*
+ * 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.
+ * 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.
+ */
+
+module html {
+
+ interface [
+ Conditional=3D_CANVAS,
+ InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443,
+ ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54,
+ CustomMarkFunction,
+ DontCheckEnums
+ ] WebGLRenderingContext : CanvasRenderingContext {
+
+ /* ClearBufferMask */
+ const unsigned int DEPTH_BUFFER_BIT = 0x00000100;
+ const unsigned int STENCIL_BUFFER_BIT = 0x00000400;
+ const unsigned int COLOR_BUFFER_BIT = 0x00004000;
+
+ /* BeginMode */
+ const unsigned int POINTS = 0x0000;
+ const unsigned int LINES = 0x0001;
+ const unsigned int LINE_LOOP = 0x0002;
+ const unsigned int LINE_STRIP = 0x0003;
+ const unsigned int TRIANGLES = 0x0004;
+ const unsigned int TRIANGLE_STRIP = 0x0005;
+ const unsigned int TRIANGLE_FAN = 0x0006;
+
+ /* AlphaFunction (not supported in ES20) */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* BlendingFactorDest */
+ const unsigned int ZERO = 0;
+ const unsigned int ONE = 1;
+ const unsigned int SRC_COLOR = 0x0300;
+ const unsigned int ONE_MINUS_SRC_COLOR = 0x0301;
+ const unsigned int SRC_ALPHA = 0x0302;
+ const unsigned int ONE_MINUS_SRC_ALPHA = 0x0303;
+ const unsigned int DST_ALPHA = 0x0304;
+ const unsigned int ONE_MINUS_DST_ALPHA = 0x0305;
+
+ /* BlendingFactorSrc */
+ /* ZERO */
+ /* ONE */
+ const unsigned int DST_COLOR = 0x0306;
+ const unsigned int ONE_MINUS_DST_COLOR = 0x0307;
+ const unsigned int SRC_ALPHA_SATURATE = 0x0308;
+ /* SRC_ALPHA */
+ /* ONE_MINUS_SRC_ALPHA */
+ /* DST_ALPHA */
+ /* ONE_MINUS_DST_ALPHA */
+
+ /* BlendEquationSeparate */
+ const unsigned int FUNC_ADD = 0x8006;
+ const unsigned int BLEND_EQUATION = 0x8009;
+ const unsigned int BLEND_EQUATION_RGB = 0x8009; /* same as BLEND_EQUATION */
+ const unsigned int BLEND_EQUATION_ALPHA = 0x883D;
+
+ /* BlendSubtract */
+ const unsigned int FUNC_SUBTRACT = 0x800A;
+ const unsigned int FUNC_REVERSE_SUBTRACT = 0x800B;
+
+ /* Separate Blend Functions */
+ const unsigned int BLEND_DST_RGB = 0x80C8;
+ const unsigned int BLEND_SRC_RGB = 0x80C9;
+ const unsigned int BLEND_DST_ALPHA = 0x80CA;
+ const unsigned int BLEND_SRC_ALPHA = 0x80CB;
+ const unsigned int CONSTANT_COLOR = 0x8001;
+ const unsigned int ONE_MINUS_CONSTANT_COLOR = 0x8002;
+ const unsigned int CONSTANT_ALPHA = 0x8003;
+ const unsigned int ONE_MINUS_CONSTANT_ALPHA = 0x8004;
+ const unsigned int BLEND_COLOR = 0x8005;
+
+ /* Buffer Objects */
+ const unsigned int ARRAY_BUFFER = 0x8892;
+ const unsigned int ELEMENT_ARRAY_BUFFER = 0x8893;
+ const unsigned int ARRAY_BUFFER_BINDING = 0x8894;
+ const unsigned int ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
+
+ const unsigned int STREAM_DRAW = 0x88E0;
+ const unsigned int STATIC_DRAW = 0x88E4;
+ const unsigned int DYNAMIC_DRAW = 0x88E8;
+
+ const unsigned int BUFFER_SIZE = 0x8764;
+ const unsigned int BUFFER_USAGE = 0x8765;
+
+ const unsigned int CURRENT_VERTEX_ATTRIB = 0x8626;
+
+ /* CullFaceMode */
+ const unsigned int FRONT = 0x0404;
+ const unsigned int BACK = 0x0405;
+ const unsigned int FRONT_AND_BACK = 0x0408;
+
+ /* DepthFunction */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* EnableCap */
+ const unsigned int TEXTURE_2D = 0x0DE1;
+ const unsigned int CULL_FACE = 0x0B44;
+ const unsigned int BLEND = 0x0BE2;
+ const unsigned int DITHER = 0x0BD0;
+ const unsigned int STENCIL_TEST = 0x0B90;
+ const unsigned int DEPTH_TEST = 0x0B71;
+ const unsigned int SCISSOR_TEST = 0x0C11;
+ const unsigned int POLYGON_OFFSET_FILL = 0x8037;
+ const unsigned int SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
+ const unsigned int SAMPLE_COVERAGE = 0x80A0;
+
+ /* ErrorCode */
+ const unsigned int NO_ERROR = 0;
+ const unsigned int INVALID_ENUM = 0x0500;
+ const unsigned int INVALID_VALUE = 0x0501;
+ const unsigned int INVALID_OPERATION = 0x0502;
+ const unsigned int OUT_OF_MEMORY = 0x0505;
+
+ /* FrontFaceDirection */
+ const unsigned int CW = 0x0900;
+ const unsigned int CCW = 0x0901;
+
+ /* GetPName */
+ const unsigned int LINE_WIDTH = 0x0B21;
+ const unsigned int ALIASED_POINT_SIZE_RANGE = 0x846D;
+ const unsigned int ALIASED_LINE_WIDTH_RANGE = 0x846E;
+ const unsigned int CULL_FACE_MODE = 0x0B45;
+ const unsigned int FRONT_FACE = 0x0B46;
+ const unsigned int DEPTH_RANGE = 0x0B70;
+ const unsigned int DEPTH_WRITEMASK = 0x0B72;
+ const unsigned int DEPTH_CLEAR_VALUE = 0x0B73;
+ const unsigned int DEPTH_FUNC = 0x0B74;
+ const unsigned int STENCIL_CLEAR_VALUE = 0x0B91;
+ const unsigned int STENCIL_FUNC = 0x0B92;
+ const unsigned int STENCIL_FAIL = 0x0B94;
+ const unsigned int STENCIL_PASS_DEPTH_FAIL = 0x0B95;
+ const unsigned int STENCIL_PASS_DEPTH_PASS = 0x0B96;
+ const unsigned int STENCIL_REF = 0x0B97;
+ const unsigned int STENCIL_VALUE_MASK = 0x0B93;
+ const unsigned int STENCIL_WRITEMASK = 0x0B98;
+ const unsigned int STENCIL_BACK_FUNC = 0x8800;
+ const unsigned int STENCIL_BACK_FAIL = 0x8801;
+ const unsigned int STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
+ const unsigned int STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
+ const unsigned int STENCIL_BACK_REF = 0x8CA3;
+ const unsigned int STENCIL_BACK_VALUE_MASK = 0x8CA4;
+ const unsigned int STENCIL_BACK_WRITEMASK = 0x8CA5;
+ const unsigned int VIEWPORT = 0x0BA2;
+ const unsigned int SCISSOR_BOX = 0x0C10;
+ /* SCISSOR_TEST */
+ const unsigned int COLOR_CLEAR_VALUE = 0x0C22;
+ const unsigned int COLOR_WRITEMASK = 0x0C23;
+ const unsigned int UNPACK_ALIGNMENT = 0x0CF5;
+ const unsigned int PACK_ALIGNMENT = 0x0D05;
+ const unsigned int MAX_TEXTURE_SIZE = 0x0D33;
+ const unsigned int MAX_VIEWPORT_DIMS = 0x0D3A;
+ const unsigned int SUBPIXEL_BITS = 0x0D50;
+ const unsigned int RED_BITS = 0x0D52;
+ const unsigned int GREEN_BITS = 0x0D53;
+ const unsigned int BLUE_BITS = 0x0D54;
+ const unsigned int ALPHA_BITS = 0x0D55;
+ const unsigned int DEPTH_BITS = 0x0D56;
+ const unsigned int STENCIL_BITS = 0x0D57;
+ const unsigned int POLYGON_OFFSET_UNITS = 0x2A00;
+ /* POLYGON_OFFSET_FILL */
+ const unsigned int POLYGON_OFFSET_FACTOR = 0x8038;
+ const unsigned int TEXTURE_BINDING_2D = 0x8069;
+ const unsigned int SAMPLE_BUFFERS = 0x80A8;
+ const unsigned int SAMPLES = 0x80A9;
+ const unsigned int SAMPLE_COVERAGE_VALUE = 0x80AA;
+ const unsigned int SAMPLE_COVERAGE_INVERT = 0x80AB;
+
+ /* GetTextureParameter */
+ /* TEXTURE_MAG_FILTER */
+ /* TEXTURE_MIN_FILTER */
+ /* TEXTURE_WRAP_S */
+ /* TEXTURE_WRAP_T */
+
+ const unsigned int NUM_COMPRESSED_TEXTURE_FORMATS = 0x86A2;
+ const unsigned int COMPRESSED_TEXTURE_FORMATS = 0x86A3;
+
+ /* HintMode */
+ const unsigned int DONT_CARE = 0x1100;
+ const unsigned int FASTEST = 0x1101;
+ const unsigned int NICEST = 0x1102;
+
+ /* HintTarget */
+ const unsigned int GENERATE_MIPMAP_HINT = 0x8192;
+
+ /* DataType */
+ const unsigned int BYTE = 0x1400;
+ const unsigned int UNSIGNED_BYTE = 0x1401;
+ const unsigned int SHORT = 0x1402;
+ const unsigned int UNSIGNED_SHORT = 0x1403;
+ const unsigned int INT = 0x1404;
+ const unsigned int UNSIGNED_INT = 0x1405;
+ const unsigned int FLOAT = 0x1406;
+
+ /* PixelFormat */
+ const unsigned int DEPTH_COMPONENT = 0x1902;
+ const unsigned int ALPHA = 0x1906;
+ const unsigned int RGB = 0x1907;
+ const unsigned int RGBA = 0x1908;
+ const unsigned int LUMINANCE = 0x1909;
+ const unsigned int LUMINANCE_ALPHA = 0x190A;
+
+ /* PixelType */
+ /* UNSIGNED_BYTE */
+ const unsigned int UNSIGNED_SHORT_4_4_4_4 = 0x8033;
+ const unsigned int UNSIGNED_SHORT_5_5_5_1 = 0x8034;
+ const unsigned int UNSIGNED_SHORT_5_6_5 = 0x8363;
+
+ /* Shaders */
+ const unsigned int FRAGMENT_SHADER = 0x8B30;
+ const unsigned int VERTEX_SHADER = 0x8B31;
+ const unsigned int MAX_VERTEX_ATTRIBS = 0x8869;
+ const unsigned int MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
+ const unsigned int MAX_VARYING_VECTORS = 0x8DFC;
+ const unsigned int MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
+ const unsigned int MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
+ const unsigned int MAX_TEXTURE_IMAGE_UNITS = 0x8872;
+ const unsigned int MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
+ const unsigned int SHADER_TYPE = 0x8B4F;
+ const unsigned int DELETE_STATUS = 0x8B80;
+ const unsigned int LINK_STATUS = 0x8B82;
+ const unsigned int VALIDATE_STATUS = 0x8B83;
+ const unsigned int ATTACHED_SHADERS = 0x8B85;
+ const unsigned int ACTIVE_UNIFORMS = 0x8B86;
+ const unsigned int ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87;
+ const unsigned int ACTIVE_ATTRIBUTES = 0x8B89;
+ const unsigned int ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A;
+ const unsigned int SHADING_LANGUAGE_VERSION = 0x8B8C;
+ const unsigned int CURRENT_PROGRAM = 0x8B8D;
+
+ /* StencilFunction */
+ const unsigned int NEVER = 0x0200;
+ const unsigned int LESS = 0x0201;
+ const unsigned int EQUAL = 0x0202;
+ const unsigned int LEQUAL = 0x0203;
+ const unsigned int GREATER = 0x0204;
+ const unsigned int NOTEQUAL = 0x0205;
+ const unsigned int GEQUAL = 0x0206;
+ const unsigned int ALWAYS = 0x0207;
+
+ /* StencilOp */
+ /* ZERO */
+ const unsigned int KEEP = 0x1E00;
+ const unsigned int REPLACE = 0x1E01;
+ const unsigned int INCR = 0x1E02;
+ const unsigned int DECR = 0x1E03;
+ const unsigned int INVERT = 0x150A;
+ const unsigned int INCR_WRAP = 0x8507;
+ const unsigned int DECR_WRAP = 0x8508;
+
+ /* StringName */
+ const unsigned int VENDOR = 0x1F00;
+ const unsigned int RENDERER = 0x1F01;
+ const unsigned int VERSION = 0x1F02;
+
+ /* TextureMagFilter */
+ const unsigned int NEAREST = 0x2600;
+ const unsigned int LINEAR = 0x2601;
+
+ /* TextureMinFilter */
+ /* NEAREST */
+ /* LINEAR */
+ const unsigned int NEAREST_MIPMAP_NEAREST = 0x2700;
+ const unsigned int LINEAR_MIPMAP_NEAREST = 0x2701;
+ const unsigned int NEAREST_MIPMAP_LINEAR = 0x2702;
+ const unsigned int LINEAR_MIPMAP_LINEAR = 0x2703;
+
+ /* TextureParameterName */
+ const unsigned int TEXTURE_MAG_FILTER = 0x2800;
+ const unsigned int TEXTURE_MIN_FILTER = 0x2801;
+ const unsigned int TEXTURE_WRAP_S = 0x2802;
+ const unsigned int TEXTURE_WRAP_T = 0x2803;
+
+ /* TextureTarget */
+ /* TEXTURE_2D */
+ const unsigned int TEXTURE = 0x1702;
+
+ const unsigned int TEXTURE_CUBE_MAP = 0x8513;
+ const unsigned int TEXTURE_BINDING_CUBE_MAP = 0x8514;
+ const unsigned int TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
+ const unsigned int TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
+ const unsigned int TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
+ const unsigned int TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
+ const unsigned int TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
+ const unsigned int TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
+ const unsigned int MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
+
+ /* TextureUnit */
+ const unsigned int TEXTURE0 = 0x84C0;
+ const unsigned int TEXTURE1 = 0x84C1;
+ const unsigned int TEXTURE2 = 0x84C2;
+ const unsigned int TEXTURE3 = 0x84C3;
+ const unsigned int TEXTURE4 = 0x84C4;
+ const unsigned int TEXTURE5 = 0x84C5;
+ const unsigned int TEXTURE6 = 0x84C6;
+ const unsigned int TEXTURE7 = 0x84C7;
+ const unsigned int TEXTURE8 = 0x84C8;
+ const unsigned int TEXTURE9 = 0x84C9;
+ const unsigned int TEXTURE10 = 0x84CA;
+ const unsigned int TEXTURE11 = 0x84CB;
+ const unsigned int TEXTURE12 = 0x84CC;
+ const unsigned int TEXTURE13 = 0x84CD;
+ const unsigned int TEXTURE14 = 0x84CE;
+ const unsigned int TEXTURE15 = 0x84CF;
+ const unsigned int TEXTURE16 = 0x84D0;
+ const unsigned int TEXTURE17 = 0x84D1;
+ const unsigned int TEXTURE18 = 0x84D2;
+ const unsigned int TEXTURE19 = 0x84D3;
+ const unsigned int TEXTURE20 = 0x84D4;
+ const unsigned int TEXTURE21 = 0x84D5;
+ const unsigned int TEXTURE22 = 0x84D6;
+ const unsigned int TEXTURE23 = 0x84D7;
+ const unsigned int TEXTURE24 = 0x84D8;
+ const unsigned int TEXTURE25 = 0x84D9;
+ const unsigned int TEXTURE26 = 0x84DA;
+ const unsigned int TEXTURE27 = 0x84DB;
+ const unsigned int TEXTURE28 = 0x84DC;
+ const unsigned int TEXTURE29 = 0x84DD;
+ const unsigned int TEXTURE30 = 0x84DE;
+ const unsigned int TEXTURE31 = 0x84DF;
+ const unsigned int ACTIVE_TEXTURE = 0x84E0;
+
+ /* TextureWrapMode */
+ const unsigned int REPEAT = 0x2901;
+ const unsigned int CLAMP_TO_EDGE = 0x812F;
+ const unsigned int MIRRORED_REPEAT = 0x8370;
+
+ /* Uniform Types */
+ const unsigned int FLOAT_VEC2 = 0x8B50;
+ const unsigned int FLOAT_VEC3 = 0x8B51;
+ const unsigned int FLOAT_VEC4 = 0x8B52;
+ const unsigned int INT_VEC2 = 0x8B53;
+ const unsigned int INT_VEC3 = 0x8B54;
+ const unsigned int INT_VEC4 = 0x8B55;
+ const unsigned int BOOL = 0x8B56;
+ const unsigned int BOOL_VEC2 = 0x8B57;
+ const unsigned int BOOL_VEC3 = 0x8B58;
+ const unsigned int BOOL_VEC4 = 0x8B59;
+ const unsigned int FLOAT_MAT2 = 0x8B5A;
+ const unsigned int FLOAT_MAT3 = 0x8B5B;
+ const unsigned int FLOAT_MAT4 = 0x8B5C;
+ const unsigned int SAMPLER_2D = 0x8B5E;
+ const unsigned int SAMPLER_CUBE = 0x8B60;
+
+ /* Vertex Arrays */
+ const unsigned int VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
+ const unsigned int VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
+ const unsigned int VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
+ const unsigned int VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
+ const unsigned int VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
+ const unsigned int VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
+ const unsigned int VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+
+ /* Shader Source */
+ const unsigned int COMPILE_STATUS = 0x8B81;
+ const unsigned int INFO_LOG_LENGTH = 0x8B84;
+ const unsigned int SHADER_SOURCE_LENGTH = 0x8B88;
+ const unsigned int SHADER_COMPILER = 0x8DFA;
+
+ /* Shader Precision-Specified Types */
+ const unsigned int LOW_FLOAT = 0x8DF0;
+ const unsigned int MEDIUM_FLOAT = 0x8DF1;
+ const unsigned int HIGH_FLOAT = 0x8DF2;
+ const unsigned int LOW_INT = 0x8DF3;
+ const unsigned int MEDIUM_INT = 0x8DF4;
+ const unsigned int HIGH_INT = 0x8DF5;
+
+ /* Framebuffer Object. */
+ const unsigned int FRAMEBUFFER = 0x8D40;
+ const unsigned int RENDERBUFFER = 0x8D41;
+
+ const unsigned int RGBA4 = 0x8056;
+ const unsigned int RGB5_A1 = 0x8057;
+ const unsigned int RGB565 = 0x8D62;
+ const unsigned int DEPTH_COMPONENT16 = 0x81A5;
+ const unsigned int STENCIL_INDEX = 0x1901;
+ const unsigned int STENCIL_INDEX8 = 0x8D48;
+ const unsigned int DEPTH_STENCIL = 0x84F9;
+
+ const unsigned int RENDERBUFFER_WIDTH = 0x8D42;
+ const unsigned int RENDERBUFFER_HEIGHT = 0x8D43;
+ const unsigned int RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
+ const unsigned int RENDERBUFFER_RED_SIZE = 0x8D50;
+ const unsigned int RENDERBUFFER_GREEN_SIZE = 0x8D51;
+ const unsigned int RENDERBUFFER_BLUE_SIZE = 0x8D52;
+ const unsigned int RENDERBUFFER_ALPHA_SIZE = 0x8D53;
+ const unsigned int RENDERBUFFER_DEPTH_SIZE = 0x8D54;
+ const unsigned int RENDERBUFFER_STENCIL_SIZE = 0x8D55;
+
+ const unsigned int FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
+ const unsigned int FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
+ const unsigned int FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
+ const unsigned int FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
+
+ const unsigned int COLOR_ATTACHMENT0 = 0x8CE0;
+ const unsigned int DEPTH_ATTACHMENT = 0x8D00;
+ const unsigned int STENCIL_ATTACHMENT = 0x8D20;
+ const unsigned int DEPTH_STENCIL_ATTACHMENT = 0x821A;
+
+ const unsigned int NONE = 0;
+
+ const unsigned int FRAMEBUFFER_COMPLETE = 0x8CD5;
+ const unsigned int FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
+ const unsigned int FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
+ const unsigned int FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
+ const unsigned int FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
+
+ const unsigned int FRAMEBUFFER_BINDING = 0x8CA6;
+ const unsigned int RENDERBUFFER_BINDING = 0x8CA7;
+ const unsigned int MAX_RENDERBUFFER_SIZE = 0x84E8;
+
+ const unsigned int INVALID_FRAMEBUFFER_OPERATION = 0x0506;
+
+ /* WebGL-specific enums */
+ const unsigned int UNPACK_FLIP_Y_WEBGL = 0x9240;
+ const unsigned int UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
+ const unsigned int CONTEXT_LOST_WEBGL = 0x9242;
+ const unsigned int UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
+ const unsigned int BROWSER_DEFAULT_WEBGL = 0x9244;
+
+ [StrictTypeChecking] void activeTexture(in unsigned long texture) raises(DOMException);
+ [StrictTypeChecking] void attachShader(in WebGLProgram program, in WebGLShader shader) raises(DOMException);
+ [StrictTypeChecking] void bindAttribLocation(in WebGLProgram program, in unsigned long index, in DOMString name) raises(DOMException);
+ [StrictTypeChecking] void bindBuffer(in unsigned long target, in WebGLBuffer buffer) raises(DOMException);
+ [StrictTypeChecking] void bindFramebuffer(in unsigned long target, in WebGLFramebuffer framebuffer) raises(DOMException);
+ [StrictTypeChecking] void bindRenderbuffer(in unsigned long target, in WebGLRenderbuffer renderbuffer) raises(DOMException);
+ [StrictTypeChecking] void bindTexture(in unsigned long target, in WebGLTexture texture) raises(DOMException);
+ [StrictTypeChecking] void blendColor(in float red, in float green, in float blue, in float alpha);
+ [StrictTypeChecking] void blendEquation( in unsigned long mode );
+ [StrictTypeChecking] void blendEquationSeparate(in unsigned long modeRGB, in unsigned long modeAlpha);
+ [StrictTypeChecking] void blendFunc(in unsigned long sfactor, in unsigned long dfactor);
+ [StrictTypeChecking] void blendFuncSeparate(in unsigned long srcRGB, in unsigned long dstRGB, in unsigned long srcAlpha, in unsigned long dstAlpha);
+ [StrictTypeChecking] void bufferData(in unsigned long target, in ArrayBuffer data, in unsigned long usage) raises (DOMException);
+ [StrictTypeChecking] void bufferData(in unsigned long target, in ArrayBufferView data, in unsigned long usage) raises (DOMException);
+ [StrictTypeChecking] void bufferData(in unsigned long target, in long size, in unsigned long usage) raises (DOMException);
+ [StrictTypeChecking] void bufferSubData(in unsigned long target, in long offset, in ArrayBuffer data) raises (DOMException);
+ [StrictTypeChecking] void bufferSubData(in unsigned long target, in long offset, in ArrayBufferView data) raises (DOMException);
+
+ [StrictTypeChecking] unsigned long checkFramebufferStatus(in unsigned long target);
+ [StrictTypeChecking] void clear(in unsigned long mask);
+ [StrictTypeChecking] void clearColor(in float red, in float green, in float blue, in float alpha);
+ [StrictTypeChecking] void clearDepth(in float depth);
+ [StrictTypeChecking] void clearStencil(in long s);
+ [StrictTypeChecking] void colorMask(in boolean red, in boolean green, in boolean blue, in boolean alpha);
+ [StrictTypeChecking] void compileShader(in WebGLShader shader) raises(DOMException);
+
+ //void compressedTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in unsigned long width, in unsigned long height, in long border, in unsigned long imageSize, const void* data);
+ //void compressedTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in unsigned long width, in unsigned long height, in unsigned long format, in unsigned long imageSize, const void* data);
+
+ [StrictTypeChecking] void copyTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in long x, in long y, in long width, in long height, in long border);
+ [StrictTypeChecking] void copyTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in long x, in long y, in long width, in long height);
+
+ [StrictTypeChecking] WebGLBuffer createBuffer();
+ [StrictTypeChecking] WebGLFramebuffer createFramebuffer();
+ [StrictTypeChecking] WebGLProgram createProgram();
+ [StrictTypeChecking] WebGLRenderbuffer createRenderbuffer();
+ [StrictTypeChecking] WebGLShader createShader(in unsigned long type) raises(DOMException);
+ [StrictTypeChecking] WebGLTexture createTexture();
+
+ [StrictTypeChecking] void cullFace(in unsigned long mode);
+
+ [StrictTypeChecking] void deleteBuffer(in WebGLBuffer buffer);
+ [StrictTypeChecking] void deleteFramebuffer(in WebGLFramebuffer framebuffer);
+ [StrictTypeChecking] void deleteProgram(in WebGLProgram program);
+ [StrictTypeChecking] void deleteRenderbuffer(in WebGLRenderbuffer renderbuffer);
+ [StrictTypeChecking] void deleteShader(in WebGLShader shader);
+ [StrictTypeChecking] void deleteTexture(in WebGLTexture texture);
+
+ [StrictTypeChecking] void depthFunc(in unsigned long func);
+ [StrictTypeChecking] void depthMask(in boolean flag);
+ // FIXME: this differs from the current WebGL spec (depthRangef)
+ [StrictTypeChecking] void depthRange(in float zNear, in float zFar);
+ [StrictTypeChecking] void detachShader(in WebGLProgram program, in WebGLShader shader) raises(DOMException);
+ [StrictTypeChecking] void disable(in unsigned long cap);
+ [StrictTypeChecking] void disableVertexAttribArray(in unsigned long index) raises(DOMException);
+ [StrictTypeChecking] void drawArrays(in unsigned long mode, in long first, in long count) raises(DOMException);
+ [StrictTypeChecking] void drawElements(in unsigned long mode, in long count, in unsigned long type, in long offset) raises(DOMException);
+
+ [StrictTypeChecking] void enable(in unsigned long cap);
+ [StrictTypeChecking] void enableVertexAttribArray(in unsigned long index) raises(DOMException);
+ [StrictTypeChecking] void finish();
+ [StrictTypeChecking] void flush();
+ [StrictTypeChecking] void framebufferRenderbuffer(in unsigned long target, in unsigned long attachment, in unsigned long renderbuffertarget, in WebGLRenderbuffer renderbuffer) raises(DOMException);
+ [StrictTypeChecking] void framebufferTexture2D(in unsigned long target, in unsigned long attachment, in unsigned long textarget, in WebGLTexture texture, in long level) raises(DOMException);
+ [StrictTypeChecking] void frontFace(in unsigned long mode);
+ [StrictTypeChecking] void generateMipmap(in unsigned long target);
+
+ [StrictTypeChecking] WebGLActiveInfo getActiveAttrib(in WebGLProgram program, in unsigned long index) raises (DOMException);
+ [StrictTypeChecking] WebGLActiveInfo getActiveUniform(in WebGLProgram program, in unsigned long index) raises (DOMException);
+
+ [StrictTypeChecking, Custom] void getAttachedShaders(in WebGLProgram program) raises (DOMException);
+
+ [StrictTypeChecking] int getAttribLocation(in WebGLProgram program, in DOMString name);
+
+ // any getBufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getBufferParameter();
+
+ [StrictTypeChecking] WebGLContextAttributes getContextAttributes();
+
+ [StrictTypeChecking] unsigned long getError();
+
+ // object getExtension(in DOMString name);
+ [StrictTypeChecking, Custom] void getExtension(in DOMString name);
+
+ // any getFramebufferAttachmentParameter(in unsigned long target, in unsigned long attachment, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getFramebufferAttachmentParameter();
+ // any getParameter(in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getParameter();
+ // any getProgramParameter(in WebGLProgram program, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getProgramParameter();
+ [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getProgramInfoLog(in WebGLProgram program) raises(DOMException);
+ // any getRenderbufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getRenderbufferParameter();
+ // any getShaderParameter(in WebGLShader shader, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getShaderParameter() raises(DOMException);
+
+ [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getShaderInfoLog(in WebGLShader shader) raises(DOMException);
+
+ // TBD
+ // void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+
+ [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getShaderSource(in WebGLShader shader) raises(DOMException);
+
+ // DOMString[] getSupportedExtensions()
+ [StrictTypeChecking, Custom] void getSupportedExtensions();
+
+ // any getTexParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getTexParameter();
+
+ // any getUniform(in WebGLProgram program, in WebGLUniformLocation location) raises(DOMException);
+ [StrictTypeChecking, Custom] void getUniform();
+
+ [StrictTypeChecking] WebGLUniformLocation getUniformLocation(in WebGLProgram program, in DOMString name) raises(DOMException);
+
+ // any getVertexAttrib(in unsigned long index, in unsigned long pname) raises(DOMException);
+ [StrictTypeChecking, Custom] void getVertexAttrib();
+
+ [StrictTypeChecking] long getVertexAttribOffset(in unsigned long index, in unsigned long pname);
+
+ [StrictTypeChecking] void hint(in unsigned long target, in unsigned long mode);
+ [StrictTypeChecking] boolean isBuffer(in WebGLBuffer buffer);
+ [StrictTypeChecking] boolean isContextLost();
+ [StrictTypeChecking] boolean isEnabled(in unsigned long cap);
+ [StrictTypeChecking] boolean isFramebuffer(in WebGLFramebuffer framebuffer);
+ [StrictTypeChecking] boolean isProgram(in WebGLProgram program);
+ [StrictTypeChecking] boolean isRenderbuffer(in WebGLRenderbuffer renderbuffer);
+ [StrictTypeChecking] boolean isShader(in WebGLShader shader);
+ [StrictTypeChecking] boolean isTexture(in WebGLTexture texture);
+ [StrictTypeChecking] void lineWidth(in float width);
+ [StrictTypeChecking] void linkProgram(in WebGLProgram program) raises(DOMException);
+ [StrictTypeChecking] void pixelStorei(in unsigned long pname, in long param);
+ [StrictTypeChecking] void polygonOffset(in float factor, in float units);
+
+ [StrictTypeChecking] void readPixels(in long x, in long y, in long width, in long height, in unsigned long format, in unsigned long type, in ArrayBufferView pixels) raises(DOMException);
+
+ [StrictTypeChecking] void releaseShaderCompiler();
+ [StrictTypeChecking] void renderbufferStorage(in unsigned long target, in unsigned long internalformat, in long width, in long height);
+ [StrictTypeChecking] void sampleCoverage(in float value, in boolean invert);
+ [StrictTypeChecking] void scissor(in long x, in long y, in long width, in long height);
+ [StrictTypeChecking] void shaderSource(in WebGLShader shader, in DOMString string) raises(DOMException);
+ [StrictTypeChecking] void stencilFunc(in unsigned long func, in long ref, in unsigned long mask);
+ [StrictTypeChecking] void stencilFuncSeparate(in unsigned long face, in unsigned long func, in long ref, in unsigned long mask);
+ [StrictTypeChecking] void stencilMask(in unsigned long mask);
+ [StrictTypeChecking] void stencilMaskSeparate(in unsigned long face, in unsigned long mask);
+ [StrictTypeChecking] void stencilOp(in unsigned long fail, in unsigned long zfail, in unsigned long zpass);
+ [StrictTypeChecking] void stencilOpSeparate(in unsigned long face, in unsigned long fail, in unsigned long zfail, in unsigned long zpass);
+
+ [StrictTypeChecking] void texParameterf(in unsigned long target, in unsigned long pname, in float param);
+ [StrictTypeChecking] void texParameteri(in unsigned long target, in unsigned long pname, in long param);
+
+ // Supported forms:
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat, in long width, in long height,
+ in long border, in unsigned long format, in unsigned long type, in ArrayBufferView pixels) raises (DOMException);
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in unsigned long format, in unsigned long type, in ImageData pixels) raises (DOMException);
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in unsigned long format, in unsigned long type, in HTMLImageElement image) raises (DOMException);
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in unsigned long format, in unsigned long type, in HTMLCanvasElement canvas) raises (DOMException);
+ [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in unsigned long format, in unsigned long type, in HTMLVideoElement video) raises (DOMException);
+
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in long width, in long height,
+ in unsigned long format, in unsigned long type, in ArrayBufferView pixels) raises (DOMException);
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in unsigned long format, in unsigned long type, in ImageData pixels) raises (DOMException);
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in unsigned long format, in unsigned long type, in HTMLImageElement image) raises (DOMException);
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in unsigned long format, in unsigned long type, in HTMLCanvasElement canvas) raises (DOMException);
+ [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in unsigned long format, in unsigned long type, in HTMLVideoElement video) raises (DOMException);
+
+ [StrictTypeChecking] void uniform1f(in WebGLUniformLocation location, in float x) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform1fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform1i(in WebGLUniformLocation location, in long x) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform1iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform2f(in WebGLUniformLocation location, in float x, in float y) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform2fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform2i(in WebGLUniformLocation location, in long x, in long y) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform2iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform3f(in WebGLUniformLocation location, in float x, in float y, in float z) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform3fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform3i(in WebGLUniformLocation location, in long x, in long y, in long z) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform3iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform4f(in WebGLUniformLocation location, in float x, in float y, in float z, in float w) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform4fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException);
+ [StrictTypeChecking] void uniform4i(in WebGLUniformLocation location, in long x, in long y, in long z, in long w) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniform4iv(in WebGLUniformLocation location, in Int32Array v) raises(DOMException);
+
+ [StrictTypeChecking, Custom] void uniformMatrix2fv(in WebGLUniformLocation location, in boolean transpose, in Float32Array array) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniformMatrix3fv(in WebGLUniformLocation location, in boolean transpose, in Float32Array array) raises(DOMException);
+ [StrictTypeChecking, Custom] void uniformMatrix4fv(in WebGLUniformLocation location, in boolean transpose, in Float32Array array) raises(DOMException);
+
+ [StrictTypeChecking] void useProgram(in WebGLProgram program) raises(DOMException);
+ [StrictTypeChecking] void validateProgram(in WebGLProgram program) raises(DOMException);
+
+ [StrictTypeChecking] void vertexAttrib1f(in unsigned long indx, in float x);
+ [StrictTypeChecking, Custom] void vertexAttrib1fv(in unsigned long indx, in Float32Array values);
+ [StrictTypeChecking] void vertexAttrib2f(in unsigned long indx, in float x, in float y);
+ [StrictTypeChecking, Custom] void vertexAttrib2fv(in unsigned long indx, in Float32Array values);
+ [StrictTypeChecking] void vertexAttrib3f(in unsigned long indx, in float x, in float y, in float z);
+ [StrictTypeChecking, Custom] void vertexAttrib3fv(in unsigned long indx, in Float32Array values);
+ [StrictTypeChecking] void vertexAttrib4f(in unsigned long indx, in float x, in float y, in float z, in float w);
+ [StrictTypeChecking, Custom] void vertexAttrib4fv(in unsigned long indx, in Float32Array values);
+ [StrictTypeChecking] void vertexAttribPointer(in unsigned long indx, in long size, in unsigned long type, in boolean normalized,
+ in long stride, in long offset) raises(DOMException);
+
+ [StrictTypeChecking] void viewport(in long x, in long y, in long width, in long height);
+ };
+}
+
diff --git a/Source/WebCore/html/canvas/WebGLShader.cpp b/Source/WebCore/html/canvas/WebGLShader.cpp
new file mode 100644
index 0000000..4f8bf68
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLShader.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ * 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(3D_CANVAS)
+
+#include "WebGLShader.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContext* ctx, GraphicsContext3D::WebGLEnumType type)
+{
+ return adoptRef(new WebGLShader(ctx, type));
+}
+
+WebGLShader::WebGLShader(WebGLRenderingContext* ctx, GraphicsContext3D::WebGLEnumType type)
+ : WebGLObject(ctx)
+ , m_type(type)
+{
+ setObject(context()->graphicsContext3D()->createShader(type));
+}
+
+void WebGLShader::deleteObjectImpl(Platform3DObject object)
+{
+ context()->graphicsContext3D()->deleteShader(object);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebGLShader.h b/Source/WebCore/html/canvas/WebGLShader.h
new file mode 100644
index 0000000..c0c41df
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLShader.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ * 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 WebGLShader_h
+#define WebGLShader_h
+
+#include "WebGLObject.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLShader : public WebGLObject {
+public:
+ virtual ~WebGLShader() { deleteObject(); }
+
+ static PassRefPtr<WebGLShader> create(WebGLRenderingContext*, GraphicsContext3D::WebGLEnumType);
+
+ GraphicsContext3D::WebGLEnumType getType() const { return m_type; }
+
+private:
+ WebGLShader(WebGLRenderingContext*, GraphicsContext3D::WebGLEnumType);
+
+ virtual void deleteObjectImpl(Platform3DObject);
+
+ virtual bool isShader() const { return true; }
+
+ GraphicsContext3D::WebGLEnumType m_type;
+};
+
+} // namespace WebCore
+
+#endif // WebGLShader_h
diff --git a/Source/WebCore/html/canvas/WebGLShader.idl b/Source/WebCore/html/canvas/WebGLShader.idl
new file mode 100644
index 0000000..45e7f54
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLShader.idl
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ * 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.
+ */
+
+module html {
+ interface [Conditional=3D_CANVAS] WebGLShader {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLTexture.cpp b/Source/WebCore/html/canvas/WebGLTexture.cpp
new file mode 100644
index 0000000..2982e51
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLTexture.cpp
@@ -0,0 +1,355 @@
+/*
+ * 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.
+ * 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(3D_CANVAS)
+
+#include "WebGLTexture.h"
+
+#include "WebGLFramebuffer.h"
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContext* ctx)
+{
+ return adoptRef(new WebGLTexture(ctx));
+}
+
+WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
+ : WebGLObject(ctx)
+ , m_target(0)
+ , m_minFilter(GraphicsContext3D::NEAREST_MIPMAP_LINEAR)
+ , m_magFilter(GraphicsContext3D::LINEAR)
+ , m_wrapS(GraphicsContext3D::REPEAT)
+ , m_wrapT(GraphicsContext3D::REPEAT)
+ , m_isNPOT(false)
+ , m_isComplete(false)
+ , m_needToUseBlackTexture(false)
+{
+ setObject(context()->graphicsContext3D()->createTexture());
+}
+
+void WebGLTexture::setTarget(unsigned long target, int maxLevel)
+{
+ if (!object())
+ return;
+ // Target is finalized the first time bindTexture() is called.
+ if (m_target)
+ return;
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ m_target = target;
+ m_info.resize(1);
+ m_info[0].resize(maxLevel);
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP:
+ m_target = target;
+ m_info.resize(6);
+ for (int ii = 0; ii < 6; ++ii)
+ m_info[ii].resize(maxLevel);
+ break;
+ }
+}
+
+void WebGLTexture::setParameteri(unsigned long pname, int param)
+{
+ if (!object() || !m_target)
+ return;
+ switch (pname) {
+ case GraphicsContext3D::TEXTURE_MIN_FILTER:
+ switch (param) {
+ case GraphicsContext3D::NEAREST:
+ case GraphicsContext3D::LINEAR:
+ case GraphicsContext3D::NEAREST_MIPMAP_NEAREST:
+ case GraphicsContext3D::LINEAR_MIPMAP_NEAREST:
+ case GraphicsContext3D::NEAREST_MIPMAP_LINEAR:
+ case GraphicsContext3D::LINEAR_MIPMAP_LINEAR:
+ m_minFilter = param;
+ break;
+ }
+ break;
+ case GraphicsContext3D::TEXTURE_MAG_FILTER:
+ switch (param) {
+ case GraphicsContext3D::NEAREST:
+ case GraphicsContext3D::LINEAR:
+ m_magFilter = param;
+ break;
+ }
+ break;
+ case GraphicsContext3D::TEXTURE_WRAP_S:
+ switch (param) {
+ case GraphicsContext3D::CLAMP_TO_EDGE:
+ case GraphicsContext3D::MIRRORED_REPEAT:
+ case GraphicsContext3D::REPEAT:
+ m_wrapS = param;
+ break;
+ }
+ break;
+ case GraphicsContext3D::TEXTURE_WRAP_T:
+ switch (param) {
+ case GraphicsContext3D::CLAMP_TO_EDGE:
+ case GraphicsContext3D::MIRRORED_REPEAT:
+ case GraphicsContext3D::REPEAT:
+ m_wrapT = param;
+ break;
+ }
+ break;
+ default:
+ return;
+ }
+ update();
+}
+
+void WebGLTexture::setParameterf(unsigned long pname, float param)
+{
+ if (!object() || !m_target)
+ return;
+ int iparam = static_cast<int>(param);
+ setParameteri(pname, iparam);
+}
+
+void WebGLTexture::setLevelInfo(unsigned long target, int level, unsigned long internalFormat, int width, int height, unsigned long type)
+{
+ if (!object() || !m_target)
+ return;
+ // We assume level, internalFormat, width, height, and type have all been
+ // validated already.
+ int index = mapTargetToIndex(target);
+ if (index < 0)
+ return;
+ m_info[index][level].setInfo(internalFormat, width, height, type);
+ update();
+}
+
+void WebGLTexture::generateMipmapLevelInfo()
+{
+ if (!object() || !m_target)
+ return;
+ if (!canGenerateMipmaps())
+ return;
+ if (!m_isComplete) {
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ const LevelInfo& info0 = m_info[ii][0];
+ int width = info0.width;
+ int height = info0.height;
+ int levelCount = computeLevelCount(width, height);
+ for (int level = 1; level < levelCount; ++level) {
+ width = std::max(1, width >> 1);
+ height = std::max(1, height >> 1);
+ LevelInfo& info = m_info[ii][level];
+ info.setInfo(info0.internalFormat, width, height, info0.type);
+ }
+ }
+ m_isComplete = true;
+ }
+ m_needToUseBlackTexture = false;
+}
+
+unsigned long WebGLTexture::getInternalFormat(unsigned long target, int level) const
+{
+ const LevelInfo* info = getLevelInfo(target, level);
+ if (!info)
+ return 0;
+ return info->internalFormat;
+}
+
+unsigned long WebGLTexture::getType(unsigned long target, int level) const
+{
+ const LevelInfo* info = getLevelInfo(target, level);
+ if (!info)
+ return 0;
+ return info->type;
+}
+
+int WebGLTexture::getWidth(unsigned long target, int level) const
+{
+ const LevelInfo* info = getLevelInfo(target, level);
+ if (!info)
+ return 0;
+ return info->width;
+}
+
+int WebGLTexture::getHeight(unsigned long target, int level) const
+{
+ const LevelInfo* info = getLevelInfo(target, level);
+ if (!info)
+ return 0;
+ return info->height;
+}
+
+bool WebGLTexture::isNPOT(unsigned width, unsigned height)
+{
+ if (!width || !height)
+ return false;
+ if ((width & (width - 1)) || (height & (height - 1)))
+ return true;
+ return false;
+}
+
+bool WebGLTexture::isNPOT() const
+{
+ if (!object())
+ return false;
+ return m_isNPOT;
+}
+
+bool WebGLTexture::needToUseBlackTexture() const
+{
+ if (!object())
+ return false;
+ return m_needToUseBlackTexture;
+}
+
+void WebGLTexture::deleteObjectImpl(Platform3DObject object)
+{
+ context()->graphicsContext3D()->deleteTexture(object);
+}
+
+int WebGLTexture::mapTargetToIndex(unsigned long target) const
+{
+ if (m_target == GraphicsContext3D::TEXTURE_2D) {
+ if (target == GraphicsContext3D::TEXTURE_2D)
+ return 0;
+ } else if (m_target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
+ return 0;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
+ return 1;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
+ return 2;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ return 3;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
+ return 4;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ return 5;
+ }
+ }
+ return -1;
+}
+
+bool WebGLTexture::canGenerateMipmaps()
+{
+ if (isNPOT())
+ return false;
+ const LevelInfo& first = m_info[0][0];
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ const LevelInfo& info = m_info[ii][0];
+ if (!info.valid
+ || info.width != first.width || info.height != first.height
+ || info.internalFormat != first.internalFormat || info.type != first.type)
+ return false;
+ }
+ return true;
+}
+
+int WebGLTexture::computeLevelCount(int width, int height)
+{
+ // return 1 + log2Floor(std::max(width, height));
+ int n = std::max(width, height);
+ if (n <= 0)
+ return 0;
+ int log = 0;
+ int value = n;
+ for (int ii = 4; ii >= 0; --ii) {
+ int shift = (1 << ii);
+ int x = (value >> shift);
+ if (x) {
+ value = x;
+ log += shift;
+ }
+ }
+ ASSERT(value == 1);
+ return log + 1;
+}
+
+void WebGLTexture::update()
+{
+ m_isNPOT = false;
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ if (isNPOT(m_info[ii][0].width, m_info[ii][0].height)) {
+ m_isNPOT = true;
+ break;
+ }
+ }
+ m_isComplete = true;
+ const LevelInfo& first = m_info[0][0];
+ int levelCount = computeLevelCount(first.width, first.height);
+ if (levelCount < 1)
+ m_isComplete = false;
+ else {
+ for (size_t ii = 0; ii < m_info.size() && m_isComplete; ++ii) {
+ const LevelInfo& info0 = m_info[ii][0];
+ if (!info0.valid
+ || info0.width != first.width || info0.height != first.height
+ || info0.internalFormat != first.internalFormat || info0.type != first.type) {
+ m_isComplete = false;
+ break;
+ }
+ int width = info0.width;
+ int height = info0.height;
+ for (int level = 1; level < levelCount; ++level) {
+ width = std::max(1, width >> 1);
+ height = std::max(1, height >> 1);
+ const LevelInfo& info = m_info[ii][level];
+ if (!info.valid
+ || info.width != width || info.height != height
+ || info.internalFormat != info0.internalFormat || info.type != info0.type) {
+ m_isComplete = false;
+ break;
+ }
+
+ }
+ }
+ }
+
+ m_needToUseBlackTexture = false;
+ // NPOT
+ if (m_isNPOT && ((m_minFilter != GraphicsContext3D::NEAREST && m_minFilter != GraphicsContext3D::LINEAR)
+ || m_wrapS != GraphicsContext3D::CLAMP_TO_EDGE || m_wrapT != GraphicsContext3D::CLAMP_TO_EDGE))
+ m_needToUseBlackTexture = true;
+ // Completeness
+ if (!m_isComplete && m_minFilter != GraphicsContext3D::NEAREST && m_minFilter != GraphicsContext3D::LINEAR)
+ m_needToUseBlackTexture = true;
+}
+
+const WebGLTexture::LevelInfo* WebGLTexture::getLevelInfo(unsigned long target, int level) const
+{
+ if (!object() || !m_target)
+ return 0;
+ int targetIndex = mapTargetToIndex(target);
+ if (targetIndex < 0 || targetIndex >= static_cast<int>(m_info.size()))
+ return 0;
+ if (level < 0 || level >= static_cast<int>(m_info[targetIndex].size()))
+ return 0;
+ return &(m_info[targetIndex][level]);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebGLTexture.h b/Source/WebCore/html/canvas/WebGLTexture.h
new file mode 100644
index 0000000..419c94d
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLTexture.h
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ * 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 WebGLTexture_h
+#define WebGLTexture_h
+
+#include "WebGLObject.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class WebGLTexture : public WebGLObject {
+public:
+ virtual ~WebGLTexture() { deleteObject(); }
+
+ static PassRefPtr<WebGLTexture> create(WebGLRenderingContext*);
+
+ void setTarget(unsigned long target, int maxLevel);
+ void setParameteri(unsigned long pname, int param);
+ void setParameterf(unsigned long pname, float param);
+
+ int getMinFilter() const { return m_minFilter; }
+
+ void setLevelInfo(unsigned long target, int level, unsigned long internalFormat, int width, int height, unsigned long type);
+
+ bool canGenerateMipmaps();
+ // Generate all level information.
+ void generateMipmapLevelInfo();
+
+ unsigned long getInternalFormat(unsigned long target, int level) const;
+ unsigned long getType(unsigned long target, int level) const;
+ int getWidth(unsigned long target, int level) const;
+ int getHeight(unsigned long target, int level) const;
+
+ // Whether width/height is NotPowerOfTwo.
+ static bool isNPOT(unsigned, unsigned);
+
+ bool isNPOT() const;
+ // Determine if texture sampling should always return [0, 0, 0, 1] (OpenGL ES 2.0 Sec 3.8.2).
+ bool needToUseBlackTexture() const;
+
+ bool hasEverBeenBound() const { return object() && m_target; }
+
+ static int computeLevelCount(int width, int height);
+
+protected:
+ WebGLTexture(WebGLRenderingContext*);
+
+ virtual void deleteObjectImpl(Platform3DObject);
+
+private:
+ class LevelInfo {
+ public:
+ LevelInfo()
+ : valid(false)
+ , internalFormat(0)
+ , width(0)
+ , height(0)
+ , type(0)
+ {
+ }
+
+ void setInfo(unsigned long internalFmt, int w, int h, unsigned long tp)
+ {
+ valid = true;
+ internalFormat = internalFmt;
+ width = w;
+ height = h;
+ type = tp;
+ }
+
+ bool valid;
+ unsigned long internalFormat;
+ int width;
+ int height;
+ unsigned long type;
+ };
+
+ virtual bool isTexture() const { return true; }
+
+ void update();
+
+ int mapTargetToIndex(unsigned long) const;
+
+ const LevelInfo* getLevelInfo(unsigned long target, int level) const;
+
+ unsigned long m_target;
+
+ int m_minFilter;
+ int m_magFilter;
+ int m_wrapS;
+ int m_wrapT;
+
+ Vector<Vector<LevelInfo> > m_info;
+
+ bool m_isNPOT;
+ bool m_isComplete;
+ bool m_needToUseBlackTexture;
+};
+
+} // namespace WebCore
+
+#endif // WebGLTexture_h
diff --git a/Source/WebCore/html/canvas/WebGLTexture.idl b/Source/WebCore/html/canvas/WebGLTexture.idl
new file mode 100644
index 0000000..da7e066
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLTexture.idl
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ * 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.
+ */
+
+module html {
+ interface [Conditional=3D_CANVAS] WebGLTexture {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.cpp b/Source/WebCore/html/canvas/WebGLUniformLocation.cpp
new file mode 100644
index 0000000..e67b09a
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLUniformLocation.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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(3D_CANVAS)
+
+#include "WebGLUniformLocation.h"
+
+namespace WebCore {
+
+PassRefPtr<WebGLUniformLocation> WebGLUniformLocation::create(WebGLProgram* program, long location)
+{
+ return adoptRef(new WebGLUniformLocation(program, location));
+}
+
+WebGLUniformLocation::WebGLUniformLocation(WebGLProgram* program, long location)
+ : m_program(program)
+ , m_location(location)
+{
+ ASSERT(m_program);
+ m_linkCount = m_program->getLinkCount();
+}
+
+WebGLProgram* WebGLUniformLocation::program() const
+{
+ // If the program has been linked again, then this UniformLocation is no
+ // longer valid.
+ if (m_program->getLinkCount() != m_linkCount)
+ return 0;
+ return m_program.get();
+}
+
+long WebGLUniformLocation::location() const
+{
+ // If the program has been linked again, then this UniformLocation is no
+ // longer valid.
+ ASSERT(m_program->getLinkCount() == m_linkCount);
+ return m_location;
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.h b/Source/WebCore/html/canvas/WebGLUniformLocation.h
new file mode 100644
index 0000000..f8ce699
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLUniformLocation.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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 WebGLUniformLocation_h
+#define WebGLUniformLocation_h
+
+#include "WebGLObject.h"
+#include "WebGLProgram.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLUniformLocation : public RefCounted<WebGLUniformLocation> {
+public:
+ virtual ~WebGLUniformLocation() { }
+
+ static PassRefPtr<WebGLUniformLocation> create(WebGLProgram* program, long location);
+
+ WebGLProgram* program() const;
+
+ long location() const;
+
+protected:
+ WebGLUniformLocation(WebGLProgram* program, long location);
+
+private:
+ RefPtr<WebGLProgram> m_program;
+ long m_location;
+ unsigned long m_linkCount;
+};
+
+} // namespace WebCore
+
+#endif // WebGLUniformLocation_h
diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.idl b/Source/WebCore/html/canvas/WebGLUniformLocation.idl
new file mode 100644
index 0000000..b080241
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLUniformLocation.idl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ * 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.
+ */
+
+module html {
+ interface [Conditional=3D_CANVAS] WebGLUniformLocation {
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebKitLoseContext.cpp b/Source/WebCore/html/canvas/WebKitLoseContext.cpp
new file mode 100644
index 0000000..c7dd078
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebKitLoseContext.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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 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(3D_CANVAS)
+
+#include "WebKitLoseContext.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+WebKitLoseContext::WebKitLoseContext(WebGLRenderingContext* context)
+ : WebGLExtension()
+ , m_context(context)
+{
+}
+
+WebKitLoseContext::~WebKitLoseContext()
+{
+}
+
+WebGLExtension::ExtensionName WebKitLoseContext::getName() const
+{
+ return WebKitLoseContextName;
+}
+
+PassRefPtr<WebKitLoseContext> WebKitLoseContext::create(WebGLRenderingContext* context)
+{
+ return adoptRef(new WebKitLoseContext(context));
+}
+
+void WebKitLoseContext::loseContext()
+{
+ m_context->forceLostContext();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/Source/WebCore/html/canvas/WebKitLoseContext.h b/Source/WebCore/html/canvas/WebKitLoseContext.h
new file mode 100644
index 0000000..e25e084
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebKitLoseContext.h
@@ -0,0 +1,54 @@
+/*
+ * 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 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 WebKitLoseContext_h
+#define WebKitLoseContext_h
+
+#include "WebGLExtension.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class WebGLRenderingContext;
+
+class WebKitLoseContext : public WebGLExtension {
+public:
+ static PassRefPtr<WebKitLoseContext> create(WebGLRenderingContext*);
+
+ virtual ~WebKitLoseContext();
+ virtual ExtensionName getName() const;
+
+ void loseContext();
+
+private:
+ WebKitLoseContext(WebGLRenderingContext*);
+
+ WebGLRenderingContext* m_context;
+};
+
+} // namespace WebCore
+
+#endif // WebKitLoseContext_h
diff --git a/Source/WebCore/html/canvas/WebKitLoseContext.idl b/Source/WebCore/html/canvas/WebKitLoseContext.idl
new file mode 100644
index 0000000..741aa4a
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebKitLoseContext.idl
@@ -0,0 +1,30 @@
+/*
+ * 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 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.
+ */
+
+module html {
+ interface [Conditional=3D_CANVAS, OmitConstructor] WebKitLoseContext {
+ [StrictTypeChecking] void loseContext();
+ };
+}
diff --git a/Source/WebCore/html/parser/CSSPreloadScanner.cpp b/Source/WebCore/html/parser/CSSPreloadScanner.cpp
new file mode 100644
index 0000000..23364f9
--- /dev/null
+++ b/Source/WebCore/html/parser/CSSPreloadScanner.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc. http://www.torchmobile.com/
+ * 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 "CSSPreloadScanner.h"
+
+#include "CachedCSSStyleSheet.h"
+#include "CachedResourceLoader.h"
+#include "Document.h"
+#include "HTMLParserIdioms.h"
+#include "HTMLToken.h"
+
+namespace WebCore {
+
+CSSPreloadScanner::CSSPreloadScanner(Document* document)
+ : m_state(Initial)
+ , m_document(document)
+{
+}
+
+void CSSPreloadScanner::reset()
+{
+ m_state = Initial;
+ m_rule.clear();
+ m_ruleValue.clear();
+}
+
+void CSSPreloadScanner::scan(const HTMLToken& token, bool scanningBody)
+{
+ m_scanningBody = scanningBody;
+
+ const HTMLToken::DataVector& characters = token.characters();
+ for (HTMLToken::DataVector::const_iterator iter = characters.begin(); iter != characters.end(); ++iter)
+ tokenize(*iter);
+}
+
+inline void CSSPreloadScanner::tokenize(UChar c)
+{
+ // We are just interested in @import rules, no need for real tokenization here
+ // Searching for other types of resources is probably low payoff.
+ switch (m_state) {
+ case Initial:
+ if (c == '@')
+ m_state = RuleStart;
+ else if (c == '/')
+ m_state = MaybeComment;
+ break;
+ case MaybeComment:
+ if (c == '*')
+ m_state = Comment;
+ else
+ m_state = Initial;
+ break;
+ case Comment:
+ if (c == '*')
+ m_state = MaybeCommentEnd;
+ break;
+ case MaybeCommentEnd:
+ if (c == '/')
+ m_state = Initial;
+ else if (c == '*')
+ ;
+ else
+ m_state = Comment;
+ break;
+ case RuleStart:
+ if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
+ m_rule.clear();
+ m_ruleValue.clear();
+ m_rule.append(c);
+ m_state = Rule;
+ } else
+ m_state = Initial;
+ break;
+ case Rule:
+ if (isHTMLSpace(c))
+ m_state = AfterRule;
+ else if (c == ';')
+ m_state = Initial;
+ else
+ m_rule.append(c);
+ break;
+ case AfterRule:
+ if (isHTMLSpace(c))
+ ;
+ else if (c == ';')
+ m_state = Initial;
+ else {
+ m_state = RuleValue;
+ m_ruleValue.append(c);
+ }
+ break;
+ case RuleValue:
+ if (isHTMLSpace(c))
+ m_state = AfterRuleValue;
+ else if (c == ';') {
+ emitRule();
+ m_state = Initial;
+ } else
+ m_ruleValue.append(c);
+ break;
+ case AfterRuleValue:
+ if (isHTMLSpace(c))
+ ;
+ else if (c == ';') {
+ emitRule();
+ m_state = Initial;
+ } else {
+ // FIXME: media rules
+ m_state = Initial;
+ }
+ break;
+ }
+}
+
+static String parseCSSStringOrURL(const UChar* characters, size_t length)
+{
+ size_t offset = 0;
+ size_t reducedLength = length;
+
+ while (reducedLength && isHTMLSpace(characters[offset])) {
+ ++offset;
+ --reducedLength;
+ }
+ while (reducedLength && isHTMLSpace(characters[offset + reducedLength - 1]))
+ --reducedLength;
+
+ if (reducedLength >= 5
+ && (characters[offset] == 'u' || characters[offset] == 'U')
+ && (characters[offset + 1] == 'r' || characters[offset + 1] == 'R')
+ && (characters[offset + 2] == 'l' || characters[offset + 2] == 'L')
+ && characters[offset + 3] == '('
+ && characters[offset + reducedLength - 1] == ')') {
+ offset += 4;
+ reducedLength -= 5;
+ }
+
+ while (reducedLength && isHTMLSpace(characters[offset])) {
+ ++offset;
+ --reducedLength;
+ }
+ while (reducedLength && isHTMLSpace(characters[offset + reducedLength - 1]))
+ --reducedLength;
+
+ if (reducedLength < 2 || characters[offset] != characters[offset + reducedLength - 1] || !(characters[offset] == '\'' || characters[offset] == '"'))
+ return String();
+ offset++;
+ reducedLength -= 2;
+
+ while (reducedLength && isHTMLSpace(characters[offset])) {
+ ++offset;
+ --reducedLength;
+ }
+ while (reducedLength && isHTMLSpace(characters[offset + reducedLength - 1]))
+ --reducedLength;
+
+ return String(characters + offset, reducedLength);
+}
+
+void CSSPreloadScanner::emitRule()
+{
+ if (equalIgnoringCase("import", m_rule.data(), m_rule.size())) {
+ String value = parseCSSStringOrURL(m_ruleValue.data(), m_ruleValue.size());
+ if (!value.isEmpty())
+ m_document->cachedResourceLoader()->preload(CachedResource::CSSStyleSheet, value, String(), m_scanningBody);
+ }
+ m_rule.clear();
+ m_ruleValue.clear();
+}
+
+}
diff --git a/Source/WebCore/html/parser/CSSPreloadScanner.h b/Source/WebCore/html/parser/CSSPreloadScanner.h
new file mode 100644
index 0000000..7ac282f
--- /dev/null
+++ b/Source/WebCore/html/parser/CSSPreloadScanner.h
@@ -0,0 +1,71 @@
+/*
+ * 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
+ * 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 CSSPreloadScanner_h
+#define CSSPreloadScanner_h
+
+#include "PlatformString.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Document;
+class HTMLToken;
+
+class CSSPreloadScanner : public Noncopyable {
+public:
+ CSSPreloadScanner(Document*);
+
+ void reset();
+ void scan(const HTMLToken&, bool scanningBody);
+
+private:
+ enum State {
+ Initial,
+ MaybeComment,
+ Comment,
+ MaybeCommentEnd,
+ RuleStart,
+ Rule,
+ AfterRule,
+ RuleValue,
+ AfterRuleValue
+ };
+
+ inline void tokenize(UChar c);
+ void emitRule();
+
+ State m_state;
+ Vector<UChar, 16> m_rule;
+ Vector<UChar> m_ruleValue;
+
+ bool m_scanningBody;
+ Document* m_document;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLConstructionSite.cpp b/Source/WebCore/html/parser/HTMLConstructionSite.cpp
new file mode 100644
index 0000000..c46b9b9
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLConstructionSite.cpp
@@ -0,0 +1,464 @@
+/*
+ * 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 GOOGLE 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 GOOGLE 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 "HTMLTreeBuilder.h"
+
+#include "Comment.h"
+#include "DocumentFragment.h"
+#include "DocumentType.h"
+#include "Element.h"
+#include "Frame.h"
+#include "HTMLDocument.h"
+#include "HTMLElementFactory.h"
+#include "HTMLFormElement.h"
+#include "HTMLHtmlElement.h"
+#include "HTMLNames.h"
+#include "HTMLScriptElement.h"
+#include "HTMLToken.h"
+#include "HTMLTokenizer.h"
+#include "LocalizedStrings.h"
+#if ENABLE(MATHML)
+#include "MathMLNames.h"
+#endif
+#include "NotImplemented.h"
+#if ENABLE(SVG)
+#include "SVGNames.h"
+#endif
+#include "ScriptController.h"
+#include "Settings.h"
+#include "Text.h"
+#include <wtf/UnusedParam.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+namespace {
+
+bool hasImpliedEndTag(Element* element)
+{
+ return element->hasTagName(ddTag)
+ || element->hasTagName(dtTag)
+ || element->hasTagName(liTag)
+ || element->hasTagName(optionTag)
+ || element->hasTagName(optgroupTag)
+ || element->hasTagName(pTag)
+ || element->hasTagName(rpTag)
+ || element->hasTagName(rtTag);
+}
+
+bool causesFosterParenting(const QualifiedName& tagName)
+{
+ return tagName == tableTag
+ || tagName == tbodyTag
+ || tagName == tfootTag
+ || tagName == theadTag
+ || tagName == trTag;
+}
+
+} // namespace
+
+template<typename ChildType>
+PassRefPtr<ChildType> HTMLConstructionSite::attach(ContainerNode* parent, PassRefPtr<ChildType> prpChild)
+{
+ RefPtr<ChildType> child = prpChild;
+
+ // FIXME: It's confusing that HTMLConstructionSite::attach does the magic
+ // redirection to the foster parent but HTMLConstructionSite::attachAtSite
+ // doesn't. It feels like we're missing a concept somehow.
+ if (shouldFosterParent()) {
+ fosterParent(child.get());
+ ASSERT(child->attached() || !child->parentNode() || !child->parentNode()->attached());
+ return child.release();
+ }
+
+ parent->parserAddChild(child);
+
+ // An event handler (DOM Mutation, beforeload, et al.) could have removed
+ // the child, in which case we shouldn't try attaching it.
+ if (!child->parentNode())
+ return child.release();
+
+ // It's slightly unfortunate that we need to hold a reference to child
+ // here to call attach(). We should investigate whether we can rely on
+ // |parent| to hold a ref at this point. In the common case (at least
+ // for elements), however, we'll get to use this ref in the stack of
+ // open elements.
+ if (parent->attached() && !child->attached())
+ child->attach();
+ return child.release();
+}
+
+void HTMLConstructionSite::attachAtSite(const AttachmentSite& site, PassRefPtr<Node> prpChild)
+{
+ // FIXME: It's unfortunate that we need to hold a reference to child
+ // here to call attach(). We should investigate whether we can rely on
+ // |site.parent| to hold a ref at this point.
+ RefPtr<Node> child = prpChild;
+
+ if (site.nextChild)
+ site.parent->parserInsertBefore(child, site.nextChild);
+ else
+ site.parent->parserAddChild(child);
+
+ // JavaScript run from beforeload (or DOM Mutation or event handlers)
+ // might have removed the child, in which case we should not attach it.
+ if (child->parentNode() && site.parent->attached() && !child->attached())
+ child->attach();
+}
+
+HTMLConstructionSite::HTMLConstructionSite(Document* document, FragmentScriptingPermission scriptingPermission, bool isParsingFragment)
+ : m_document(document)
+ , m_fragmentScriptingPermission(scriptingPermission)
+ , m_isParsingFragment(isParsingFragment)
+ , m_redirectAttachToFosterParent(false)
+{
+}
+
+HTMLConstructionSite::~HTMLConstructionSite()
+{
+}
+
+void HTMLConstructionSite::detach()
+{
+ m_document = 0;
+}
+
+void HTMLConstructionSite::setForm(HTMLFormElement* form)
+{
+ // This method should only be needed for HTMLTreeBuilder in the fragment case.
+ ASSERT(!m_form);
+ m_form = form;
+}
+
+PassRefPtr<HTMLFormElement> HTMLConstructionSite::takeForm()
+{
+ return m_form.release();
+}
+
+void HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded()
+{
+ ASSERT(m_document);
+ if (m_document->frame() && !m_isParsingFragment)
+ m_document->frame()->loader()->dispatchDocumentElementAvailable();
+}
+
+void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken& token)
+{
+ RefPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(m_document);
+ element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
+ m_openElements.pushHTMLHtmlElement(attach<Element>(m_document, element.get()));
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ element->insertedByParser();
+#endif
+ dispatchDocumentElementAvailableIfNeeded();
+}
+
+void HTMLConstructionSite::mergeAttributesFromTokenIntoElement(AtomicHTMLToken& token, Element* element)
+{
+ if (!token.attributes())
+ return;
+
+ NamedNodeMap* attributes = element->attributes(false);
+ for (unsigned i = 0; i < token.attributes()->length(); ++i) {
+ Attribute* attribute = token.attributes()->attributeItem(i);
+ if (!attributes->getAttributeItem(attribute->name()))
+ element->setAttribute(attribute->name(), attribute->value());
+ }
+}
+
+void HTMLConstructionSite::insertHTMLHtmlStartTagInBody(AtomicHTMLToken& token)
+{
+ // FIXME: parse error
+ mergeAttributesFromTokenIntoElement(token, m_openElements.htmlElement());
+}
+
+void HTMLConstructionSite::insertHTMLBodyStartTagInBody(AtomicHTMLToken& token)
+{
+ // FIXME: parse error
+ mergeAttributesFromTokenIntoElement(token, m_openElements.bodyElement());
+}
+
+void HTMLConstructionSite::insertDoctype(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::DOCTYPE);
+ attach(m_document, DocumentType::create(m_document, token.name(), String::adopt(token.publicIdentifier()), String::adopt(token.systemIdentifier())));
+
+ if (token.forceQuirks())
+ m_document->setCompatibilityMode(Document::QuirksMode);
+ else
+ m_document->setCompatibilityModeFromDoctype();
+}
+
+void HTMLConstructionSite::insertComment(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::Comment);
+ attach(currentElement(), Comment::create(currentElement()->document(), token.comment()));
+}
+
+void HTMLConstructionSite::insertCommentOnDocument(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::Comment);
+ attach(m_document, Comment::create(m_document, token.comment()));
+}
+
+void HTMLConstructionSite::insertCommentOnHTMLHtmlElement(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::Comment);
+ Element* parent = m_openElements.htmlElement();
+ attach(parent, Comment::create(parent->document(), token.comment()));
+}
+
+PassRefPtr<Element> HTMLConstructionSite::attachToCurrent(PassRefPtr<Element> child)
+{
+ return attach(currentElement(), child);
+}
+
+void HTMLConstructionSite::insertHTMLHeadElement(AtomicHTMLToken& token)
+{
+ ASSERT(!shouldFosterParent());
+ m_head = attachToCurrent(createHTMLElement(token));
+ m_openElements.pushHTMLHeadElement(m_head);
+}
+
+void HTMLConstructionSite::insertHTMLBodyElement(AtomicHTMLToken& token)
+{
+ ASSERT(!shouldFosterParent());
+ m_openElements.pushHTMLBodyElement(attachToCurrent(createHTMLElement(token)));
+}
+
+void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken& token, bool isDemoted)
+{
+ RefPtr<Element> element = createHTMLElement(token);
+ ASSERT(element->hasTagName(formTag));
+ RefPtr<HTMLFormElement> form = static_pointer_cast<HTMLFormElement>(element.release());
+ form->setDemoted(isDemoted);
+ m_openElements.push(attachToCurrent(form.release()));
+ ASSERT(currentElement()->isHTMLElement());
+ ASSERT(currentElement()->hasTagName(formTag));
+ m_form = static_cast<HTMLFormElement*>(currentElement());
+}
+
+void HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken& token)
+{
+ m_openElements.push(attachToCurrent(createHTMLElement(token)));
+}
+
+void HTMLConstructionSite::insertSelfClosingHTMLElement(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::StartTag);
+ RefPtr<Element> element = attachToCurrent(createHTMLElement(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.
+ element->finishParsingChildren();
+ // 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
+}
+
+void HTMLConstructionSite::insertFormattingElement(AtomicHTMLToken& token)
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#the-stack-of-open-elements
+ // 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(currentElement());
+}
+
+void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken& token)
+{
+ RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(scriptTag, currentElement()->document(), true);
+ if (m_fragmentScriptingPermission == FragmentScriptingAllowed)
+ element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
+ m_openElements.push(attachToCurrent(element.release()));
+}
+
+void HTMLConstructionSite::insertForeignElement(AtomicHTMLToken& token, const AtomicString& namespaceURI)
+{
+ ASSERT(token.type() == HTMLToken::StartTag);
+ notImplemented(); // parseError when xmlns or xmlns:xlink are wrong.
+
+ RefPtr<Element> element = attachToCurrent(createElement(token, namespaceURI));
+ if (!token.selfClosing())
+ m_openElements.push(element);
+}
+
+void HTMLConstructionSite::insertTextNode(const String& characters)
+{
+ AttachmentSite site;
+ site.parent = currentElement();
+ site.nextChild = 0;
+ if (shouldFosterParent())
+ findFosterSite(site);
+
+ Node* previousChild = site.nextChild ? site.nextChild->previousSibling() : site.parent->lastChild();
+ 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.
+ CharacterData* textNode = static_cast<CharacterData*>(previousChild);
+ textNode->parserAppendData(characters);
+ return;
+ }
+
+ attachAtSite(site, Text::create(site.parent->document(), characters));
+}
+
+PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken& token, const AtomicString& namespaceURI)
+{
+ QualifiedName tagName(nullAtom, token.name(), namespaceURI);
+ RefPtr<Element> element = currentElement()->document()->createElement(tagName, true);
+ element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
+ return element.release();
+}
+
+PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken& token)
+{
+ QualifiedName tagName(nullAtom, token.name(), xhtmlNamespaceURI);
+ // FIXME: This can't use HTMLConstructionSite::createElement because we
+ // have to pass the current form element. We should rework form association
+ // to occur after construction to allow better code sharing here.
+ RefPtr<Element> element = HTMLElementFactory::createHTMLElement(tagName, currentElement()->document(), form(), true);
+ element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
+ ASSERT(element->isHTMLElement());
+ return element.release();
+}
+
+PassRefPtr<Element> HTMLConstructionSite::createHTMLElementFromElementRecord(HTMLElementStack::ElementRecord* record)
+{
+ return createHTMLElementFromSavedElement(record->element());
+}
+
+namespace {
+
+PassRefPtr<NamedNodeMap> cloneAttributes(Element* element)
+{
+ NamedNodeMap* attributes = element->attributes(true);
+ if (!attributes)
+ return 0;
+
+ RefPtr<NamedNodeMap> newAttributes = NamedNodeMap::create();
+ for (size_t i = 0; i < attributes->length(); ++i) {
+ Attribute* attribute = attributes->attributeItem(i);
+ RefPtr<Attribute> clone = Attribute::createMapped(attribute->name(), attribute->value());
+ newAttributes->addAttribute(clone);
+ }
+ return newAttributes.release();
+}
+
+}
+
+PassRefPtr<Element> HTMLConstructionSite::createHTMLElementFromSavedElement(Element* element)
+{
+ // FIXME: This method is wrong. We should be using the original token.
+ // Using an Element* causes us to fail examples like this:
+ // <b id="1"><p><script>document.getElementById("1").id = "2"</script></p>TEXT</b>
+ // When reconstructTheActiveFormattingElements calls this method to open
+ // a second <b> tag to wrap TEXT, it will have id "2", even though the HTML5
+ // spec implies it should be "1". Minefield matches the HTML5 spec here.
+
+ ASSERT(element->isHTMLElement()); // otherwise localName() might be wrong.
+ AtomicHTMLToken fakeToken(HTMLToken::StartTag, element->localName(), cloneAttributes(element));
+ return createHTMLElement(fakeToken);
+}
+
+bool HTMLConstructionSite::indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const
+{
+ if (m_activeFormattingElements.isEmpty())
+ return false;
+ unsigned index = m_activeFormattingElements.size();
+ do {
+ --index;
+ const HTMLFormattingElementList::Entry& entry = m_activeFormattingElements.at(index);
+ if (entry.isMarker() || m_openElements.contains(entry.element())) {
+ firstUnopenElementIndex = index + 1;
+ return firstUnopenElementIndex < m_activeFormattingElements.size();
+ }
+ } while (index);
+ firstUnopenElementIndex = index;
+ return true;
+}
+
+void HTMLConstructionSite::reconstructTheActiveFormattingElements()
+{
+ unsigned firstUnopenElementIndex;
+ if (!indexOfFirstUnopenFormattingElement(firstUnopenElementIndex))
+ return;
+
+ unsigned unopenEntryIndex = firstUnopenElementIndex;
+ ASSERT(unopenEntryIndex < m_activeFormattingElements.size());
+ for (; unopenEntryIndex < m_activeFormattingElements.size(); ++unopenEntryIndex) {
+ HTMLFormattingElementList::Entry& unopenedEntry = m_activeFormattingElements.at(unopenEntryIndex);
+ RefPtr<Element> reconstructed = createHTMLElementFromSavedElement(unopenedEntry.element());
+ m_openElements.push(attachToCurrent(reconstructed.release()));
+ unopenedEntry.replaceElement(currentElement());
+ }
+}
+
+void HTMLConstructionSite::generateImpliedEndTagsWithExclusion(const AtomicString& tagName)
+{
+ while (hasImpliedEndTag(currentElement()) && !currentElement()->hasLocalName(tagName))
+ m_openElements.pop();
+}
+
+void HTMLConstructionSite::generateImpliedEndTags()
+{
+ while (hasImpliedEndTag(currentElement()))
+ m_openElements.pop();
+}
+
+void HTMLConstructionSite::findFosterSite(AttachmentSite& site)
+{
+ HTMLElementStack::ElementRecord* lastTableElementRecord = m_openElements.topmost(tableTag.localName());
+ if (lastTableElementRecord) {
+ Element* lastTableElement = lastTableElementRecord->element();
+ if (ContainerNode* parent = lastTableElement->parentNode()) {
+ site.parent = parent;
+ site.nextChild = lastTableElement;
+ return;
+ }
+ site.parent = lastTableElementRecord->next()->element();
+ site.nextChild = 0;
+ return;
+ }
+ // Fragment case
+ site.parent = m_openElements.bottom(); // <html> element
+ site.nextChild = 0;
+}
+
+bool HTMLConstructionSite::shouldFosterParent() const
+{
+ return m_redirectAttachToFosterParent
+ && causesFosterParenting(currentElement()->tagQName());
+}
+
+void HTMLConstructionSite::fosterParent(Node* node)
+{
+ AttachmentSite site;
+ findFosterSite(site);
+ attachAtSite(site, node);
+}
+
+}
diff --git a/Source/WebCore/html/parser/HTMLConstructionSite.h b/Source/WebCore/html/parser/HTMLConstructionSite.h
new file mode 100644
index 0000000..8b09bf5
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLConstructionSite.h
@@ -0,0 +1,148 @@
+/*
+ * 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 GOOGLE 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 GOOGLE 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 HTMLConstructionSite_h
+#define HTMLConstructionSite_h
+
+#include "FragmentScriptingPermission.h"
+#include "HTMLElementStack.h"
+#include "HTMLFormattingElementList.h"
+#include "NotImplemented.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class AtomicHTMLToken;
+class Document;
+class Element;
+
+class HTMLConstructionSite : public Noncopyable {
+public:
+ HTMLConstructionSite(Document*, FragmentScriptingPermission, bool isParsingFragment);
+ ~HTMLConstructionSite();
+
+ void detach();
+
+ void insertDoctype(AtomicHTMLToken&);
+ void insertComment(AtomicHTMLToken&);
+ void insertCommentOnDocument(AtomicHTMLToken&);
+ void insertCommentOnHTMLHtmlElement(AtomicHTMLToken&);
+ void insertHTMLElement(AtomicHTMLToken&);
+ void insertSelfClosingHTMLElement(AtomicHTMLToken&);
+ void insertFormattingElement(AtomicHTMLToken&);
+ void insertHTMLHeadElement(AtomicHTMLToken&);
+ void insertHTMLBodyElement(AtomicHTMLToken&);
+ void insertHTMLFormElement(AtomicHTMLToken&, bool isDemoted = false);
+ void insertScriptElement(AtomicHTMLToken&);
+ void insertTextNode(const String&);
+ void insertForeignElement(AtomicHTMLToken&, const AtomicString& namespaceURI);
+
+ void insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken&);
+ void insertHTMLHtmlStartTagInBody(AtomicHTMLToken&);
+ void insertHTMLBodyStartTagInBody(AtomicHTMLToken&);
+
+ PassRefPtr<Element> createHTMLElement(AtomicHTMLToken&);
+ PassRefPtr<Element> createHTMLElementFromElementRecord(HTMLElementStack::ElementRecord*);
+
+ bool shouldFosterParent() const;
+ void fosterParent(Node*);
+
+ bool indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const;
+ void reconstructTheActiveFormattingElements();
+
+ void generateImpliedEndTags();
+ void generateImpliedEndTagsWithExclusion(const AtomicString& tagName);
+
+ Element* currentElement() const { return m_openElements.top(); }
+ Element* oneBelowTop() const { return m_openElements.oneBelowTop(); }
+
+ HTMLElementStack* openElements() const { return &m_openElements; }
+ HTMLFormattingElementList* activeFormattingElements() const { return &m_activeFormattingElements; }
+
+ Element* head() const { return m_head.get(); }
+
+ void setForm(HTMLFormElement*);
+ HTMLFormElement* form() const { return m_form.get(); }
+ PassRefPtr<HTMLFormElement> takeForm();
+
+ class RedirectToFosterParentGuard : public Noncopyable {
+ public:
+ RedirectToFosterParentGuard(HTMLConstructionSite& tree)
+ : m_tree(tree)
+ , m_wasRedirectingBefore(tree.m_redirectAttachToFosterParent)
+ {
+ m_tree.m_redirectAttachToFosterParent = true;
+ }
+
+ ~RedirectToFosterParentGuard()
+ {
+ m_tree.m_redirectAttachToFosterParent = m_wasRedirectingBefore;
+ }
+
+ private:
+ HTMLConstructionSite& m_tree;
+ bool m_wasRedirectingBefore;
+ };
+
+private:
+ struct AttachmentSite {
+ ContainerNode* parent;
+ Node* nextChild;
+ };
+
+ template<typename ChildType>
+ PassRefPtr<ChildType> attach(ContainerNode* parent, PassRefPtr<ChildType> child);
+ PassRefPtr<Element> attachToCurrent(PassRefPtr<Element>);
+
+ void attachAtSite(const AttachmentSite&, PassRefPtr<Node> child);
+ void findFosterSite(AttachmentSite&);
+
+ PassRefPtr<Element> createHTMLElementFromSavedElement(Element*);
+ PassRefPtr<Element> createElement(AtomicHTMLToken&, const AtomicString& namespaceURI);
+
+ void mergeAttributesFromTokenIntoElement(AtomicHTMLToken&, Element*);
+ void dispatchDocumentElementAvailableIfNeeded();
+
+ Document* m_document;
+ RefPtr<Element> m_head;
+ RefPtr<HTMLFormElement> m_form;
+ mutable HTMLElementStack m_openElements;
+ mutable HTMLFormattingElementList m_activeFormattingElements;
+
+ FragmentScriptingPermission m_fragmentScriptingPermission;
+ bool m_isParsingFragment;
+
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-intable
+ // In the "in table" insertion mode, we sometimes get into a state where
+ // "whenever a node would be inserted into the current node, it must instead
+ // be foster parented." This flag tracks whether we're in that state.
+ bool m_redirectAttachToFosterParent;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.cpp b/Source/WebCore/html/parser/HTMLDocumentParser.cpp
new file mode 100644
index 0000000..93e1309
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLDocumentParser.cpp
@@ -0,0 +1,549 @@
+/*
+ * 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 "HTMLDocumentParser.h"
+
+#include "DocumentFragment.h"
+#include "Element.h"
+#include "Frame.h"
+#include "HTMLNames.h"
+#include "HTMLParserScheduler.h"
+#include "HTMLTokenizer.h"
+#include "HTMLPreloadScanner.h"
+#include "HTMLScriptRunner.h"
+#include "HTMLTreeBuilder.h"
+#include "HTMLDocument.h"
+#include "InspectorInstrumentation.h"
+#include "NestingLevelIncrementer.h"
+#include "Settings.h"
+#include "XSSAuditor.h"
+#include <wtf/CurrentTime.h>
+
+#ifdef ANDROID_INSTRUMENT
+#include "TimeCounter.h"
+#endif
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+namespace {
+
+// This is a direct transcription of step 4 from:
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
+HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElement, bool reportErrors)
+{
+ 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) && HTMLTreeBuilder::pluginsEnabled(contextElement->document()->frame()))
+ || (contextTag.matches(noscriptTag) && HTMLTreeBuilder::scriptEnabled(contextElement->document()->frame()))
+ || 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;
+}
+
+} // namespace
+
+HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors)
+ : ScriptableDocumentParser(document)
+ , m_tokenizer(HTMLTokenizer::create(usePreHTML5ParserQuirks(document)))
+ , m_scriptRunner(HTMLScriptRunner::create(document, this))
+ , m_treeBuilder(HTMLTreeBuilder::create(this, document, reportErrors, usePreHTML5ParserQuirks(document)))
+ , m_parserScheduler(HTMLParserScheduler::create(this))
+ , m_endWasDelayed(false)
+ , m_writeNestingLevel(0)
+{
+}
+
+// FIXME: Member variables should be grouped into self-initializing structs to
+// minimize code duplication between these constructors.
+HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
+ : ScriptableDocumentParser(fragment->document())
+ , m_tokenizer(HTMLTokenizer::create(usePreHTML5ParserQuirks(fragment->document())))
+ , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, scriptingPermission, usePreHTML5ParserQuirks(fragment->document())))
+ , m_endWasDelayed(false)
+ , m_writeNestingLevel(0)
+{
+ bool reportErrors = false; // For now document fragment parsing never reports errors.
+ m_tokenizer->setState(tokenizerStateForContextElement(contextElement, reportErrors));
+}
+
+HTMLDocumentParser::~HTMLDocumentParser()
+{
+ ASSERT(!m_parserScheduler);
+ ASSERT(!m_writeNestingLevel);
+ ASSERT(!m_preloadScanner);
+}
+
+void HTMLDocumentParser::detach()
+{
+ DocumentParser::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.clear();
+ m_parserScheduler.clear(); // Deleting the scheduler will clear any timers.
+}
+
+void HTMLDocumentParser::stopParsing()
+{
+ DocumentParser::stopParsing();
+ m_parserScheduler.clear(); // Deleting the scheduler will clear any timers.
+}
+
+// This kicks off "Once the user agent stops parsing" as described by:
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end
+void HTMLDocumentParser::prepareToStopParsing()
+{
+ ASSERT(!hasInsertionPoint());
+
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+
+ // NOTE: This pump should only ever emit buffered character tokens,
+ // so ForceSynchronous vs. AllowYield should be meaningless.
+ pumpTokenizerIfPossible(ForceSynchronous);
+
+ if (isStopped())
+ return;
+
+ DocumentParser::prepareToStopParsing();
+
+ // We will not have a scriptRunner when parsing a DocumentFragment.
+ if (m_scriptRunner)
+ document()->setReadyState(Document::Interactive);
+
+ attemptToRunDeferredScriptsAndEnd();
+}
+
+bool HTMLDocumentParser::processingData() const
+{
+ return isScheduledForResume() || inWrite();
+}
+
+void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode)
+{
+ if (isStopped() || m_treeBuilder->isPaused())
+ return;
+
+ // Once a resume is scheduled, HTMLParserScheduler controls when we next pump.
+ if (isScheduledForResume()) {
+ ASSERT(mode == AllowYield);
+ return;
+ }
+
+ pumpTokenizer(mode);
+}
+
+bool HTMLDocumentParser::isScheduledForResume() const
+{
+ return m_parserScheduler && m_parserScheduler->isScheduledForResume();
+}
+
+// Used by HTMLParserScheduler
+void HTMLDocumentParser::resumeParsingAfterYield()
+{
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<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.
+ pumpTokenizer(AllowYield);
+ endIfDelayed();
+}
+
+bool HTMLDocumentParser::runScriptsForPausedTreeBuilder()
+{
+ ASSERT(m_treeBuilder->isPaused());
+
+ TextPosition1 scriptStartPosition = TextPosition1::belowRangePosition();
+ RefPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptStartPosition);
+ // We will not have a scriptRunner when parsing a DocumentFragment.
+ if (!m_scriptRunner)
+ return true;
+ return m_scriptRunner->execute(scriptElement.release(), scriptStartPosition);
+}
+
+void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
+{
+ ASSERT(!isStopped());
+ ASSERT(!m_treeBuilder->isPaused());
+ ASSERT(!isScheduledForResume());
+ // ASSERT that this object is both attached to the Document and protected.
+ ASSERT(refCount() >= 2);
+
+ // We tell the InspectorInstrumentation about every pump, even if we
+ // end up pumping nothing. It can filter out empty pumps itself.
+ // 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.
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteHTML(document(), m_input.current().length(), m_tokenizer->lineNumber());
+
+ HTMLParserScheduler::PumpSession session;
+ // FIXME: This loop body has is now too long and needs cleanup.
+ while (mode == ForceSynchronous || m_parserScheduler->shouldContinueParsing(session)) {
+ // 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 (!m_treeBuilder->isParsingFragment()
+ && document()->frame() && document()->frame()->navigationScheduler()->locationChangePending())
+ break;
+ if (!m_tokenizer->nextToken(m_input.current(), m_token))
+ break;
+
+ m_treeBuilder->constructTreeFromToken(m_token);
+ m_token.clear();
+
+ // JavaScript may have stopped or detached the parser.
+ if (isStopped())
+ return;
+
+ // The parser will pause itself when waiting on a script to load or run.
+ if (!m_treeBuilder->isPaused())
+ continue;
+
+ // If we're paused waiting for a script, we try to execute scripts before continuing.
+ bool shouldContinueParsing = runScriptsForPausedTreeBuilder();
+ m_treeBuilder->setPaused(!shouldContinueParsing);
+
+ // JavaScript may have stopped or detached the parser.
+ if (isStopped())
+ return;
+
+ if (!shouldContinueParsing)
+ break;
+ }
+
+ // Ensure we haven't been totally deref'ed after pumping. Any caller of this
+ // function should be holding a RefPtr to this to ensure we weren't deleted.
+ ASSERT(refCount() >= 1);
+
+ if (isWaitingForScripts()) {
+ ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState);
+ if (!m_preloadScanner) {
+ m_preloadScanner.set(new HTMLPreloadScanner(document()));
+ m_preloadScanner->appendToEnd(m_input.current());
+ }
+ m_preloadScanner->scan();
+ }
+
+ InspectorInstrumentation::didWriteHTML(cookie, m_tokenizer->lineNumber());
+}
+
+bool HTMLDocumentParser::hasInsertionPoint()
+{
+ return m_input.hasInsertionPoint();
+}
+
+void HTMLDocumentParser::insert(const SegmentedString& source)
+{
+ if (isStopped())
+ return;
+
+#ifdef ANDROID_INSTRUMENT
+ android::TimeCounter::start(android::TimeCounter::ParsingTimeCounter);
+#endif
+
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+
+ {
+ NestingLevelIncrementer nestingLevelIncrementer(m_writeNestingLevel);
+
+ SegmentedString excludedLineNumberSource(source);
+ excludedLineNumberSource.setExcludeLineNumbers();
+ m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource);
+ pumpTokenizerIfPossible(ForceSynchronous);
+ }
+
+ endIfDelayed();
+}
+
+void HTMLDocumentParser::append(const SegmentedString& source)
+{
+ if (isStopped())
+ return;
+
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+
+ {
+ NestingLevelIncrementer nestingLevelIncrementer(m_writeNestingLevel);
+
+ m_input.appendToEnd(source);
+ if (m_preloadScanner)
+ m_preloadScanner->appendToEnd(source);
+
+ if (m_writeNestingLevel > 1) {
+ // We've gotten data off the network in a nested write.
+ // We don't want to consume any more of the input stream now. Do
+ // not worry. We'll consume this data in a less-nested write().
+#ifdef ANDROID_INSTRUMENT
+ android::TimeCounter::record(android::TimeCounter::ParsingTimeCounter, __FUNCTION__);
+#endif
+ return;
+ }
+
+ pumpTokenizerIfPossible(AllowYield);
+ }
+
+ endIfDelayed();
+#ifdef ANDROID_INSTRUMENT
+ android::TimeCounter::record(android::TimeCounter::ParsingTimeCounter, __FUNCTION__);
+#endif
+}
+
+void HTMLDocumentParser::end()
+{
+ ASSERT(!isDetached());
+ ASSERT(!isScheduledForResume());
+
+ // Informs the the rest of WebCore that parsing is really finished (and deletes this).
+ m_treeBuilder->finished();
+}
+
+void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd()
+{
+ ASSERT(isStopping());
+ ASSERT(!hasInsertionPoint());
+ if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing())
+ return;
+ end();
+}
+
+void HTMLDocumentParser::attemptToEnd()
+{
+ // finish() indicates we will not receive any more data. If we are waiting on
+ // an external script to load, we can't finish parsing quite yet.
+
+ if (shouldDelayEnd()) {
+ m_endWasDelayed = true;
+ return;
+ }
+ prepareToStopParsing();
+}
+
+void HTMLDocumentParser::endIfDelayed()
+{
+ // If we've already been detached, don't bother ending.
+ if (isDetached())
+ return;
+
+ if (!m_endWasDelayed || shouldDelayEnd())
+ return;
+
+ m_endWasDelayed = false;
+ prepareToStopParsing();
+}
+
+void HTMLDocumentParser::finish()
+{
+ // FIXME: We should ASSERT(!m_parserStopped) here, since it does not
+ // makes sense to call any methods on DocumentParser once it's been stopped.
+ // However, FrameLoader::stop calls Document::finishParsing unconditionally
+ // which in turn calls m_parser->finish().
+
+ // We're not going to get any more data off the network, so we tell the
+ // input stream we've reached the end of file. finish() can be called more
+ // than once, if the first time does not call end().
+ if (!m_input.haveSeenEndOfFile())
+ m_input.markEndOfFile();
+ attemptToEnd();
+}
+
+bool HTMLDocumentParser::finishWasCalled()
+{
+ return m_input.haveSeenEndOfFile();
+}
+
+// This function is virtual and just for the DocumentParser interface.
+bool HTMLDocumentParser::isExecutingScript() const
+{
+ return inScriptExecution();
+}
+
+// This function is non-virtual and used throughout the implementation.
+bool HTMLDocumentParser::inScriptExecution() const
+{
+ if (!m_scriptRunner)
+ return false;
+ return m_scriptRunner->isExecutingScript();
+}
+
+int HTMLDocumentParser::lineNumber() const
+{
+ return m_tokenizer->lineNumber();
+}
+
+TextPosition0 HTMLDocumentParser::textPosition() const
+{
+ const SegmentedString& currentString = m_input.current();
+ WTF::ZeroBasedNumber line = currentString.currentLine();
+ WTF::ZeroBasedNumber column = currentString.currentColumn();
+ ASSERT(m_tokenizer->lineNumber() == line.zeroBasedInt());
+
+ return TextPosition0(line, column);
+}
+
+bool HTMLDocumentParser::isWaitingForScripts() const
+{
+ return m_treeBuilder->isPaused();
+}
+
+void HTMLDocumentParser::resumeParsingAfterScriptExecution()
+{
+ ASSERT(!inScriptExecution());
+ ASSERT(!m_treeBuilder->isPaused());
+
+ m_preloadScanner.clear();
+ pumpTokenizerIfPossible(AllowYield);
+ endIfDelayed();
+}
+
+void HTMLDocumentParser::watchForLoad(CachedResource* cachedScript)
+{
+ ASSERT(!cachedScript->isLoaded());
+ // addClient would call notifyFinished if the load were complete.
+ // Callers do not expect to be re-entered from this call, so they should
+ // not an already-loaded CachedResource.
+ cachedScript->addClient(this);
+}
+
+void HTMLDocumentParser::stopWatchingForLoad(CachedResource* cachedScript)
+{
+ cachedScript->removeClient(this);
+}
+
+bool HTMLDocumentParser::shouldLoadExternalScriptFromSrc(const AtomicString& srcValue)
+{
+ if (!xssAuditor())
+ return true;
+ return xssAuditor()->canLoadExternalScriptFromSrc(srcValue);
+}
+
+void HTMLDocumentParser::notifyFinished(CachedResource* cachedResource)
+{
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+
+ ASSERT(m_scriptRunner);
+ ASSERT(!inScriptExecution());
+ if (isStopping()) {
+ attemptToRunDeferredScriptsAndEnd();
+ return;
+ }
+
+ ASSERT(m_treeBuilder->isPaused());
+ // Note: We only ever wait on one script at a time, so we always know this
+ // is the one we were waiting on and can un-pause the tree builder.
+ m_treeBuilder->setPaused(false);
+ bool shouldContinueParsing = m_scriptRunner->executeScriptsWaitingForLoad(cachedResource);
+ m_treeBuilder->setPaused(!shouldContinueParsing);
+ if (shouldContinueParsing)
+ resumeParsingAfterScriptExecution();
+}
+
+void HTMLDocumentParser::executeScriptsWaitingForStylesheets()
+{
+ // Document only calls this when the Document owns the DocumentParser
+ // so this will not be called in the DocumentFragment case.
+ ASSERT(m_scriptRunner);
+ // Ignore calls unless we have a script blocking the parser waiting on a
+ // stylesheet load. Otherwise we are currently parsing and this
+ // is a re-entrant call from encountering a </ style> tag.
+ if (!m_scriptRunner->hasScriptsWaitingForStylesheets())
+ return;
+
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+
+ ASSERT(!m_scriptRunner->isExecutingScript());
+ ASSERT(m_treeBuilder->isPaused());
+ // Note: We only ever wait on one script at a time, so we always know this
+ // is the one we were waiting on and can un-pause the tree builder.
+ m_treeBuilder->setPaused(false);
+ bool shouldContinueParsing = m_scriptRunner->executeScriptsWaitingForStylesheets();
+ m_treeBuilder->setPaused(!shouldContinueParsing);
+ if (shouldContinueParsing)
+ resumeParsingAfterScriptExecution();
+}
+
+ScriptController* HTMLDocumentParser::script() const
+{
+ return document()->frame() ? document()->frame()->script() : 0;
+}
+
+void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
+{
+ RefPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(fragment, contextElement, scriptingPermission);
+ parser->insert(source); // Use insert() so that the parser will not yield.
+ parser->finish();
+ ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/3963151>
+ parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction.
+}
+
+bool HTMLDocumentParser::usePreHTML5ParserQuirks(Document* document)
+{
+ ASSERT(document);
+ return document->settings() && document->settings()->usePreHTML5ParserQuirks();
+}
+
+void HTMLDocumentParser::suspendScheduledTasks()
+{
+ if (m_parserScheduler)
+ m_parserScheduler->suspend();
+}
+
+void HTMLDocumentParser::resumeScheduledTasks()
+{
+ if (m_parserScheduler)
+ m_parserScheduler->resume();
+}
+
+}
diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.h b/Source/WebCore/html/parser/HTMLDocumentParser.h
new file mode 100644
index 0000000..80ca727
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLDocumentParser.h
@@ -0,0 +1,150 @@
+/*
+ * 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 HTMLDocumentParser_h
+#define HTMLDocumentParser_h
+
+#include "CachedResourceClient.h"
+#include "FragmentScriptingPermission.h"
+#include "HTMLInputStream.h"
+#include "HTMLScriptRunnerHost.h"
+#include "HTMLToken.h"
+#include "ScriptableDocumentParser.h"
+#include "SegmentedString.h"
+#include "Timer.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class Document;
+class DocumentFragment;
+class HTMLDocument;
+class HTMLParserScheduler;
+class HTMLTokenizer;
+class HTMLScriptRunner;
+class HTMLTreeBuilder;
+class HTMLPreloadScanner;
+class ScriptController;
+class ScriptSourceCode;
+
+class HTMLDocumentParser : public ScriptableDocumentParser, HTMLScriptRunnerHost, CachedResourceClient {
+public:
+ static PassRefPtr<HTMLDocumentParser> create(HTMLDocument* document, bool reportErrors)
+ {
+ return adoptRef(new HTMLDocumentParser(document, reportErrors));
+ }
+ static PassRefPtr<HTMLDocumentParser> create(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission permission)
+ {
+ return adoptRef(new HTMLDocumentParser(fragment, contextElement, permission));
+ }
+
+ virtual ~HTMLDocumentParser();
+
+ // Exposed for HTMLParserScheduler
+ void resumeParsingAfterYield();
+
+ static void parseDocumentFragment(const String&, DocumentFragment*, Element* contextElement, FragmentScriptingPermission = FragmentScriptingAllowed);
+
+ static bool usePreHTML5ParserQuirks(Document*);
+
+ HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); }
+
+ virtual TextPosition0 textPosition() const;
+ virtual void suspendScheduledTasks();
+ virtual void resumeScheduledTasks();
+
+protected:
+ virtual void insert(const SegmentedString&);
+ virtual void append(const SegmentedString&);
+ virtual void finish();
+
+ HTMLDocumentParser(HTMLDocument*, bool reportErrors);
+ HTMLDocumentParser(DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
+
+ HTMLTreeBuilder* treeBuilder() const { return m_treeBuilder.get(); }
+
+private:
+ // DocumentParser
+ virtual void detach();
+ virtual bool hasInsertionPoint();
+ virtual bool finishWasCalled();
+ virtual bool processingData() const;
+ virtual void prepareToStopParsing();
+ virtual void stopParsing();
+ virtual bool isWaitingForScripts() const;
+ virtual bool isExecutingScript() const;
+ virtual void executeScriptsWaitingForStylesheets();
+ virtual int lineNumber() const;
+
+ // HTMLScriptRunnerHost
+ virtual void watchForLoad(CachedResource*);
+ virtual void stopWatchingForLoad(CachedResource*);
+ virtual bool shouldLoadExternalScriptFromSrc(const AtomicString&);
+ virtual HTMLInputStream& inputStream() { return m_input; }
+
+ // CachedResourceClient
+ virtual void notifyFinished(CachedResource*);
+
+ enum SynchronousMode {
+ AllowYield,
+ ForceSynchronous,
+ };
+ void pumpTokenizer(SynchronousMode);
+ void pumpTokenizerIfPossible(SynchronousMode);
+
+ bool runScriptsForPausedTreeBuilder();
+ void resumeParsingAfterScriptExecution();
+
+ void begin();
+ void attemptToEnd();
+ void endIfDelayed();
+ void attemptToRunDeferredScriptsAndEnd();
+ void end();
+
+ bool isScheduledForResume() const;
+ bool inScriptExecution() const;
+ bool inWrite() const { return m_writeNestingLevel > 0; }
+ bool shouldDelayEnd() const { return inWrite() || isWaitingForScripts() || inScriptExecution() || isScheduledForResume(); }
+
+ ScriptController* script() const;
+
+ HTMLInputStream m_input;
+
+ // We hold m_token here because it might be partially complete.
+ HTMLToken m_token;
+
+ OwnPtr<HTMLTokenizer> m_tokenizer;
+ OwnPtr<HTMLScriptRunner> m_scriptRunner;
+ OwnPtr<HTMLTreeBuilder> m_treeBuilder;
+ OwnPtr<HTMLPreloadScanner> m_preloadScanner;
+ OwnPtr<HTMLParserScheduler> m_parserScheduler;
+
+ bool m_endWasDelayed;
+ unsigned m_writeNestingLevel;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLElementStack.cpp b/Source/WebCore/html/parser/HTMLElementStack.cpp
new file mode 100644
index 0000000..6aab0f7
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLElementStack.cpp
@@ -0,0 +1,569 @@
+/*
+ * 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 GOOGLE 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 GOOGLE 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 "HTMLElementStack.h"
+
+#include "Element.h"
+#include "HTMLNames.h"
+#include "MathMLNames.h"
+#include "SVGNames.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+namespace {
+
+inline bool isNumberedHeaderElement(Element* element)
+{
+ return element->hasTagName(h1Tag)
+ || element->hasTagName(h2Tag)
+ || element->hasTagName(h3Tag)
+ || element->hasTagName(h4Tag)
+ || element->hasTagName(h5Tag)
+ || element->hasTagName(h6Tag);
+}
+
+inline bool isScopeMarker(Element* element)
+{
+ return element->hasTagName(appletTag)
+ || element->hasTagName(captionTag)
+ || element->hasTagName(htmlTag)
+ || element->hasTagName(marqueeTag)
+ || element->hasTagName(objectTag)
+ || element->hasTagName(tableTag)
+ || element->hasTagName(tdTag)
+ || element->hasTagName(thTag)
+ || element->hasTagName(MathMLNames::miTag)
+ || element->hasTagName(MathMLNames::moTag)
+ || element->hasTagName(MathMLNames::mnTag)
+ || element->hasTagName(MathMLNames::msTag)
+ || element->hasTagName(MathMLNames::mtextTag)
+ || element->hasTagName(MathMLNames::annotation_xmlTag)
+ || element->hasTagName(SVGNames::foreignObjectTag)
+ || element->hasTagName(SVGNames::descTag)
+ || element->hasTagName(SVGNames::titleTag);
+}
+
+inline bool isListItemScopeMarker(Element* element)
+{
+ return isScopeMarker(element)
+ || element->hasTagName(olTag)
+ || element->hasTagName(ulTag);
+}
+
+inline bool isTableScopeMarker(Element* element)
+{
+ return element->hasTagName(tableTag)
+ || element->hasTagName(htmlTag);
+}
+
+inline bool isTableBodyScopeMarker(Element* element)
+{
+ return element->hasTagName(tbodyTag)
+ || element->hasTagName(tfootTag)
+ || element->hasTagName(theadTag)
+ || element->hasTagName(htmlTag);
+}
+
+inline bool isTableRowScopeMarker(Element* element)
+{
+ return element->hasTagName(trTag)
+ || element->hasTagName(htmlTag);
+}
+
+inline bool isForeignContentScopeMarker(Element* element)
+{
+ return element->hasTagName(MathMLNames::miTag)
+ || element->hasTagName(MathMLNames::moTag)
+ || element->hasTagName(MathMLNames::mnTag)
+ || element->hasTagName(MathMLNames::msTag)
+ || element->hasTagName(MathMLNames::mtextTag)
+ || element->hasTagName(SVGNames::foreignObjectTag)
+ || element->hasTagName(SVGNames::descTag)
+ || element->hasTagName(SVGNames::titleTag)
+ || element->namespaceURI() == HTMLNames::xhtmlNamespaceURI;
+}
+
+inline bool isButtonScopeMarker(Element* element)
+{
+ return isScopeMarker(element)
+ || element->hasTagName(buttonTag);
+}
+
+inline bool isSelectScopeMarker(Element* element)
+{
+ return !element->hasTagName(optgroupTag)
+ && !element->hasTagName(optionTag);
+}
+
+}
+
+HTMLElementStack::ElementRecord::ElementRecord(PassRefPtr<Element> element, PassOwnPtr<ElementRecord> next)
+ : m_element(element)
+ , m_next(next)
+{
+ ASSERT(m_element);
+}
+
+HTMLElementStack::ElementRecord::~ElementRecord()
+{
+}
+
+void HTMLElementStack::ElementRecord::replaceElement(PassRefPtr<Element> element)
+{
+ ASSERT(element);
+ // FIXME: Should this call finishParsingChildren?
+ m_element = element;
+}
+
+bool HTMLElementStack::ElementRecord::isAbove(ElementRecord* other) const
+{
+ for (ElementRecord* below = next(); below; below = below->next()) {
+ if (below == other)
+ return true;
+ }
+ return false;
+}
+
+HTMLElementStack::HTMLElementStack()
+ : m_htmlElement(0)
+ , m_headElement(0)
+ , m_bodyElement(0)
+{
+}
+
+HTMLElementStack::~HTMLElementStack()
+{
+}
+
+bool HTMLElementStack::hasOnlyOneElement() const
+{
+ return !topRecord()->next();
+}
+
+bool HTMLElementStack::secondElementIsHTMLBodyElement() const
+{
+ // This is used the fragment case of <body> and <frameset> in the "in body"
+ // insertion mode.
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-inbody
+ ASSERT(m_htmlElement);
+ // If we have a body element, it must always be the second element on the
+ // stack, as we always start with an html element, and any other element
+ // would cause the implicit creation of a body element.
+ return !!m_bodyElement;
+}
+
+void HTMLElementStack::popHTMLHeadElement()
+{
+ ASSERT(top() == m_headElement);
+ m_headElement = 0;
+ popCommon();
+}
+
+void HTMLElementStack::popHTMLBodyElement()
+{
+ ASSERT(top() == m_bodyElement);
+ m_bodyElement = 0;
+ popCommon();
+}
+
+void HTMLElementStack::popAll()
+{
+ m_htmlElement = 0;
+ m_headElement = 0;
+ m_bodyElement = 0;
+ while (m_top) {
+ top()->finishParsingChildren();
+ m_top = m_top->releaseNext();
+ }
+}
+
+void HTMLElementStack::pop()
+{
+ ASSERT(!top()->hasTagName(HTMLNames::headTag));
+ popCommon();
+}
+
+void HTMLElementStack::popUntil(const AtomicString& tagName)
+{
+ while (!top()->hasLocalName(tagName)) {
+ // pop() will ASSERT at <body> if callers fail to check that there is an
+ // element with localName |tagName| on the stack of open elements.
+ pop();
+ }
+}
+
+void HTMLElementStack::popUntilPopped(const AtomicString& tagName)
+{
+ popUntil(tagName);
+ pop();
+}
+
+void HTMLElementStack::popUntilNumberedHeaderElementPopped()
+{
+ while (!isNumberedHeaderElement(top()))
+ pop();
+ pop();
+}
+
+void HTMLElementStack::popUntil(Element* element)
+{
+ while (top() != element)
+ pop();
+}
+
+void HTMLElementStack::popUntilPopped(Element* element)
+{
+ popUntil(element);
+ pop();
+}
+
+void HTMLElementStack::popUntilTableScopeMarker()
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#clear-the-stack-back-to-a-table-context
+ while (!isTableScopeMarker(top()))
+ pop();
+}
+
+void HTMLElementStack::popUntilTableBodyScopeMarker()
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#clear-the-stack-back-to-a-table-body-context
+ while (!isTableBodyScopeMarker(top()))
+ pop();
+}
+
+void HTMLElementStack::popUntilTableRowScopeMarker()
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#clear-the-stack-back-to-a-table-row-context
+ while (!isTableRowScopeMarker(top()))
+ pop();
+}
+
+void HTMLElementStack::popUntilForeignContentScopeMarker()
+{
+ while (!isForeignContentScopeMarker(top()))
+ pop();
+}
+
+void HTMLElementStack::pushHTMLHtmlElement(PassRefPtr<Element> element)
+{
+ ASSERT(!m_top); // <html> should always be the bottom of the stack.
+ ASSERT(element->hasTagName(HTMLNames::htmlTag));
+ ASSERT(!m_htmlElement);
+ m_htmlElement = element.get();
+ pushCommon(element);
+}
+
+void HTMLElementStack::pushHTMLHeadElement(PassRefPtr<Element> element)
+{
+ ASSERT(element->hasTagName(HTMLNames::headTag));
+ ASSERT(!m_headElement);
+ m_headElement = element.get();
+ pushCommon(element);
+}
+
+void HTMLElementStack::pushHTMLBodyElement(PassRefPtr<Element> element)
+{
+ ASSERT(element->hasTagName(HTMLNames::bodyTag));
+ ASSERT(!m_bodyElement);
+ m_bodyElement = element.get();
+ pushCommon(element);
+}
+
+void HTMLElementStack::push(PassRefPtr<Element> element)
+{
+ ASSERT(!element->hasTagName(HTMLNames::htmlTag));
+ ASSERT(!element->hasTagName(HTMLNames::headTag));
+ ASSERT(!element->hasTagName(HTMLNames::bodyTag));
+ ASSERT(m_htmlElement);
+ pushCommon(element);
+}
+
+void HTMLElementStack::insertAbove(PassRefPtr<Element> element, ElementRecord* recordBelow)
+{
+ ASSERT(element);
+ ASSERT(recordBelow);
+ ASSERT(m_top);
+ ASSERT(!element->hasTagName(HTMLNames::htmlTag));
+ ASSERT(!element->hasTagName(HTMLNames::headTag));
+ ASSERT(!element->hasTagName(HTMLNames::bodyTag));
+ ASSERT(m_htmlElement);
+ if (recordBelow == m_top) {
+ push(element);
+ return;
+ }
+
+ for (ElementRecord* recordAbove = m_top.get(); recordAbove; recordAbove = recordAbove->next()) {
+ if (recordAbove->next() != recordBelow)
+ continue;
+
+ recordAbove->setNext(adoptPtr(new ElementRecord(element, recordAbove->releaseNext())));
+ recordAbove->next()->element()->beginParsingChildren();
+ return;
+ }
+ ASSERT_NOT_REACHED();
+}
+
+HTMLElementStack::ElementRecord* HTMLElementStack::topRecord() const
+{
+ ASSERT(m_top);
+ return m_top.get();
+}
+
+Element* HTMLElementStack::oneBelowTop() const
+{
+ // We should never be calling this if it could be 0.
+ ASSERT(m_top);
+ ASSERT(m_top->next());
+ return m_top->next()->element();
+}
+
+Element* HTMLElementStack::bottom() const
+{
+ return htmlElement();
+}
+
+void HTMLElementStack::removeHTMLHeadElement(Element* element)
+{
+ ASSERT(m_headElement == element);
+ if (m_top->element() == element) {
+ popHTMLHeadElement();
+ return;
+ }
+ m_headElement = 0;
+ removeNonTopCommon(element);
+}
+
+void HTMLElementStack::remove(Element* element)
+{
+ ASSERT(!element->hasTagName(HTMLNames::headTag));
+ if (m_top->element() == element) {
+ pop();
+ return;
+ }
+ removeNonTopCommon(element);
+}
+
+HTMLElementStack::ElementRecord* HTMLElementStack::find(Element* element) const
+{
+ for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
+ if (pos->element() == element)
+ return pos;
+ }
+ return 0;
+}
+
+HTMLElementStack::ElementRecord* HTMLElementStack::topmost(const AtomicString& tagName) const
+{
+ for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
+ if (pos->element()->hasLocalName(tagName))
+ return pos;
+ }
+ return 0;
+}
+
+bool HTMLElementStack::contains(Element* element) const
+{
+ return !!find(element);
+}
+
+bool HTMLElementStack::contains(const AtomicString& tagName) const
+{
+ return !!topmost(tagName);
+}
+
+template <bool isMarker(Element*)>
+bool inScopeCommon(HTMLElementStack::ElementRecord* top, const AtomicString& targetTag)
+{
+ for (HTMLElementStack::ElementRecord* pos = top; pos; pos = pos->next()) {
+ Element* element = pos->element();
+ if (element->hasLocalName(targetTag))
+ return true;
+ if (isMarker(element))
+ return false;
+ }
+ ASSERT_NOT_REACHED(); // <html> is always on the stack and is a scope marker.
+ return false;
+}
+
+bool HTMLElementStack::hasOnlyHTMLElementsInScope() const
+{
+ for (ElementRecord* record = m_top.get(); record; record = record->next()) {
+ Element* element = record->element();
+ if (element->namespaceURI() != xhtmlNamespaceURI)
+ return false;
+ if (isScopeMarker(element))
+ return true;
+ }
+ ASSERT_NOT_REACHED(); // <html> is always on the stack and is a scope marker.
+ return true;
+}
+
+bool HTMLElementStack::hasNumberedHeaderElementInScope() const
+{
+ for (ElementRecord* record = m_top.get(); record; record = record->next()) {
+ Element* element = record->element();
+ if (isNumberedHeaderElement(element))
+ return true;
+ if (isScopeMarker(element))
+ return false;
+ }
+ ASSERT_NOT_REACHED(); // <html> is always on the stack and is a scope marker.
+ return false;
+}
+
+bool HTMLElementStack::inScope(Element* targetElement) const
+{
+ for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
+ Element* element = pos->element();
+ if (element == targetElement)
+ return true;
+ if (isScopeMarker(element))
+ return false;
+ }
+ ASSERT_NOT_REACHED(); // <html> is always on the stack and is a scope marker.
+ return false;
+}
+
+bool HTMLElementStack::inScope(const AtomicString& targetTag) const
+{
+ return inScopeCommon<isScopeMarker>(m_top.get(), targetTag);
+}
+
+bool HTMLElementStack::inScope(const QualifiedName& tagName) const
+{
+ // FIXME: Is localName() right for non-html elements?
+ return inScope(tagName.localName());
+}
+
+bool HTMLElementStack::inListItemScope(const AtomicString& targetTag) const
+{
+ return inScopeCommon<isListItemScopeMarker>(m_top.get(), targetTag);
+}
+
+bool HTMLElementStack::inListItemScope(const QualifiedName& tagName) const
+{
+ // FIXME: Is localName() right for non-html elements?
+ return inListItemScope(tagName.localName());
+}
+
+bool HTMLElementStack::inTableScope(const AtomicString& targetTag) const
+{
+ return inScopeCommon<isTableScopeMarker>(m_top.get(), targetTag);
+}
+
+bool HTMLElementStack::inTableScope(const QualifiedName& tagName) const
+{
+ // FIXME: Is localName() right for non-html elements?
+ return inTableScope(tagName.localName());
+}
+
+bool HTMLElementStack::inButtonScope(const AtomicString& targetTag) const
+{
+ return inScopeCommon<isButtonScopeMarker>(m_top.get(), targetTag);
+}
+
+bool HTMLElementStack::inButtonScope(const QualifiedName& tagName) const
+{
+ // FIXME: Is localName() right for non-html elements?
+ return inButtonScope(tagName.localName());
+}
+
+bool HTMLElementStack::inSelectScope(const AtomicString& targetTag) const
+{
+ return inScopeCommon<isSelectScopeMarker>(m_top.get(), targetTag);
+}
+
+bool HTMLElementStack::inSelectScope(const QualifiedName& tagName) const
+{
+ // FIXME: Is localName() right for non-html elements?
+ return inSelectScope(tagName.localName());
+}
+
+Element* HTMLElementStack::htmlElement() const
+{
+ ASSERT(m_htmlElement);
+ return m_htmlElement;
+}
+
+Element* HTMLElementStack::headElement() const
+{
+ ASSERT(m_headElement);
+ return m_headElement;
+}
+
+Element* HTMLElementStack::bodyElement() const
+{
+ ASSERT(m_bodyElement);
+ return m_bodyElement;
+}
+
+void HTMLElementStack::pushCommon(PassRefPtr<Element> element)
+{
+ ASSERT(m_htmlElement);
+ m_top = adoptPtr(new ElementRecord(element, m_top.release()));
+ top()->beginParsingChildren();
+}
+
+void HTMLElementStack::popCommon()
+{
+ ASSERT(!top()->hasTagName(HTMLNames::htmlTag));
+ ASSERT(!top()->hasTagName(HTMLNames::headTag) || !m_headElement);
+ ASSERT(!top()->hasTagName(HTMLNames::bodyTag) || !m_bodyElement);
+ top()->finishParsingChildren();
+ m_top = m_top->releaseNext();
+}
+
+void HTMLElementStack::removeNonTopCommon(Element* element)
+{
+ ASSERT(!element->hasTagName(HTMLNames::htmlTag));
+ ASSERT(!element->hasTagName(HTMLNames::bodyTag));
+ 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();
+ pos->setNext(pos->next()->releaseNext());
+ return;
+ }
+ }
+ ASSERT_NOT_REACHED();
+}
+
+#ifndef NDEBUG
+
+void HTMLElementStack::show()
+{
+ for (ElementRecord* record = m_top.get(); record; record = record->next())
+ record->element()->showNode();
+}
+
+#endif
+
+}
diff --git a/Source/WebCore/html/parser/HTMLElementStack.h b/Source/WebCore/html/parser/HTMLElementStack.h
new file mode 100644
index 0000000..8a8e160
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLElementStack.h
@@ -0,0 +1,156 @@
+/*
+ * 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 GOOGLE 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 GOOGLE 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 HTMLElementStack_h
+#define HTMLElementStack_h
+
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Element;
+class QualifiedName;
+
+// NOTE: The HTML5 spec uses a backwards (grows downward) stack. We're using
+// more standard (grows upwards) stack terminology here.
+class HTMLElementStack : public Noncopyable {
+public:
+ HTMLElementStack();
+ ~HTMLElementStack();
+
+ class ElementRecord : public Noncopyable {
+ public:
+ ~ElementRecord(); // Public for ~PassOwnPtr()
+
+ Element* element() const { return m_element.get(); }
+ void replaceElement(PassRefPtr<Element>);
+
+ bool isAbove(ElementRecord*) const;
+
+ ElementRecord* next() const { return m_next.get(); }
+
+ private:
+ friend class HTMLElementStack;
+
+ ElementRecord(PassRefPtr<Element>, PassOwnPtr<ElementRecord>);
+
+ PassOwnPtr<ElementRecord> releaseNext() { return m_next.release(); }
+ void setNext(PassOwnPtr<ElementRecord> next) { m_next = next; }
+
+ RefPtr<Element> m_element;
+ OwnPtr<ElementRecord> m_next;
+ };
+
+ // Inlining this function is a (small) performance win on the parsing
+ // benchmark.
+ Element* top() const
+ {
+ ASSERT(m_top->element());
+ return m_top->element();
+ }
+
+ Element* oneBelowTop() const;
+ ElementRecord* topRecord() const;
+ Element* bottom() const;
+ ElementRecord* find(Element*) const;
+ ElementRecord* topmost(const AtomicString& tagName) const;
+
+ void insertAbove(PassRefPtr<Element>, ElementRecord*);
+
+ void push(PassRefPtr<Element>);
+ void pushHTMLHtmlElement(PassRefPtr<Element>);
+ void pushHTMLHeadElement(PassRefPtr<Element>);
+ void pushHTMLBodyElement(PassRefPtr<Element>);
+
+ void pop();
+ void popUntil(const AtomicString& tagName);
+ void popUntil(Element*);
+ void popUntilPopped(const AtomicString& tagName);
+ void popUntilPopped(Element*);
+ void popUntilNumberedHeaderElementPopped();
+ void popUntilTableScopeMarker(); // "clear the stack back to a table context" in the spec.
+ void popUntilTableBodyScopeMarker(); // "clear the stack back to a table body context" in the spec.
+ void popUntilTableRowScopeMarker(); // "clear the stack back to a table row context" in the spec.
+ void popUntilForeignContentScopeMarker();
+ void popHTMLHeadElement();
+ void popHTMLBodyElement();
+ void popAll();
+
+ void remove(Element*);
+ void removeHTMLHeadElement(Element*);
+
+ bool contains(Element*) const;
+ bool contains(const AtomicString& tagName) const;
+
+ bool inScope(Element*) const;
+ bool inScope(const AtomicString& tagName) const;
+ bool inScope(const QualifiedName&) const;
+ bool inListItemScope(const AtomicString& tagName) const;
+ bool inListItemScope(const QualifiedName&) const;
+ bool inTableScope(const AtomicString& tagName) const;
+ bool inTableScope(const QualifiedName&) const;
+ bool inButtonScope(const AtomicString& tagName) const;
+ bool inButtonScope(const QualifiedName&) const;
+ bool inSelectScope(const AtomicString& tagName) const;
+ bool inSelectScope(const QualifiedName&) const;
+
+ bool hasOnlyHTMLElementsInScope() const;
+ bool hasNumberedHeaderElementInScope() const;
+
+ bool hasOnlyOneElement() const;
+ bool secondElementIsHTMLBodyElement() const;
+
+ Element* htmlElement() const;
+ Element* headElement() const;
+ Element* bodyElement() const;
+
+#ifndef NDEBUG
+ void show();
+#endif
+
+private:
+ void pushCommon(PassRefPtr<Element>);
+ void popCommon();
+ void removeNonTopCommon(Element*);
+
+ OwnPtr<ElementRecord> m_top;
+
+ // We remember <html>, <head> and <body> as they are pushed. Their
+ // ElementRecords keep them alive. <html> is never popped.
+ // FIXME: We don't currently require type-specific information about
+ // these elements so we haven't yet bothered to plumb the types all the
+ // way down through createElement, etc.
+ Element* m_htmlElement;
+ Element* m_headElement;
+ Element* m_bodyElement;
+};
+
+} // namespace WebCore
+
+#endif // HTMLElementStack_h
diff --git a/Source/WebCore/html/parser/HTMLEntityNames.in b/Source/WebCore/html/parser/HTMLEntityNames.in
new file mode 100644
index 0000000..2d42ab2
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLEntityNames.in
@@ -0,0 +1,2138 @@
+"AElig;","U+000C6"
+"AElig","U+000C6"
+"AMP;","U+00026"
+"AMP","U+00026"
+"Aacute;","U+000C1"
+"Aacute","U+000C1"
+"Abreve;","U+00102"
+"Acirc;","U+000C2"
+"Acirc","U+000C2"
+"Acy;","U+00410"
+"Afr;","U+1D504"
+"Agrave;","U+000C0"
+"Agrave","U+000C0"
+"Alpha;","U+00391"
+"Amacr;","U+00100"
+"And;","U+02A53"
+"Aogon;","U+00104"
+"Aopf;","U+1D538"
+"ApplyFunction;","U+02061"
+"Aring;","U+000C5"
+"Aring","U+000C5"
+"Ascr;","U+1D49C"
+"Assign;","U+02254"
+"Atilde;","U+000C3"
+"Atilde","U+000C3"
+"Auml;","U+000C4"
+"Auml","U+000C4"
+"Backslash;","U+02216"
+"Barv;","U+02AE7"
+"Barwed;","U+02306"
+"Bcy;","U+00411"
+"Because;","U+02235"
+"Bernoullis;","U+0212C"
+"Beta;","U+00392"
+"Bfr;","U+1D505"
+"Bopf;","U+1D539"
+"Breve;","U+002D8"
+"Bscr;","U+0212C"
+"Bumpeq;","U+0224E"
+"CHcy;","U+00427"
+"COPY;","U+000A9"
+"COPY","U+000A9"
+"Cacute;","U+00106"
+"Cap;","U+022D2"
+"CapitalDifferentialD;","U+02145"
+"Cayleys;","U+0212D"
+"Ccaron;","U+0010C"
+"Ccedil;","U+000C7"
+"Ccedil","U+000C7"
+"Ccirc;","U+00108"
+"Cconint;","U+02230"
+"Cdot;","U+0010A"
+"Cedilla;","U+000B8"
+"CenterDot;","U+000B7"
+"Cfr;","U+0212D"
+"Chi;","U+003A7"
+"CircleDot;","U+02299"
+"CircleMinus;","U+02296"
+"CirclePlus;","U+02295"
+"CircleTimes;","U+02297"
+"ClockwiseContourIntegral;","U+02232"
+"CloseCurlyDoubleQuote;","U+0201D"
+"CloseCurlyQuote;","U+02019"
+"Colon;","U+02237"
+"Colone;","U+02A74"
+"Congruent;","U+02261"
+"Conint;","U+0222F"
+"ContourIntegral;","U+0222E"
+"Copf;","U+02102"
+"Coproduct;","U+02210"
+"CounterClockwiseContourIntegral;","U+02233"
+"Cross;","U+02A2F"
+"Cscr;","U+1D49E"
+"Cup;","U+022D3"
+"CupCap;","U+0224D"
+"DD;","U+02145"
+"DDotrahd;","U+02911"
+"DJcy;","U+00402"
+"DScy;","U+00405"
+"DZcy;","U+0040F"
+"Dagger;","U+02021"
+"Darr;","U+021A1"
+"Dashv;","U+02AE4"
+"Dcaron;","U+0010E"
+"Dcy;","U+00414"
+"Del;","U+02207"
+"Delta;","U+00394"
+"Dfr;","U+1D507"
+"DiacriticalAcute;","U+000B4"
+"DiacriticalDot;","U+002D9"
+"DiacriticalDoubleAcute;","U+002DD"
+"DiacriticalGrave;","U+00060"
+"DiacriticalTilde;","U+002DC"
+"Diamond;","U+022C4"
+"DifferentialD;","U+02146"
+"Dopf;","U+1D53B"
+"Dot;","U+000A8"
+"DotDot;","U+020DC"
+"DotEqual;","U+02250"
+"DoubleContourIntegral;","U+0222F"
+"DoubleDot;","U+000A8"
+"DoubleDownArrow;","U+021D3"
+"DoubleLeftArrow;","U+021D0"
+"DoubleLeftRightArrow;","U+021D4"
+"DoubleLeftTee;","U+02AE4"
+"DoubleLongLeftArrow;","U+027F8"
+"DoubleLongLeftRightArrow;","U+027FA"
+"DoubleLongRightArrow;","U+027F9"
+"DoubleRightArrow;","U+021D2"
+"DoubleRightTee;","U+022A8"
+"DoubleUpArrow;","U+021D1"
+"DoubleUpDownArrow;","U+021D5"
+"DoubleVerticalBar;","U+02225"
+"DownArrow;","U+02193"
+"DownArrowBar;","U+02913"
+"DownArrowUpArrow;","U+021F5"
+"DownBreve;","U+00311"
+"DownLeftRightVector;","U+02950"
+"DownLeftTeeVector;","U+0295E"
+"DownLeftVector;","U+021BD"
+"DownLeftVectorBar;","U+02956"
+"DownRightTeeVector;","U+0295F"
+"DownRightVector;","U+021C1"
+"DownRightVectorBar;","U+02957"
+"DownTee;","U+022A4"
+"DownTeeArrow;","U+021A7"
+"Downarrow;","U+021D3"
+"Dscr;","U+1D49F"
+"Dstrok;","U+00110"
+"ENG;","U+0014A"
+"ETH;","U+000D0"
+"ETH","U+000D0"
+"Eacute;","U+000C9"
+"Eacute","U+000C9"
+"Ecaron;","U+0011A"
+"Ecirc;","U+000CA"
+"Ecirc","U+000CA"
+"Ecy;","U+0042D"
+"Edot;","U+00116"
+"Efr;","U+1D508"
+"Egrave;","U+000C8"
+"Egrave","U+000C8"
+"Element;","U+02208"
+"Emacr;","U+00112"
+"EmptySmallSquare;","U+025FB"
+"EmptyVerySmallSquare;","U+025AB"
+"Eogon;","U+00118"
+"Eopf;","U+1D53C"
+"Epsilon;","U+00395"
+"Equal;","U+02A75"
+"EqualTilde;","U+02242"
+"Equilibrium;","U+021CC"
+"Escr;","U+02130"
+"Esim;","U+02A73"
+"Eta;","U+00397"
+"Euml;","U+000CB"
+"Euml","U+000CB"
+"Exists;","U+02203"
+"ExponentialE;","U+02147"
+"Fcy;","U+00424"
+"Ffr;","U+1D509"
+"FilledSmallSquare;","U+025FC"
+"FilledVerySmallSquare;","U+025AA"
+"Fopf;","U+1D53D"
+"ForAll;","U+02200"
+"Fouriertrf;","U+02131"
+"Fscr;","U+02131"
+"GJcy;","U+00403"
+"GT;","U+0003E"
+"GT","U+0003E"
+"Gamma;","U+00393"
+"Gammad;","U+003DC"
+"Gbreve;","U+0011E"
+"Gcedil;","U+00122"
+"Gcirc;","U+0011C"
+"Gcy;","U+00413"
+"Gdot;","U+00120"
+"Gfr;","U+1D50A"
+"Gg;","U+022D9"
+"Gopf;","U+1D53E"
+"GreaterEqual;","U+02265"
+"GreaterEqualLess;","U+022DB"
+"GreaterFullEqual;","U+02267"
+"GreaterGreater;","U+02AA2"
+"GreaterLess;","U+02277"
+"GreaterSlantEqual;","U+02A7E"
+"GreaterTilde;","U+02273"
+"Gscr;","U+1D4A2"
+"Gt;","U+0226B"
+"HARDcy;","U+0042A"
+"Hacek;","U+002C7"
+"Hat;","U+0005E"
+"Hcirc;","U+00124"
+"Hfr;","U+0210C"
+"HilbertSpace;","U+0210B"
+"Hopf;","U+0210D"
+"HorizontalLine;","U+02500"
+"Hscr;","U+0210B"
+"Hstrok;","U+00126"
+"HumpDownHump;","U+0224E"
+"HumpEqual;","U+0224F"
+"IEcy;","U+00415"
+"IJlig;","U+00132"
+"IOcy;","U+00401"
+"Iacute;","U+000CD"
+"Iacute","U+000CD"
+"Icirc;","U+000CE"
+"Icirc","U+000CE"
+"Icy;","U+00418"
+"Idot;","U+00130"
+"Ifr;","U+02111"
+"Igrave;","U+000CC"
+"Igrave","U+000CC"
+"Im;","U+02111"
+"Imacr;","U+0012A"
+"ImaginaryI;","U+02148"
+"Implies;","U+021D2"
+"Int;","U+0222C"
+"Integral;","U+0222B"
+"Intersection;","U+022C2"
+"InvisibleComma;","U+02063"
+"InvisibleTimes;","U+02062"
+"Iogon;","U+0012E"
+"Iopf;","U+1D540"
+"Iota;","U+00399"
+"Iscr;","U+02110"
+"Itilde;","U+00128"
+"Iukcy;","U+00406"
+"Iuml;","U+000CF"
+"Iuml","U+000CF"
+"Jcirc;","U+00134"
+"Jcy;","U+00419"
+"Jfr;","U+1D50D"
+"Jopf;","U+1D541"
+"Jscr;","U+1D4A5"
+"Jsercy;","U+00408"
+"Jukcy;","U+00404"
+"KHcy;","U+00425"
+"KJcy;","U+0040C"
+"Kappa;","U+0039A"
+"Kcedil;","U+00136"
+"Kcy;","U+0041A"
+"Kfr;","U+1D50E"
+"Kopf;","U+1D542"
+"Kscr;","U+1D4A6"
+"LJcy;","U+00409"
+"LT;","U+0003C"
+"LT","U+0003C"
+"Lacute;","U+00139"
+"Lambda;","U+0039B"
+"Lang;","U+027EA"
+"Laplacetrf;","U+02112"
+"Larr;","U+0219E"
+"Lcaron;","U+0013D"
+"Lcedil;","U+0013B"
+"Lcy;","U+0041B"
+"LeftAngleBracket;","U+027E8"
+"LeftArrow;","U+02190"
+"LeftArrowBar;","U+021E4"
+"LeftArrowRightArrow;","U+021C6"
+"LeftCeiling;","U+02308"
+"LeftDoubleBracket;","U+027E6"
+"LeftDownTeeVector;","U+02961"
+"LeftDownVector;","U+021C3"
+"LeftDownVectorBar;","U+02959"
+"LeftFloor;","U+0230A"
+"LeftRightArrow;","U+02194"
+"LeftRightVector;","U+0294E"
+"LeftTee;","U+022A3"
+"LeftTeeArrow;","U+021A4"
+"LeftTeeVector;","U+0295A"
+"LeftTriangle;","U+022B2"
+"LeftTriangleBar;","U+029CF"
+"LeftTriangleEqual;","U+022B4"
+"LeftUpDownVector;","U+02951"
+"LeftUpTeeVector;","U+02960"
+"LeftUpVector;","U+021BF"
+"LeftUpVectorBar;","U+02958"
+"LeftVector;","U+021BC"
+"LeftVectorBar;","U+02952"
+"Leftarrow;","U+021D0"
+"Leftrightarrow;","U+021D4"
+"LessEqualGreater;","U+022DA"
+"LessFullEqual;","U+02266"
+"LessGreater;","U+02276"
+"LessLess;","U+02AA1"
+"LessSlantEqual;","U+02A7D"
+"LessTilde;","U+02272"
+"Lfr;","U+1D50F"
+"Ll;","U+022D8"
+"Lleftarrow;","U+021DA"
+"Lmidot;","U+0013F"
+"LongLeftArrow;","U+027F5"
+"LongLeftRightArrow;","U+027F7"
+"LongRightArrow;","U+027F6"
+"Longleftarrow;","U+027F8"
+"Longleftrightarrow;","U+027FA"
+"Longrightarrow;","U+027F9"
+"Lopf;","U+1D543"
+"LowerLeftArrow;","U+02199"
+"LowerRightArrow;","U+02198"
+"Lscr;","U+02112"
+"Lsh;","U+021B0"
+"Lstrok;","U+00141"
+"Lt;","U+0226A"
+"Map;","U+02905"
+"Mcy;","U+0041C"
+"MediumSpace;","U+0205F"
+"Mellintrf;","U+02133"
+"Mfr;","U+1D510"
+"MinusPlus;","U+02213"
+"Mopf;","U+1D544"
+"Mscr;","U+02133"
+"Mu;","U+0039C"
+"NJcy;","U+0040A"
+"Nacute;","U+00143"
+"Ncaron;","U+00147"
+"Ncedil;","U+00145"
+"Ncy;","U+0041D"
+"NegativeMediumSpace;","U+0200B"
+"NegativeThickSpace;","U+0200B"
+"NegativeThinSpace;","U+0200B"
+"NegativeVeryThinSpace;","U+0200B"
+"NestedGreaterGreater;","U+0226B"
+"NestedLessLess;","U+0226A"
+"NewLine;","U+0000A"
+"Nfr;","U+1D511"
+"NoBreak;","U+02060"
+"NonBreakingSpace;","U+000A0"
+"Nopf;","U+02115"
+"Not;","U+02AEC"
+"NotCongruent;","U+02262"
+"NotCupCap;","U+0226D"
+"NotDoubleVerticalBar;","U+02226"
+"NotElement;","U+02209"
+"NotEqual;","U+02260"
+"NotExists;","U+02204"
+"NotGreater;","U+0226F"
+"NotGreaterEqual;","U+02271"
+"NotGreaterLess;","U+02279"
+"NotGreaterTilde;","U+02275"
+"NotLeftTriangle;","U+022EA"
+"NotLeftTriangleEqual;","U+022EC"
+"NotLess;","U+0226E"
+"NotLessEqual;","U+02270"
+"NotLessGreater;","U+02278"
+"NotLessTilde;","U+02274"
+"NotPrecedes;","U+02280"
+"NotPrecedesSlantEqual;","U+022E0"
+"NotReverseElement;","U+0220C"
+"NotRightTriangle;","U+022EB"
+"NotRightTriangleEqual;","U+022ED"
+"NotSquareSubsetEqual;","U+022E2"
+"NotSquareSupersetEqual;","U+022E3"
+"NotSubsetEqual;","U+02288"
+"NotSucceeds;","U+02281"
+"NotSucceedsSlantEqual;","U+022E1"
+"NotSupersetEqual;","U+02289"
+"NotTilde;","U+02241"
+"NotTildeEqual;","U+02244"
+"NotTildeFullEqual;","U+02247"
+"NotTildeTilde;","U+02249"
+"NotVerticalBar;","U+02224"
+"Nscr;","U+1D4A9"
+"Ntilde;","U+000D1"
+"Ntilde","U+000D1"
+"Nu;","U+0039D"
+"OElig;","U+00152"
+"Oacute;","U+000D3"
+"Oacute","U+000D3"
+"Ocirc;","U+000D4"
+"Ocirc","U+000D4"
+"Ocy;","U+0041E"
+"Odblac;","U+00150"
+"Ofr;","U+1D512"
+"Ograve;","U+000D2"
+"Ograve","U+000D2"
+"Omacr;","U+0014C"
+"Omega;","U+003A9"
+"Omicron;","U+0039F"
+"Oopf;","U+1D546"
+"OpenCurlyDoubleQuote;","U+0201C"
+"OpenCurlyQuote;","U+02018"
+"Or;","U+02A54"
+"Oscr;","U+1D4AA"
+"Oslash;","U+000D8"
+"Oslash","U+000D8"
+"Otilde;","U+000D5"
+"Otilde","U+000D5"
+"Otimes;","U+02A37"
+"Ouml;","U+000D6"
+"Ouml","U+000D6"
+"OverBar;","U+0203E"
+"OverBrace;","U+023DE"
+"OverBracket;","U+023B4"
+"OverParenthesis;","U+023DC"
+"PartialD;","U+02202"
+"Pcy;","U+0041F"
+"Pfr;","U+1D513"
+"Phi;","U+003A6"
+"Pi;","U+003A0"
+"PlusMinus;","U+000B1"
+"Poincareplane;","U+0210C"
+"Popf;","U+02119"
+"Pr;","U+02ABB"
+"Precedes;","U+0227A"
+"PrecedesEqual;","U+02AAF"
+"PrecedesSlantEqual;","U+0227C"
+"PrecedesTilde;","U+0227E"
+"Prime;","U+02033"
+"Product;","U+0220F"
+"Proportion;","U+02237"
+"Proportional;","U+0221D"
+"Pscr;","U+1D4AB"
+"Psi;","U+003A8"
+"QUOT;","U+00022"
+"QUOT","U+00022"
+"Qfr;","U+1D514"
+"Qopf;","U+0211A"
+"Qscr;","U+1D4AC"
+"RBarr;","U+02910"
+"REG;","U+000AE"
+"REG","U+000AE"
+"Racute;","U+00154"
+"Rang;","U+027EB"
+"Rarr;","U+021A0"
+"Rarrtl;","U+02916"
+"Rcaron;","U+00158"
+"Rcedil;","U+00156"
+"Rcy;","U+00420"
+"Re;","U+0211C"
+"ReverseElement;","U+0220B"
+"ReverseEquilibrium;","U+021CB"
+"ReverseUpEquilibrium;","U+0296F"
+"Rfr;","U+0211C"
+"Rho;","U+003A1"
+"RightAngleBracket;","U+027E9"
+"RightArrow;","U+02192"
+"RightArrowBar;","U+021E5"
+"RightArrowLeftArrow;","U+021C4"
+"RightCeiling;","U+02309"
+"RightDoubleBracket;","U+027E7"
+"RightDownTeeVector;","U+0295D"
+"RightDownVector;","U+021C2"
+"RightDownVectorBar;","U+02955"
+"RightFloor;","U+0230B"
+"RightTee;","U+022A2"
+"RightTeeArrow;","U+021A6"
+"RightTeeVector;","U+0295B"
+"RightTriangle;","U+022B3"
+"RightTriangleBar;","U+029D0"
+"RightTriangleEqual;","U+022B5"
+"RightUpDownVector;","U+0294F"
+"RightUpTeeVector;","U+0295C"
+"RightUpVector;","U+021BE"
+"RightUpVectorBar;","U+02954"
+"RightVector;","U+021C0"
+"RightVectorBar;","U+02953"
+"Rightarrow;","U+021D2"
+"Ropf;","U+0211D"
+"RoundImplies;","U+02970"
+"Rrightarrow;","U+021DB"
+"Rscr;","U+0211B"
+"Rsh;","U+021B1"
+"RuleDelayed;","U+029F4"
+"SHCHcy;","U+00429"
+"SHcy;","U+00428"
+"SOFTcy;","U+0042C"
+"Sacute;","U+0015A"
+"Sc;","U+02ABC"
+"Scaron;","U+00160"
+"Scedil;","U+0015E"
+"Scirc;","U+0015C"
+"Scy;","U+00421"
+"Sfr;","U+1D516"
+"ShortDownArrow;","U+02193"
+"ShortLeftArrow;","U+02190"
+"ShortRightArrow;","U+02192"
+"ShortUpArrow;","U+02191"
+"Sigma;","U+003A3"
+"SmallCircle;","U+02218"
+"Sopf;","U+1D54A"
+"Sqrt;","U+0221A"
+"Square;","U+025A1"
+"SquareIntersection;","U+02293"
+"SquareSubset;","U+0228F"
+"SquareSubsetEqual;","U+02291"
+"SquareSuperset;","U+02290"
+"SquareSupersetEqual;","U+02292"
+"SquareUnion;","U+02294"
+"Sscr;","U+1D4AE"
+"Star;","U+022C6"
+"Sub;","U+022D0"
+"Subset;","U+022D0"
+"SubsetEqual;","U+02286"
+"Succeeds;","U+0227B"
+"SucceedsEqual;","U+02AB0"
+"SucceedsSlantEqual;","U+0227D"
+"SucceedsTilde;","U+0227F"
+"SuchThat;","U+0220B"
+"Sum;","U+02211"
+"Sup;","U+022D1"
+"Superset;","U+02283"
+"SupersetEqual;","U+02287"
+"Supset;","U+022D1"
+"THORN;","U+000DE"
+"THORN","U+000DE"
+"TRADE;","U+02122"
+"TSHcy;","U+0040B"
+"TScy;","U+00426"
+"Tab;","U+00009"
+"Tau;","U+003A4"
+"Tcaron;","U+00164"
+"Tcedil;","U+00162"
+"Tcy;","U+00422"
+"Tfr;","U+1D517"
+"Therefore;","U+02234"
+"Theta;","U+00398"
+"ThinSpace;","U+02009"
+"Tilde;","U+0223C"
+"TildeEqual;","U+02243"
+"TildeFullEqual;","U+02245"
+"TildeTilde;","U+02248"
+"Topf;","U+1D54B"
+"TripleDot;","U+020DB"
+"Tscr;","U+1D4AF"
+"Tstrok;","U+00166"
+"Uacute;","U+000DA"
+"Uacute","U+000DA"
+"Uarr;","U+0219F"
+"Uarrocir;","U+02949"
+"Ubrcy;","U+0040E"
+"Ubreve;","U+0016C"
+"Ucirc;","U+000DB"
+"Ucirc","U+000DB"
+"Ucy;","U+00423"
+"Udblac;","U+00170"
+"Ufr;","U+1D518"
+"Ugrave;","U+000D9"
+"Ugrave","U+000D9"
+"Umacr;","U+0016A"
+"UnderBar;","U+0005F"
+"UnderBrace;","U+023DF"
+"UnderBracket;","U+023B5"
+"UnderParenthesis;","U+023DD"
+"Union;","U+022C3"
+"UnionPlus;","U+0228E"
+"Uogon;","U+00172"
+"Uopf;","U+1D54C"
+"UpArrow;","U+02191"
+"UpArrowBar;","U+02912"
+"UpArrowDownArrow;","U+021C5"
+"UpDownArrow;","U+02195"
+"UpEquilibrium;","U+0296E"
+"UpTee;","U+022A5"
+"UpTeeArrow;","U+021A5"
+"Uparrow;","U+021D1"
+"Updownarrow;","U+021D5"
+"UpperLeftArrow;","U+02196"
+"UpperRightArrow;","U+02197"
+"Upsi;","U+003D2"
+"Upsilon;","U+003A5"
+"Uring;","U+0016E"
+"Uscr;","U+1D4B0"
+"Utilde;","U+00168"
+"Uuml;","U+000DC"
+"Uuml","U+000DC"
+"VDash;","U+022AB"
+"Vbar;","U+02AEB"
+"Vcy;","U+00412"
+"Vdash;","U+022A9"
+"Vdashl;","U+02AE6"
+"Vee;","U+022C1"
+"Verbar;","U+02016"
+"Vert;","U+02016"
+"VerticalBar;","U+02223"
+"VerticalLine;","U+0007C"
+"VerticalSeparator;","U+02758"
+"VerticalTilde;","U+02240"
+"VeryThinSpace;","U+0200A"
+"Vfr;","U+1D519"
+"Vopf;","U+1D54D"
+"Vscr;","U+1D4B1"
+"Vvdash;","U+022AA"
+"Wcirc;","U+00174"
+"Wedge;","U+022C0"
+"Wfr;","U+1D51A"
+"Wopf;","U+1D54E"
+"Wscr;","U+1D4B2"
+"Xfr;","U+1D51B"
+"Xi;","U+0039E"
+"Xopf;","U+1D54F"
+"Xscr;","U+1D4B3"
+"YAcy;","U+0042F"
+"YIcy;","U+00407"
+"YUcy;","U+0042E"
+"Yacute;","U+000DD"
+"Yacute","U+000DD"
+"Ycirc;","U+00176"
+"Ycy;","U+0042B"
+"Yfr;","U+1D51C"
+"Yopf;","U+1D550"
+"Yscr;","U+1D4B4"
+"Yuml;","U+00178"
+"ZHcy;","U+00416"
+"Zacute;","U+00179"
+"Zcaron;","U+0017D"
+"Zcy;","U+00417"
+"Zdot;","U+0017B"
+"ZeroWidthSpace;","U+0200B"
+"Zeta;","U+00396"
+"Zfr;","U+02128"
+"Zopf;","U+02124"
+"Zscr;","U+1D4B5"
+"aacute;","U+000E1"
+"aacute","U+000E1"
+"abreve;","U+00103"
+"ac;","U+0223E"
+"acd;","U+0223F"
+"acirc;","U+000E2"
+"acirc","U+000E2"
+"acute;","U+000B4"
+"acute","U+000B4"
+"acy;","U+00430"
+"aelig;","U+000E6"
+"aelig","U+000E6"
+"af;","U+02061"
+"afr;","U+1D51E"
+"agrave;","U+000E0"
+"agrave","U+000E0"
+"alefsym;","U+02135"
+"aleph;","U+02135"
+"alpha;","U+003B1"
+"amacr;","U+00101"
+"amalg;","U+02A3F"
+"amp;","U+00026"
+"amp","U+00026"
+"and;","U+02227"
+"andand;","U+02A55"
+"andd;","U+02A5C"
+"andslope;","U+02A58"
+"andv;","U+02A5A"
+"ang;","U+02220"
+"ange;","U+029A4"
+"angle;","U+02220"
+"angmsd;","U+02221"
+"angmsdaa;","U+029A8"
+"angmsdab;","U+029A9"
+"angmsdac;","U+029AA"
+"angmsdad;","U+029AB"
+"angmsdae;","U+029AC"
+"angmsdaf;","U+029AD"
+"angmsdag;","U+029AE"
+"angmsdah;","U+029AF"
+"angrt;","U+0221F"
+"angrtvb;","U+022BE"
+"angrtvbd;","U+0299D"
+"angsph;","U+02222"
+"angst;","U+000C5"
+"angzarr;","U+0237C"
+"aogon;","U+00105"
+"aopf;","U+1D552"
+"ap;","U+02248"
+"apE;","U+02A70"
+"apacir;","U+02A6F"
+"ape;","U+0224A"
+"apid;","U+0224B"
+"apos;","U+00027"
+"approx;","U+02248"
+"approxeq;","U+0224A"
+"aring;","U+000E5"
+"aring","U+000E5"
+"ascr;","U+1D4B6"
+"ast;","U+0002A"
+"asymp;","U+02248"
+"asympeq;","U+0224D"
+"atilde;","U+000E3"
+"atilde","U+000E3"
+"auml;","U+000E4"
+"auml","U+000E4"
+"awconint;","U+02233"
+"awint;","U+02A11"
+"bNot;","U+02AED"
+"backcong;","U+0224C"
+"backepsilon;","U+003F6"
+"backprime;","U+02035"
+"backsim;","U+0223D"
+"backsimeq;","U+022CD"
+"barvee;","U+022BD"
+"barwed;","U+02305"
+"barwedge;","U+02305"
+"bbrk;","U+023B5"
+"bbrktbrk;","U+023B6"
+"bcong;","U+0224C"
+"bcy;","U+00431"
+"bdquo;","U+0201E"
+"becaus;","U+02235"
+"because;","U+02235"
+"bemptyv;","U+029B0"
+"bepsi;","U+003F6"
+"bernou;","U+0212C"
+"beta;","U+003B2"
+"beth;","U+02136"
+"between;","U+0226C"
+"bfr;","U+1D51F"
+"bigcap;","U+022C2"
+"bigcirc;","U+025EF"
+"bigcup;","U+022C3"
+"bigodot;","U+02A00"
+"bigoplus;","U+02A01"
+"bigotimes;","U+02A02"
+"bigsqcup;","U+02A06"
+"bigstar;","U+02605"
+"bigtriangledown;","U+025BD"
+"bigtriangleup;","U+025B3"
+"biguplus;","U+02A04"
+"bigvee;","U+022C1"
+"bigwedge;","U+022C0"
+"bkarow;","U+0290D"
+"blacklozenge;","U+029EB"
+"blacksquare;","U+025AA"
+"blacktriangle;","U+025B4"
+"blacktriangledown;","U+025BE"
+"blacktriangleleft;","U+025C2"
+"blacktriangleright;","U+025B8"
+"blank;","U+02423"
+"blk12;","U+02592"
+"blk14;","U+02591"
+"blk34;","U+02593"
+"block;","U+02588"
+"bnot;","U+02310"
+"bopf;","U+1D553"
+"bot;","U+022A5"
+"bottom;","U+022A5"
+"bowtie;","U+022C8"
+"boxDL;","U+02557"
+"boxDR;","U+02554"
+"boxDl;","U+02556"
+"boxDr;","U+02553"
+"boxH;","U+02550"
+"boxHD;","U+02566"
+"boxHU;","U+02569"
+"boxHd;","U+02564"
+"boxHu;","U+02567"
+"boxUL;","U+0255D"
+"boxUR;","U+0255A"
+"boxUl;","U+0255C"
+"boxUr;","U+02559"
+"boxV;","U+02551"
+"boxVH;","U+0256C"
+"boxVL;","U+02563"
+"boxVR;","U+02560"
+"boxVh;","U+0256B"
+"boxVl;","U+02562"
+"boxVr;","U+0255F"
+"boxbox;","U+029C9"
+"boxdL;","U+02555"
+"boxdR;","U+02552"
+"boxdl;","U+02510"
+"boxdr;","U+0250C"
+"boxh;","U+02500"
+"boxhD;","U+02565"
+"boxhU;","U+02568"
+"boxhd;","U+0252C"
+"boxhu;","U+02534"
+"boxminus;","U+0229F"
+"boxplus;","U+0229E"
+"boxtimes;","U+022A0"
+"boxuL;","U+0255B"
+"boxuR;","U+02558"
+"boxul;","U+02518"
+"boxur;","U+02514"
+"boxv;","U+02502"
+"boxvH;","U+0256A"
+"boxvL;","U+02561"
+"boxvR;","U+0255E"
+"boxvh;","U+0253C"
+"boxvl;","U+02524"
+"boxvr;","U+0251C"
+"bprime;","U+02035"
+"breve;","U+002D8"
+"brvbar;","U+000A6"
+"brvbar","U+000A6"
+"bscr;","U+1D4B7"
+"bsemi;","U+0204F"
+"bsim;","U+0223D"
+"bsime;","U+022CD"
+"bsol;","U+0005C"
+"bsolb;","U+029C5"
+"bsolhsub;","U+027C8"
+"bull;","U+02022"
+"bullet;","U+02022"
+"bump;","U+0224E"
+"bumpE;","U+02AAE"
+"bumpe;","U+0224F"
+"bumpeq;","U+0224F"
+"cacute;","U+00107"
+"cap;","U+02229"
+"capand;","U+02A44"
+"capbrcup;","U+02A49"
+"capcap;","U+02A4B"
+"capcup;","U+02A47"
+"capdot;","U+02A40"
+"caret;","U+02041"
+"caron;","U+002C7"
+"ccaps;","U+02A4D"
+"ccaron;","U+0010D"
+"ccedil;","U+000E7"
+"ccedil","U+000E7"
+"ccirc;","U+00109"
+"ccups;","U+02A4C"
+"ccupssm;","U+02A50"
+"cdot;","U+0010B"
+"cedil;","U+000B8"
+"cedil","U+000B8"
+"cemptyv;","U+029B2"
+"cent;","U+000A2"
+"cent","U+000A2"
+"centerdot;","U+000B7"
+"cfr;","U+1D520"
+"chcy;","U+00447"
+"check;","U+02713"
+"checkmark;","U+02713"
+"chi;","U+003C7"
+"cir;","U+025CB"
+"cirE;","U+029C3"
+"circ;","U+002C6"
+"circeq;","U+02257"
+"circlearrowleft;","U+021BA"
+"circlearrowright;","U+021BB"
+"circledR;","U+000AE"
+"circledS;","U+024C8"
+"circledast;","U+0229B"
+"circledcirc;","U+0229A"
+"circleddash;","U+0229D"
+"cire;","U+02257"
+"cirfnint;","U+02A10"
+"cirmid;","U+02AEF"
+"cirscir;","U+029C2"
+"clubs;","U+02663"
+"clubsuit;","U+02663"
+"colon;","U+0003A"
+"colone;","U+02254"
+"coloneq;","U+02254"
+"comma;","U+0002C"
+"commat;","U+00040"
+"comp;","U+02201"
+"compfn;","U+02218"
+"complement;","U+02201"
+"complexes;","U+02102"
+"cong;","U+02245"
+"congdot;","U+02A6D"
+"conint;","U+0222E"
+"copf;","U+1D554"
+"coprod;","U+02210"
+"copy;","U+000A9"
+"copy","U+000A9"
+"copysr;","U+02117"
+"crarr;","U+021B5"
+"cross;","U+02717"
+"cscr;","U+1D4B8"
+"csub;","U+02ACF"
+"csube;","U+02AD1"
+"csup;","U+02AD0"
+"csupe;","U+02AD2"
+"ctdot;","U+022EF"
+"cudarrl;","U+02938"
+"cudarrr;","U+02935"
+"cuepr;","U+022DE"
+"cuesc;","U+022DF"
+"cularr;","U+021B6"
+"cularrp;","U+0293D"
+"cup;","U+0222A"
+"cupbrcap;","U+02A48"
+"cupcap;","U+02A46"
+"cupcup;","U+02A4A"
+"cupdot;","U+0228D"
+"cupor;","U+02A45"
+"curarr;","U+021B7"
+"curarrm;","U+0293C"
+"curlyeqprec;","U+022DE"
+"curlyeqsucc;","U+022DF"
+"curlyvee;","U+022CE"
+"curlywedge;","U+022CF"
+"curren;","U+000A4"
+"curren","U+000A4"
+"curvearrowleft;","U+021B6"
+"curvearrowright;","U+021B7"
+"cuvee;","U+022CE"
+"cuwed;","U+022CF"
+"cwconint;","U+02232"
+"cwint;","U+02231"
+"cylcty;","U+0232D"
+"dArr;","U+021D3"
+"dHar;","U+02965"
+"dagger;","U+02020"
+"daleth;","U+02138"
+"darr;","U+02193"
+"dash;","U+02010"
+"dashv;","U+022A3"
+"dbkarow;","U+0290F"
+"dblac;","U+002DD"
+"dcaron;","U+0010F"
+"dcy;","U+00434"
+"dd;","U+02146"
+"ddagger;","U+02021"
+"ddarr;","U+021CA"
+"ddotseq;","U+02A77"
+"deg;","U+000B0"
+"deg","U+000B0"
+"delta;","U+003B4"
+"demptyv;","U+029B1"
+"dfisht;","U+0297F"
+"dfr;","U+1D521"
+"dharl;","U+021C3"
+"dharr;","U+021C2"
+"diam;","U+022C4"
+"diamond;","U+022C4"
+"diamondsuit;","U+02666"
+"diams;","U+02666"
+"die;","U+000A8"
+"digamma;","U+003DD"
+"disin;","U+022F2"
+"div;","U+000F7"
+"divide;","U+000F7"
+"divide","U+000F7"
+"divideontimes;","U+022C7"
+"divonx;","U+022C7"
+"djcy;","U+00452"
+"dlcorn;","U+0231E"
+"dlcrop;","U+0230D"
+"dollar;","U+00024"
+"dopf;","U+1D555"
+"dot;","U+002D9"
+"doteq;","U+02250"
+"doteqdot;","U+02251"
+"dotminus;","U+02238"
+"dotplus;","U+02214"
+"dotsquare;","U+022A1"
+"doublebarwedge;","U+02306"
+"downarrow;","U+02193"
+"downdownarrows;","U+021CA"
+"downharpoonleft;","U+021C3"
+"downharpoonright;","U+021C2"
+"drbkarow;","U+02910"
+"drcorn;","U+0231F"
+"drcrop;","U+0230C"
+"dscr;","U+1D4B9"
+"dscy;","U+00455"
+"dsol;","U+029F6"
+"dstrok;","U+00111"
+"dtdot;","U+022F1"
+"dtri;","U+025BF"
+"dtrif;","U+025BE"
+"duarr;","U+021F5"
+"duhar;","U+0296F"
+"dwangle;","U+029A6"
+"dzcy;","U+0045F"
+"dzigrarr;","U+027FF"
+"eDDot;","U+02A77"
+"eDot;","U+02251"
+"eacute;","U+000E9"
+"eacute","U+000E9"
+"easter;","U+02A6E"
+"ecaron;","U+0011B"
+"ecir;","U+02256"
+"ecirc;","U+000EA"
+"ecirc","U+000EA"
+"ecolon;","U+02255"
+"ecy;","U+0044D"
+"edot;","U+00117"
+"ee;","U+02147"
+"efDot;","U+02252"
+"efr;","U+1D522"
+"eg;","U+02A9A"
+"egrave;","U+000E8"
+"egrave","U+000E8"
+"egs;","U+02A96"
+"egsdot;","U+02A98"
+"el;","U+02A99"
+"elinters;","U+023E7"
+"ell;","U+02113"
+"els;","U+02A95"
+"elsdot;","U+02A97"
+"emacr;","U+00113"
+"empty;","U+02205"
+"emptyset;","U+02205"
+"emptyv;","U+02205"
+"emsp13;","U+02004"
+"emsp14;","U+02005"
+"emsp;","U+02003"
+"eng;","U+0014B"
+"ensp;","U+02002"
+"eogon;","U+00119"
+"eopf;","U+1D556"
+"epar;","U+022D5"
+"eparsl;","U+029E3"
+"eplus;","U+02A71"
+"epsi;","U+003B5"
+"epsilon;","U+003B5"
+"epsiv;","U+003F5"
+"eqcirc;","U+02256"
+"eqcolon;","U+02255"
+"eqsim;","U+02242"
+"eqslantgtr;","U+02A96"
+"eqslantless;","U+02A95"
+"equals;","U+0003D"
+"equest;","U+0225F"
+"equiv;","U+02261"
+"equivDD;","U+02A78"
+"eqvparsl;","U+029E5"
+"erDot;","U+02253"
+"erarr;","U+02971"
+"escr;","U+0212F"
+"esdot;","U+02250"
+"esim;","U+02242"
+"eta;","U+003B7"
+"eth;","U+000F0"
+"eth","U+000F0"
+"euml;","U+000EB"
+"euml","U+000EB"
+"euro;","U+020AC"
+"excl;","U+00021"
+"exist;","U+02203"
+"expectation;","U+02130"
+"exponentiale;","U+02147"
+"fallingdotseq;","U+02252"
+"fcy;","U+00444"
+"female;","U+02640"
+"ffilig;","U+0FB03"
+"fflig;","U+0FB00"
+"ffllig;","U+0FB04"
+"ffr;","U+1D523"
+"filig;","U+0FB01"
+"flat;","U+0266D"
+"fllig;","U+0FB02"
+"fltns;","U+025B1"
+"fnof;","U+00192"
+"fopf;","U+1D557"
+"forall;","U+02200"
+"fork;","U+022D4"
+"forkv;","U+02AD9"
+"fpartint;","U+02A0D"
+"frac12;","U+000BD"
+"frac12","U+000BD"
+"frac13;","U+02153"
+"frac14;","U+000BC"
+"frac14","U+000BC"
+"frac15;","U+02155"
+"frac16;","U+02159"
+"frac18;","U+0215B"
+"frac23;","U+02154"
+"frac25;","U+02156"
+"frac34;","U+000BE"
+"frac34","U+000BE"
+"frac35;","U+02157"
+"frac38;","U+0215C"
+"frac45;","U+02158"
+"frac56;","U+0215A"
+"frac58;","U+0215D"
+"frac78;","U+0215E"
+"frasl;","U+02044"
+"frown;","U+02322"
+"fscr;","U+1D4BB"
+"gE;","U+02267"
+"gEl;","U+02A8C"
+"gacute;","U+001F5"
+"gamma;","U+003B3"
+"gammad;","U+003DD"
+"gap;","U+02A86"
+"gbreve;","U+0011F"
+"gcirc;","U+0011D"
+"gcy;","U+00433"
+"gdot;","U+00121"
+"ge;","U+02265"
+"gel;","U+022DB"
+"geq;","U+02265"
+"geqq;","U+02267"
+"geqslant;","U+02A7E"
+"ges;","U+02A7E"
+"gescc;","U+02AA9"
+"gesdot;","U+02A80"
+"gesdoto;","U+02A82"
+"gesdotol;","U+02A84"
+"gesles;","U+02A94"
+"gfr;","U+1D524"
+"gg;","U+0226B"
+"ggg;","U+022D9"
+"gimel;","U+02137"
+"gjcy;","U+00453"
+"gl;","U+02277"
+"glE;","U+02A92"
+"gla;","U+02AA5"
+"glj;","U+02AA4"
+"gnE;","U+02269"
+"gnap;","U+02A8A"
+"gnapprox;","U+02A8A"
+"gne;","U+02A88"
+"gneq;","U+02A88"
+"gneqq;","U+02269"
+"gnsim;","U+022E7"
+"gopf;","U+1D558"
+"grave;","U+00060"
+"gscr;","U+0210A"
+"gsim;","U+02273"
+"gsime;","U+02A8E"
+"gsiml;","U+02A90"
+"gt;","U+0003E"
+"gt","U+0003E"
+"gtcc;","U+02AA7"
+"gtcir;","U+02A7A"
+"gtdot;","U+022D7"
+"gtlPar;","U+02995"
+"gtquest;","U+02A7C"
+"gtrapprox;","U+02A86"
+"gtrarr;","U+02978"
+"gtrdot;","U+022D7"
+"gtreqless;","U+022DB"
+"gtreqqless;","U+02A8C"
+"gtrless;","U+02277"
+"gtrsim;","U+02273"
+"hArr;","U+021D4"
+"hairsp;","U+0200A"
+"half;","U+000BD"
+"hamilt;","U+0210B"
+"hardcy;","U+0044A"
+"harr;","U+02194"
+"harrcir;","U+02948"
+"harrw;","U+021AD"
+"hbar;","U+0210F"
+"hcirc;","U+00125"
+"hearts;","U+02665"
+"heartsuit;","U+02665"
+"hellip;","U+02026"
+"hercon;","U+022B9"
+"hfr;","U+1D525"
+"hksearow;","U+02925"
+"hkswarow;","U+02926"
+"hoarr;","U+021FF"
+"homtht;","U+0223B"
+"hookleftarrow;","U+021A9"
+"hookrightarrow;","U+021AA"
+"hopf;","U+1D559"
+"horbar;","U+02015"
+"hscr;","U+1D4BD"
+"hslash;","U+0210F"
+"hstrok;","U+00127"
+"hybull;","U+02043"
+"hyphen;","U+02010"
+"iacute;","U+000ED"
+"iacute","U+000ED"
+"ic;","U+02063"
+"icirc;","U+000EE"
+"icirc","U+000EE"
+"icy;","U+00438"
+"iecy;","U+00435"
+"iexcl;","U+000A1"
+"iexcl","U+000A1"
+"iff;","U+021D4"
+"ifr;","U+1D526"
+"igrave;","U+000EC"
+"igrave","U+000EC"
+"ii;","U+02148"
+"iiiint;","U+02A0C"
+"iiint;","U+0222D"
+"iinfin;","U+029DC"
+"iiota;","U+02129"
+"ijlig;","U+00133"
+"imacr;","U+0012B"
+"image;","U+02111"
+"imagline;","U+02110"
+"imagpart;","U+02111"
+"imath;","U+00131"
+"imof;","U+022B7"
+"imped;","U+001B5"
+"in;","U+02208"
+"incare;","U+02105"
+"infin;","U+0221E"
+"infintie;","U+029DD"
+"inodot;","U+00131"
+"int;","U+0222B"
+"intcal;","U+022BA"
+"integers;","U+02124"
+"intercal;","U+022BA"
+"intlarhk;","U+02A17"
+"intprod;","U+02A3C"
+"iocy;","U+00451"
+"iogon;","U+0012F"
+"iopf;","U+1D55A"
+"iota;","U+003B9"
+"iprod;","U+02A3C"
+"iquest;","U+000BF"
+"iquest","U+000BF"
+"iscr;","U+1D4BE"
+"isin;","U+02208"
+"isinE;","U+022F9"
+"isindot;","U+022F5"
+"isins;","U+022F4"
+"isinsv;","U+022F3"
+"isinv;","U+02208"
+"it;","U+02062"
+"itilde;","U+00129"
+"iukcy;","U+00456"
+"iuml;","U+000EF"
+"iuml","U+000EF"
+"jcirc;","U+00135"
+"jcy;","U+00439"
+"jfr;","U+1D527"
+"jmath;","U+00237"
+"jopf;","U+1D55B"
+"jscr;","U+1D4BF"
+"jsercy;","U+00458"
+"jukcy;","U+00454"
+"kappa;","U+003BA"
+"kappav;","U+003F0"
+"kcedil;","U+00137"
+"kcy;","U+0043A"
+"kfr;","U+1D528"
+"kgreen;","U+00138"
+"khcy;","U+00445"
+"kjcy;","U+0045C"
+"kopf;","U+1D55C"
+"kscr;","U+1D4C0"
+"lAarr;","U+021DA"
+"lArr;","U+021D0"
+"lAtail;","U+0291B"
+"lBarr;","U+0290E"
+"lE;","U+02266"
+"lEg;","U+02A8B"
+"lHar;","U+02962"
+"lacute;","U+0013A"
+"laemptyv;","U+029B4"
+"lagran;","U+02112"
+"lambda;","U+003BB"
+"lang;","U+027E8"
+"langd;","U+02991"
+"langle;","U+027E8"
+"lap;","U+02A85"
+"laquo;","U+000AB"
+"laquo","U+000AB"
+"larr;","U+02190"
+"larrb;","U+021E4"
+"larrbfs;","U+0291F"
+"larrfs;","U+0291D"
+"larrhk;","U+021A9"
+"larrlp;","U+021AB"
+"larrpl;","U+02939"
+"larrsim;","U+02973"
+"larrtl;","U+021A2"
+"lat;","U+02AAB"
+"latail;","U+02919"
+"late;","U+02AAD"
+"lbarr;","U+0290C"
+"lbbrk;","U+02772"
+"lbrace;","U+0007B"
+"lbrack;","U+0005B"
+"lbrke;","U+0298B"
+"lbrksld;","U+0298F"
+"lbrkslu;","U+0298D"
+"lcaron;","U+0013E"
+"lcedil;","U+0013C"
+"lceil;","U+02308"
+"lcub;","U+0007B"
+"lcy;","U+0043B"
+"ldca;","U+02936"
+"ldquo;","U+0201C"
+"ldquor;","U+0201E"
+"ldrdhar;","U+02967"
+"ldrushar;","U+0294B"
+"ldsh;","U+021B2"
+"le;","U+02264"
+"leftarrow;","U+02190"
+"leftarrowtail;","U+021A2"
+"leftharpoondown;","U+021BD"
+"leftharpoonup;","U+021BC"
+"leftleftarrows;","U+021C7"
+"leftrightarrow;","U+02194"
+"leftrightarrows;","U+021C6"
+"leftrightharpoons;","U+021CB"
+"leftrightsquigarrow;","U+021AD"
+"leftthreetimes;","U+022CB"
+"leg;","U+022DA"
+"leq;","U+02264"
+"leqq;","U+02266"
+"leqslant;","U+02A7D"
+"les;","U+02A7D"
+"lescc;","U+02AA8"
+"lesdot;","U+02A7F"
+"lesdoto;","U+02A81"
+"lesdotor;","U+02A83"
+"lesges;","U+02A93"
+"lessapprox;","U+02A85"
+"lessdot;","U+022D6"
+"lesseqgtr;","U+022DA"
+"lesseqqgtr;","U+02A8B"
+"lessgtr;","U+02276"
+"lesssim;","U+02272"
+"lfisht;","U+0297C"
+"lfloor;","U+0230A"
+"lfr;","U+1D529"
+"lg;","U+02276"
+"lgE;","U+02A91"
+"lhard;","U+021BD"
+"lharu;","U+021BC"
+"lharul;","U+0296A"
+"lhblk;","U+02584"
+"ljcy;","U+00459"
+"ll;","U+0226A"
+"llarr;","U+021C7"
+"llcorner;","U+0231E"
+"llhard;","U+0296B"
+"lltri;","U+025FA"
+"lmidot;","U+00140"
+"lmoust;","U+023B0"
+"lmoustache;","U+023B0"
+"lnE;","U+02268"
+"lnap;","U+02A89"
+"lnapprox;","U+02A89"
+"lne;","U+02A87"
+"lneq;","U+02A87"
+"lneqq;","U+02268"
+"lnsim;","U+022E6"
+"loang;","U+027EC"
+"loarr;","U+021FD"
+"lobrk;","U+027E6"
+"longleftarrow;","U+027F5"
+"longleftrightarrow;","U+027F7"
+"longmapsto;","U+027FC"
+"longrightarrow;","U+027F6"
+"looparrowleft;","U+021AB"
+"looparrowright;","U+021AC"
+"lopar;","U+02985"
+"lopf;","U+1D55D"
+"loplus;","U+02A2D"
+"lotimes;","U+02A34"
+"lowast;","U+02217"
+"lowbar;","U+0005F"
+"loz;","U+025CA"
+"lozenge;","U+025CA"
+"lozf;","U+029EB"
+"lpar;","U+00028"
+"lparlt;","U+02993"
+"lrarr;","U+021C6"
+"lrcorner;","U+0231F"
+"lrhar;","U+021CB"
+"lrhard;","U+0296D"
+"lrm;","U+0200E"
+"lrtri;","U+022BF"
+"lsaquo;","U+02039"
+"lscr;","U+1D4C1"
+"lsh;","U+021B0"
+"lsim;","U+02272"
+"lsime;","U+02A8D"
+"lsimg;","U+02A8F"
+"lsqb;","U+0005B"
+"lsquo;","U+02018"
+"lsquor;","U+0201A"
+"lstrok;","U+00142"
+"lt;","U+0003C"
+"lt","U+0003C"
+"ltcc;","U+02AA6"
+"ltcir;","U+02A79"
+"ltdot;","U+022D6"
+"lthree;","U+022CB"
+"ltimes;","U+022C9"
+"ltlarr;","U+02976"
+"ltquest;","U+02A7B"
+"ltrPar;","U+02996"
+"ltri;","U+025C3"
+"ltrie;","U+022B4"
+"ltrif;","U+025C2"
+"lurdshar;","U+0294A"
+"luruhar;","U+02966"
+"mDDot;","U+0223A"
+"macr;","U+000AF"
+"macr","U+000AF"
+"male;","U+02642"
+"malt;","U+02720"
+"maltese;","U+02720"
+"map;","U+021A6"
+"mapsto;","U+021A6"
+"mapstodown;","U+021A7"
+"mapstoleft;","U+021A4"
+"mapstoup;","U+021A5"
+"marker;","U+025AE"
+"mcomma;","U+02A29"
+"mcy;","U+0043C"
+"mdash;","U+02014"
+"measuredangle;","U+02221"
+"mfr;","U+1D52A"
+"mho;","U+02127"
+"micro;","U+000B5"
+"micro","U+000B5"
+"mid;","U+02223"
+"midast;","U+0002A"
+"midcir;","U+02AF0"
+"middot;","U+000B7"
+"middot","U+000B7"
+"minus;","U+02212"
+"minusb;","U+0229F"
+"minusd;","U+02238"
+"minusdu;","U+02A2A"
+"mlcp;","U+02ADB"
+"mldr;","U+02026"
+"mnplus;","U+02213"
+"models;","U+022A7"
+"mopf;","U+1D55E"
+"mp;","U+02213"
+"mscr;","U+1D4C2"
+"mstpos;","U+0223E"
+"mu;","U+003BC"
+"multimap;","U+022B8"
+"mumap;","U+022B8"
+"nLeftarrow;","U+021CD"
+"nLeftrightarrow;","U+021CE"
+"nRightarrow;","U+021CF"
+"nVDash;","U+022AF"
+"nVdash;","U+022AE"
+"nabla;","U+02207"
+"nacute;","U+00144"
+"nap;","U+02249"
+"napos;","U+00149"
+"napprox;","U+02249"
+"natur;","U+0266E"
+"natural;","U+0266E"
+"naturals;","U+02115"
+"nbsp;","U+000A0"
+"nbsp","U+000A0"
+"ncap;","U+02A43"
+"ncaron;","U+00148"
+"ncedil;","U+00146"
+"ncong;","U+02247"
+"ncup;","U+02A42"
+"ncy;","U+0043D"
+"ndash;","U+02013"
+"ne;","U+02260"
+"neArr;","U+021D7"
+"nearhk;","U+02924"
+"nearr;","U+02197"
+"nearrow;","U+02197"
+"nequiv;","U+02262"
+"nesear;","U+02928"
+"nexist;","U+02204"
+"nexists;","U+02204"
+"nfr;","U+1D52B"
+"nge;","U+02271"
+"ngeq;","U+02271"
+"ngsim;","U+02275"
+"ngt;","U+0226F"
+"ngtr;","U+0226F"
+"nhArr;","U+021CE"
+"nharr;","U+021AE"
+"nhpar;","U+02AF2"
+"ni;","U+0220B"
+"nis;","U+022FC"
+"nisd;","U+022FA"
+"niv;","U+0220B"
+"njcy;","U+0045A"
+"nlArr;","U+021CD"
+"nlarr;","U+0219A"
+"nldr;","U+02025"
+"nle;","U+02270"
+"nleftarrow;","U+0219A"
+"nleftrightarrow;","U+021AE"
+"nleq;","U+02270"
+"nless;","U+0226E"
+"nlsim;","U+02274"
+"nlt;","U+0226E"
+"nltri;","U+022EA"
+"nltrie;","U+022EC"
+"nmid;","U+02224"
+"nopf;","U+1D55F"
+"not;","U+000AC"
+"not","U+000AC"
+"notin;","U+02209"
+"notinva;","U+02209"
+"notinvb;","U+022F7"
+"notinvc;","U+022F6"
+"notni;","U+0220C"
+"notniva;","U+0220C"
+"notnivb;","U+022FE"
+"notnivc;","U+022FD"
+"npar;","U+02226"
+"nparallel;","U+02226"
+"npolint;","U+02A14"
+"npr;","U+02280"
+"nprcue;","U+022E0"
+"nprec;","U+02280"
+"nrArr;","U+021CF"
+"nrarr;","U+0219B"
+"nrightarrow;","U+0219B"
+"nrtri;","U+022EB"
+"nrtrie;","U+022ED"
+"nsc;","U+02281"
+"nsccue;","U+022E1"
+"nscr;","U+1D4C3"
+"nshortmid;","U+02224"
+"nshortparallel;","U+02226"
+"nsim;","U+02241"
+"nsime;","U+02244"
+"nsimeq;","U+02244"
+"nsmid;","U+02224"
+"nspar;","U+02226"
+"nsqsube;","U+022E2"
+"nsqsupe;","U+022E3"
+"nsub;","U+02284"
+"nsube;","U+02288"
+"nsubseteq;","U+02288"
+"nsucc;","U+02281"
+"nsup;","U+02285"
+"nsupe;","U+02289"
+"nsupseteq;","U+02289"
+"ntgl;","U+02279"
+"ntilde;","U+000F1"
+"ntilde","U+000F1"
+"ntlg;","U+02278"
+"ntriangleleft;","U+022EA"
+"ntrianglelefteq;","U+022EC"
+"ntriangleright;","U+022EB"
+"ntrianglerighteq;","U+022ED"
+"nu;","U+003BD"
+"num;","U+00023"
+"numero;","U+02116"
+"numsp;","U+02007"
+"nvDash;","U+022AD"
+"nvHarr;","U+02904"
+"nvdash;","U+022AC"
+"nvinfin;","U+029DE"
+"nvlArr;","U+02902"
+"nvrArr;","U+02903"
+"nwArr;","U+021D6"
+"nwarhk;","U+02923"
+"nwarr;","U+02196"
+"nwarrow;","U+02196"
+"nwnear;","U+02927"
+"oS;","U+024C8"
+"oacute;","U+000F3"
+"oacute","U+000F3"
+"oast;","U+0229B"
+"ocir;","U+0229A"
+"ocirc;","U+000F4"
+"ocirc","U+000F4"
+"ocy;","U+0043E"
+"odash;","U+0229D"
+"odblac;","U+00151"
+"odiv;","U+02A38"
+"odot;","U+02299"
+"odsold;","U+029BC"
+"oelig;","U+00153"
+"ofcir;","U+029BF"
+"ofr;","U+1D52C"
+"ogon;","U+002DB"
+"ograve;","U+000F2"
+"ograve","U+000F2"
+"ogt;","U+029C1"
+"ohbar;","U+029B5"
+"ohm;","U+003A9"
+"oint;","U+0222E"
+"olarr;","U+021BA"
+"olcir;","U+029BE"
+"olcross;","U+029BB"
+"oline;","U+0203E"
+"olt;","U+029C0"
+"omacr;","U+0014D"
+"omega;","U+003C9"
+"omicron;","U+003BF"
+"omid;","U+029B6"
+"ominus;","U+02296"
+"oopf;","U+1D560"
+"opar;","U+029B7"
+"operp;","U+029B9"
+"oplus;","U+02295"
+"or;","U+02228"
+"orarr;","U+021BB"
+"ord;","U+02A5D"
+"order;","U+02134"
+"orderof;","U+02134"
+"ordf;","U+000AA"
+"ordf","U+000AA"
+"ordm;","U+000BA"
+"ordm","U+000BA"
+"origof;","U+022B6"
+"oror;","U+02A56"
+"orslope;","U+02A57"
+"orv;","U+02A5B"
+"oscr;","U+02134"
+"oslash;","U+000F8"
+"oslash","U+000F8"
+"osol;","U+02298"
+"otilde;","U+000F5"
+"otilde","U+000F5"
+"otimes;","U+02297"
+"otimesas;","U+02A36"
+"ouml;","U+000F6"
+"ouml","U+000F6"
+"ovbar;","U+0233D"
+"par;","U+02225"
+"para;","U+000B6"
+"para","U+000B6"
+"parallel;","U+02225"
+"parsim;","U+02AF3"
+"parsl;","U+02AFD"
+"part;","U+02202"
+"pcy;","U+0043F"
+"percnt;","U+00025"
+"period;","U+0002E"
+"permil;","U+02030"
+"perp;","U+022A5"
+"pertenk;","U+02031"
+"pfr;","U+1D52D"
+"phi;","U+003C6"
+"phiv;","U+003D5"
+"phmmat;","U+02133"
+"phone;","U+0260E"
+"pi;","U+003C0"
+"pitchfork;","U+022D4"
+"piv;","U+003D6"
+"planck;","U+0210F"
+"planckh;","U+0210E"
+"plankv;","U+0210F"
+"plus;","U+0002B"
+"plusacir;","U+02A23"
+"plusb;","U+0229E"
+"pluscir;","U+02A22"
+"plusdo;","U+02214"
+"plusdu;","U+02A25"
+"pluse;","U+02A72"
+"plusmn;","U+000B1"
+"plusmn","U+000B1"
+"plussim;","U+02A26"
+"plustwo;","U+02A27"
+"pm;","U+000B1"
+"pointint;","U+02A15"
+"popf;","U+1D561"
+"pound;","U+000A3"
+"pound","U+000A3"
+"pr;","U+0227A"
+"prE;","U+02AB3"
+"prap;","U+02AB7"
+"prcue;","U+0227C"
+"pre;","U+02AAF"
+"prec;","U+0227A"
+"precapprox;","U+02AB7"
+"preccurlyeq;","U+0227C"
+"preceq;","U+02AAF"
+"precnapprox;","U+02AB9"
+"precneqq;","U+02AB5"
+"precnsim;","U+022E8"
+"precsim;","U+0227E"
+"prime;","U+02032"
+"primes;","U+02119"
+"prnE;","U+02AB5"
+"prnap;","U+02AB9"
+"prnsim;","U+022E8"
+"prod;","U+0220F"
+"profalar;","U+0232E"
+"profline;","U+02312"
+"profsurf;","U+02313"
+"prop;","U+0221D"
+"propto;","U+0221D"
+"prsim;","U+0227E"
+"prurel;","U+022B0"
+"pscr;","U+1D4C5"
+"psi;","U+003C8"
+"puncsp;","U+02008"
+"qfr;","U+1D52E"
+"qint;","U+02A0C"
+"qopf;","U+1D562"
+"qprime;","U+02057"
+"qscr;","U+1D4C6"
+"quaternions;","U+0210D"
+"quatint;","U+02A16"
+"quest;","U+0003F"
+"questeq;","U+0225F"
+"quot;","U+00022"
+"quot","U+00022"
+"rAarr;","U+021DB"
+"rArr;","U+021D2"
+"rAtail;","U+0291C"
+"rBarr;","U+0290F"
+"rHar;","U+02964"
+"racute;","U+00155"
+"radic;","U+0221A"
+"raemptyv;","U+029B3"
+"rang;","U+027E9"
+"rangd;","U+02992"
+"range;","U+029A5"
+"rangle;","U+027E9"
+"raquo;","U+000BB"
+"raquo","U+000BB"
+"rarr;","U+02192"
+"rarrap;","U+02975"
+"rarrb;","U+021E5"
+"rarrbfs;","U+02920"
+"rarrc;","U+02933"
+"rarrfs;","U+0291E"
+"rarrhk;","U+021AA"
+"rarrlp;","U+021AC"
+"rarrpl;","U+02945"
+"rarrsim;","U+02974"
+"rarrtl;","U+021A3"
+"rarrw;","U+0219D"
+"ratail;","U+0291A"
+"ratio;","U+02236"
+"rationals;","U+0211A"
+"rbarr;","U+0290D"
+"rbbrk;","U+02773"
+"rbrace;","U+0007D"
+"rbrack;","U+0005D"
+"rbrke;","U+0298C"
+"rbrksld;","U+0298E"
+"rbrkslu;","U+02990"
+"rcaron;","U+00159"
+"rcedil;","U+00157"
+"rceil;","U+02309"
+"rcub;","U+0007D"
+"rcy;","U+00440"
+"rdca;","U+02937"
+"rdldhar;","U+02969"
+"rdquo;","U+0201D"
+"rdquor;","U+0201D"
+"rdsh;","U+021B3"
+"real;","U+0211C"
+"realine;","U+0211B"
+"realpart;","U+0211C"
+"reals;","U+0211D"
+"rect;","U+025AD"
+"reg;","U+000AE"
+"reg","U+000AE"
+"rfisht;","U+0297D"
+"rfloor;","U+0230B"
+"rfr;","U+1D52F"
+"rhard;","U+021C1"
+"rharu;","U+021C0"
+"rharul;","U+0296C"
+"rho;","U+003C1"
+"rhov;","U+003F1"
+"rightarrow;","U+02192"
+"rightarrowtail;","U+021A3"
+"rightharpoondown;","U+021C1"
+"rightharpoonup;","U+021C0"
+"rightleftarrows;","U+021C4"
+"rightleftharpoons;","U+021CC"
+"rightrightarrows;","U+021C9"
+"rightsquigarrow;","U+0219D"
+"rightthreetimes;","U+022CC"
+"ring;","U+002DA"
+"risingdotseq;","U+02253"
+"rlarr;","U+021C4"
+"rlhar;","U+021CC"
+"rlm;","U+0200F"
+"rmoust;","U+023B1"
+"rmoustache;","U+023B1"
+"rnmid;","U+02AEE"
+"roang;","U+027ED"
+"roarr;","U+021FE"
+"robrk;","U+027E7"
+"ropar;","U+02986"
+"ropf;","U+1D563"
+"roplus;","U+02A2E"
+"rotimes;","U+02A35"
+"rpar;","U+00029"
+"rpargt;","U+02994"
+"rppolint;","U+02A12"
+"rrarr;","U+021C9"
+"rsaquo;","U+0203A"
+"rscr;","U+1D4C7"
+"rsh;","U+021B1"
+"rsqb;","U+0005D"
+"rsquo;","U+02019"
+"rsquor;","U+02019"
+"rthree;","U+022CC"
+"rtimes;","U+022CA"
+"rtri;","U+025B9"
+"rtrie;","U+022B5"
+"rtrif;","U+025B8"
+"rtriltri;","U+029CE"
+"ruluhar;","U+02968"
+"rx;","U+0211E"
+"sacute;","U+0015B"
+"sbquo;","U+0201A"
+"sc;","U+0227B"
+"scE;","U+02AB4"
+"scap;","U+02AB8"
+"scaron;","U+00161"
+"sccue;","U+0227D"
+"sce;","U+02AB0"
+"scedil;","U+0015F"
+"scirc;","U+0015D"
+"scnE;","U+02AB6"
+"scnap;","U+02ABA"
+"scnsim;","U+022E9"
+"scpolint;","U+02A13"
+"scsim;","U+0227F"
+"scy;","U+00441"
+"sdot;","U+022C5"
+"sdotb;","U+022A1"
+"sdote;","U+02A66"
+"seArr;","U+021D8"
+"searhk;","U+02925"
+"searr;","U+02198"
+"searrow;","U+02198"
+"sect;","U+000A7"
+"sect","U+000A7"
+"semi;","U+0003B"
+"seswar;","U+02929"
+"setminus;","U+02216"
+"setmn;","U+02216"
+"sext;","U+02736"
+"sfr;","U+1D530"
+"sfrown;","U+02322"
+"sharp;","U+0266F"
+"shchcy;","U+00449"
+"shcy;","U+00448"
+"shortmid;","U+02223"
+"shortparallel;","U+02225"
+"shy;","U+000AD "
+"shy","U+000AD "
+"sigma;","U+003C3"
+"sigmaf;","U+003C2"
+"sigmav;","U+003C2"
+"sim;","U+0223C"
+"simdot;","U+02A6A"
+"sime;","U+02243"
+"simeq;","U+02243"
+"simg;","U+02A9E"
+"simgE;","U+02AA0"
+"siml;","U+02A9D"
+"simlE;","U+02A9F"
+"simne;","U+02246"
+"simplus;","U+02A24"
+"simrarr;","U+02972"
+"slarr;","U+02190"
+"smallsetminus;","U+02216"
+"smashp;","U+02A33"
+"smeparsl;","U+029E4"
+"smid;","U+02223"
+"smile;","U+02323"
+"smt;","U+02AAA"
+"smte;","U+02AAC"
+"softcy;","U+0044C"
+"sol;","U+0002F"
+"solb;","U+029C4"
+"solbar;","U+0233F"
+"sopf;","U+1D564"
+"spades;","U+02660"
+"spadesuit;","U+02660"
+"spar;","U+02225"
+"sqcap;","U+02293"
+"sqcup;","U+02294"
+"sqsub;","U+0228F"
+"sqsube;","U+02291"
+"sqsubset;","U+0228F"
+"sqsubseteq;","U+02291"
+"sqsup;","U+02290"
+"sqsupe;","U+02292"
+"sqsupset;","U+02290"
+"sqsupseteq;","U+02292"
+"squ;","U+025A1"
+"square;","U+025A1"
+"squarf;","U+025AA"
+"squf;","U+025AA"
+"srarr;","U+02192"
+"sscr;","U+1D4C8"
+"ssetmn;","U+02216"
+"ssmile;","U+02323"
+"sstarf;","U+022C6"
+"star;","U+02606"
+"starf;","U+02605"
+"straightepsilon;","U+003F5"
+"straightphi;","U+003D5"
+"strns;","U+000AF"
+"sub;","U+02282"
+"subE;","U+02AC5"
+"subdot;","U+02ABD"
+"sube;","U+02286"
+"subedot;","U+02AC3"
+"submult;","U+02AC1"
+"subnE;","U+02ACB"
+"subne;","U+0228A"
+"subplus;","U+02ABF"
+"subrarr;","U+02979"
+"subset;","U+02282"
+"subseteq;","U+02286"
+"subseteqq;","U+02AC5"
+"subsetneq;","U+0228A"
+"subsetneqq;","U+02ACB"
+"subsim;","U+02AC7"
+"subsub;","U+02AD5"
+"subsup;","U+02AD3"
+"succ;","U+0227B"
+"succapprox;","U+02AB8"
+"succcurlyeq;","U+0227D"
+"succeq;","U+02AB0"
+"succnapprox;","U+02ABA"
+"succneqq;","U+02AB6"
+"succnsim;","U+022E9"
+"succsim;","U+0227F"
+"sum;","U+02211"
+"sung;","U+0266A"
+"sup1;","U+000B9"
+"sup1","U+000B9"
+"sup2;","U+000B2"
+"sup2","U+000B2"
+"sup3;","U+000B3"
+"sup3","U+000B3"
+"sup;","U+02283"
+"supE;","U+02AC6"
+"supdot;","U+02ABE"
+"supdsub;","U+02AD8"
+"supe;","U+02287"
+"supedot;","U+02AC4"
+"suphsol;","U+027C9"
+"suphsub;","U+02AD7"
+"suplarr;","U+0297B"
+"supmult;","U+02AC2"
+"supnE;","U+02ACC"
+"supne;","U+0228B"
+"supplus;","U+02AC0"
+"supset;","U+02283"
+"supseteq;","U+02287"
+"supseteqq;","U+02AC6"
+"supsetneq;","U+0228B"
+"supsetneqq;","U+02ACC"
+"supsim;","U+02AC8"
+"supsub;","U+02AD4"
+"supsup;","U+02AD6"
+"swArr;","U+021D9"
+"swarhk;","U+02926"
+"swarr;","U+02199"
+"swarrow;","U+02199"
+"swnwar;","U+0292A"
+"szlig;","U+000DF"
+"szlig","U+000DF"
+"target;","U+02316"
+"tau;","U+003C4"
+"tbrk;","U+023B4"
+"tcaron;","U+00165"
+"tcedil;","U+00163"
+"tcy;","U+00442"
+"tdot;","U+020DB"
+"telrec;","U+02315"
+"tfr;","U+1D531"
+"there4;","U+02234"
+"therefore;","U+02234"
+"theta;","U+003B8"
+"thetasym;","U+003D1"
+"thetav;","U+003D1"
+"thickapprox;","U+02248"
+"thicksim;","U+0223C"
+"thinsp;","U+02009"
+"thkap;","U+02248"
+"thksim;","U+0223C"
+"thorn;","U+000FE"
+"thorn","U+000FE"
+"tilde;","U+002DC"
+"times;","U+000D7"
+"times","U+000D7"
+"timesb;","U+022A0"
+"timesbar;","U+02A31"
+"timesd;","U+02A30"
+"tint;","U+0222D"
+"toea;","U+02928"
+"top;","U+022A4"
+"topbot;","U+02336"
+"topcir;","U+02AF1"
+"topf;","U+1D565"
+"topfork;","U+02ADA"
+"tosa;","U+02929"
+"tprime;","U+02034"
+"trade;","U+02122"
+"triangle;","U+025B5"
+"triangledown;","U+025BF"
+"triangleleft;","U+025C3"
+"trianglelefteq;","U+022B4"
+"triangleq;","U+0225C"
+"triangleright;","U+025B9"
+"trianglerighteq;","U+022B5"
+"tridot;","U+025EC"
+"trie;","U+0225C"
+"triminus;","U+02A3A"
+"triplus;","U+02A39"
+"trisb;","U+029CD"
+"tritime;","U+02A3B"
+"trpezium;","U+023E2"
+"tscr;","U+1D4C9"
+"tscy;","U+00446"
+"tshcy;","U+0045B"
+"tstrok;","U+00167"
+"twixt;","U+0226C"
+"twoheadleftarrow;","U+0219E"
+"twoheadrightarrow;","U+021A0"
+"uArr;","U+021D1"
+"uHar;","U+02963"
+"uacute;","U+000FA"
+"uacute","U+000FA"
+"uarr;","U+02191"
+"ubrcy;","U+0045E"
+"ubreve;","U+0016D"
+"ucirc;","U+000FB"
+"ucirc","U+000FB"
+"ucy;","U+00443"
+"udarr;","U+021C5"
+"udblac;","U+00171"
+"udhar;","U+0296E"
+"ufisht;","U+0297E"
+"ufr;","U+1D532"
+"ugrave;","U+000F9"
+"ugrave","U+000F9"
+"uharl;","U+021BF"
+"uharr;","U+021BE"
+"uhblk;","U+02580"
+"ulcorn;","U+0231C"
+"ulcorner;","U+0231C"
+"ulcrop;","U+0230F"
+"ultri;","U+025F8"
+"umacr;","U+0016B"
+"uml;","U+000A8"
+"uml","U+000A8"
+"uogon;","U+00173"
+"uopf;","U+1D566"
+"uparrow;","U+02191"
+"updownarrow;","U+02195"
+"upharpoonleft;","U+021BF"
+"upharpoonright;","U+021BE"
+"uplus;","U+0228E"
+"upsi;","U+003C5"
+"upsih;","U+003D2"
+"upsilon;","U+003C5"
+"upuparrows;","U+021C8"
+"urcorn;","U+0231D"
+"urcorner;","U+0231D"
+"urcrop;","U+0230E"
+"uring;","U+0016F"
+"urtri;","U+025F9"
+"uscr;","U+1D4CA"
+"utdot;","U+022F0"
+"utilde;","U+00169"
+"utri;","U+025B5"
+"utrif;","U+025B4"
+"uuarr;","U+021C8"
+"uuml;","U+000FC"
+"uuml","U+000FC"
+"uwangle;","U+029A7"
+"vArr;","U+021D5"
+"vBar;","U+02AE8"
+"vBarv;","U+02AE9"
+"vDash;","U+022A8"
+"vangrt;","U+0299C"
+"varepsilon;","U+003F5"
+"varkappa;","U+003F0"
+"varnothing;","U+02205"
+"varphi;","U+003D5"
+"varpi;","U+003D6"
+"varpropto;","U+0221D"
+"varr;","U+02195"
+"varrho;","U+003F1"
+"varsigma;","U+003C2"
+"vartheta;","U+003D1"
+"vartriangleleft;","U+022B2"
+"vartriangleright;","U+022B3"
+"vcy;","U+00432"
+"vdash;","U+022A2"
+"vee;","U+02228"
+"veebar;","U+022BB"
+"veeeq;","U+0225A"
+"vellip;","U+022EE"
+"verbar;","U+0007C"
+"vert;","U+0007C"
+"vfr;","U+1D533"
+"vltri;","U+022B2"
+"vopf;","U+1D567"
+"vprop;","U+0221D"
+"vrtri;","U+022B3"
+"vscr;","U+1D4CB"
+"vzigzag;","U+0299A"
+"wcirc;","U+00175"
+"wedbar;","U+02A5F"
+"wedge;","U+02227"
+"wedgeq;","U+02259"
+"weierp;","U+02118"
+"wfr;","U+1D534"
+"wopf;","U+1D568"
+"wp;","U+02118"
+"wr;","U+02240"
+"wreath;","U+02240"
+"wscr;","U+1D4CC"
+"xcap;","U+022C2"
+"xcirc;","U+025EF"
+"xcup;","U+022C3"
+"xdtri;","U+025BD"
+"xfr;","U+1D535"
+"xhArr;","U+027FA"
+"xharr;","U+027F7"
+"xi;","U+003BE"
+"xlArr;","U+027F8"
+"xlarr;","U+027F5"
+"xmap;","U+027FC"
+"xnis;","U+022FB"
+"xodot;","U+02A00"
+"xopf;","U+1D569"
+"xoplus;","U+02A01"
+"xotime;","U+02A02"
+"xrArr;","U+027F9"
+"xrarr;","U+027F6"
+"xscr;","U+1D4CD"
+"xsqcup;","U+02A06"
+"xuplus;","U+02A04"
+"xutri;","U+025B3"
+"xvee;","U+022C1"
+"xwedge;","U+022C0"
+"yacute;","U+000FD"
+"yacute","U+000FD"
+"yacy;","U+0044F"
+"ycirc;","U+00177"
+"ycy;","U+0044B"
+"yen;","U+000A5"
+"yen","U+000A5"
+"yfr;","U+1D536"
+"yicy;","U+00457"
+"yopf;","U+1D56A"
+"yscr;","U+1D4CE"
+"yucy;","U+0044E"
+"yuml;","U+000FF"
+"yuml","U+000FF"
+"zacute;","U+0017A"
+"zcaron;","U+0017E"
+"zcy;","U+00437"
+"zdot;","U+0017C"
+"zeetrf;","U+02128"
+"zeta;","U+003B6"
+"zfr;","U+1D537"
+"zhcy;","U+00436"
+"zigrarr;","U+021DD"
+"zopf;","U+1D56B"
+"zscr;","U+1D4CF"
+"zwj;","U+0200D"
+"zwnj;","U+0200C"
diff --git a/Source/WebCore/html/parser/HTMLEntityParser.cpp b/Source/WebCore/html/parser/HTMLEntityParser.cpp
new file mode 100644
index 0000000..6a422b8
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLEntityParser.cpp
@@ -0,0 +1,272 @@
+/*
+ * 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.
+ *
+ * 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 "HTMLEntityParser.h"
+
+#include "HTMLEntitySearch.h"
+#include "HTMLEntityTable.h"
+#include <wtf/Vector.h>
+
+using namespace WTF;
+
+namespace WebCore {
+
+namespace {
+
+static const UChar windowsLatin1ExtensionArray[32] = {
+ 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, // 80-87
+ 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008D, 0x017D, 0x008F, // 88-8F
+ 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, // 90-97
+ 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x017E, 0x0178, // 98-9F
+};
+
+inline UChar adjustEntity(UChar32 value)
+{
+ if ((value & ~0x1F) != 0x0080)
+ return value;
+ return windowsLatin1ExtensionArray[value - 0x80];
+}
+
+inline UChar32 legalEntityFor(UChar32 value)
+{
+ // FIXME: A number of specific entity values generate parse errors.
+ if (value == 0 || value > 0x10FFFF || (value >= 0xD800 && value <= 0xDFFF))
+ return 0xFFFD;
+ if (U_IS_BMP(value))
+ return adjustEntity(value);
+ return value;
+}
+
+inline bool convertToUTF16(UChar32 value, Vector<UChar, 16>& decodedEntity)
+{
+ if (U_IS_BMP(value)) {
+ UChar character = static_cast<UChar>(value);
+ ASSERT(character == value);
+ decodedEntity.append(character);
+ return true;
+ }
+ decodedEntity.append(U16_LEAD(value));
+ decodedEntity.append(U16_TRAIL(value));
+ return true;
+}
+
+inline bool isHexDigit(UChar cc)
+{
+ return (cc >= '0' && cc <= '9') || (cc >= 'a' && cc <= 'f') || (cc >= 'A' && cc <= 'F');
+}
+
+inline bool isAlphaNumeric(UChar cc)
+{
+ return (cc >= '0' && cc <= '9') || (cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z');
+}
+
+void unconsumeCharacters(SegmentedString& source, const Vector<UChar, 10>& consumedCharacters)
+{
+ if (consumedCharacters.size() == 1)
+ source.push(consumedCharacters[0]);
+ else if (consumedCharacters.size() == 2) {
+ source.push(consumedCharacters[0]);
+ source.push(consumedCharacters[1]);
+ } else
+ source.prepend(SegmentedString(String(consumedCharacters.data(), consumedCharacters.size())));
+}
+
+}
+
+bool consumeHTMLEntity(SegmentedString& source, Vector<UChar, 16>& decodedEntity, bool& notEnoughCharacters, UChar additionalAllowedCharacter)
+{
+ ASSERT(!additionalAllowedCharacter || additionalAllowedCharacter == '"' || additionalAllowedCharacter == '\'' || additionalAllowedCharacter == '>');
+ ASSERT(!notEnoughCharacters);
+ ASSERT(decodedEntity.isEmpty());
+
+ enum EntityState {
+ Initial,
+ Number,
+ MaybeHexLowerCaseX,
+ MaybeHexUpperCaseX,
+ Hex,
+ Decimal,
+ Named
+ };
+ EntityState entityState = Initial;
+ UChar32 result = 0;
+ Vector<UChar, 10> consumedCharacters;
+
+ while (!source.isEmpty()) {
+ UChar cc = *source;
+ switch (entityState) {
+ case Initial: {
+ if (cc == '\x09' || cc == '\x0A' || cc == '\x0C' || cc == ' ' || cc == '<' || cc == '&')
+ return false;
+ if (additionalAllowedCharacter && cc == additionalAllowedCharacter)
+ return false;
+ if (cc == '#') {
+ entityState = Number;
+ break;
+ }
+ if ((cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z')) {
+ entityState = Named;
+ continue;
+ }
+ return false;
+ }
+ case Number: {
+ if (cc == 'x') {
+ entityState = MaybeHexLowerCaseX;
+ break;
+ }
+ if (cc == 'X') {
+ entityState = MaybeHexUpperCaseX;
+ break;
+ }
+ if (cc >= '0' && cc <= '9') {
+ entityState = Decimal;
+ continue;
+ }
+ source.push('#');
+ return false;
+ }
+ case MaybeHexLowerCaseX: {
+ if (isHexDigit(cc)) {
+ entityState = Hex;
+ continue;
+ }
+ source.push('#');
+ source.push('x');
+ return false;
+ }
+ case MaybeHexUpperCaseX: {
+ if (isHexDigit(cc)) {
+ entityState = Hex;
+ continue;
+ }
+ source.push('#');
+ source.push('X');
+ return false;
+ }
+ case Hex: {
+ if (cc >= '0' && cc <= '9')
+ result = result * 16 + cc - '0';
+ else if (cc >= 'a' && cc <= 'f')
+ result = result * 16 + 10 + cc - 'a';
+ else if (cc >= 'A' && cc <= 'F')
+ result = result * 16 + 10 + cc - 'A';
+ else {
+ if (cc == ';')
+ source.advanceAndASSERT(cc);
+ return convertToUTF16(legalEntityFor(result), decodedEntity);
+ }
+ break;
+ }
+ case Decimal: {
+ if (cc >= '0' && cc <= '9')
+ result = result * 10 + cc - '0';
+ else {
+ if (cc == ';')
+ source.advanceAndASSERT(cc);
+ return convertToUTF16(legalEntityFor(result), decodedEntity);
+ }
+ break;
+ }
+ case Named: {
+ HTMLEntitySearch entitySearch;
+ while (!source.isEmpty()) {
+ cc = *source;
+ entitySearch.advance(cc);
+ if (!entitySearch.isEntityPrefix())
+ break;
+ consumedCharacters.append(cc);
+ source.advanceAndASSERT(cc);
+ }
+ notEnoughCharacters = source.isEmpty();
+ if (notEnoughCharacters) {
+ // We can't an entity because there might be a longer entity
+ // that we could match if we had more data.
+ unconsumeCharacters(source, consumedCharacters);
+ return false;
+ }
+ if (!entitySearch.mostRecentMatch()) {
+ ASSERT(!entitySearch.currentValue());
+ unconsumeCharacters(source, consumedCharacters);
+ return false;
+ }
+ if (entitySearch.mostRecentMatch()->length != entitySearch.currentLength()) {
+ // We've consumed too many characters. We need to walk the
+ // source back to the point at which we had consumed an
+ // actual entity.
+ unconsumeCharacters(source, consumedCharacters);
+ consumedCharacters.clear();
+ const int length = entitySearch.mostRecentMatch()->length;
+ const UChar* reference = entitySearch.mostRecentMatch()->entity;
+ for (int i = 0; i < length; ++i) {
+ cc = *source;
+ ASSERT_UNUSED(reference, cc == *reference++);
+ consumedCharacters.append(cc);
+ source.advanceAndASSERT(cc);
+ ASSERT(!source.isEmpty());
+ }
+ cc = *source;
+ }
+ if (entitySearch.mostRecentMatch()->lastCharacter() == ';'
+ || !additionalAllowedCharacter
+ || !(isAlphaNumeric(cc) || cc == '=')) {
+ return convertToUTF16(entitySearch.mostRecentMatch()->value, decodedEntity);
+ }
+ unconsumeCharacters(source, consumedCharacters);
+ return false;
+ }
+ }
+ consumedCharacters.append(cc);
+ source.advanceAndASSERT(cc);
+ }
+ ASSERT(source.isEmpty());
+ notEnoughCharacters = true;
+ unconsumeCharacters(source, consumedCharacters);
+ return false;
+}
+
+UChar decodeNamedEntity(const char* name)
+{
+ HTMLEntitySearch search;
+ while (*name) {
+ search.advance(*name++);
+ if (!search.isEntityPrefix())
+ return 0;
+ }
+ search.advance(';');
+ UChar32 entityValue = search.currentValue();
+ if (U16_LENGTH(entityValue) != 1) {
+ // Callers need to move off this API if the entity table has values
+ // which do no fit in a 16 bit UChar!
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+ return static_cast<UChar>(entityValue);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/html/parser/HTMLEntityParser.h b/Source/WebCore/html/parser/HTMLEntityParser.h
new file mode 100644
index 0000000..f02e849
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLEntityParser.h
@@ -0,0 +1,41 @@
+/*
+ * 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
+ * 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 HTMLEntityParser_h
+#define HTMLEntityParser_h
+
+#include "SegmentedString.h"
+
+namespace WebCore {
+
+bool consumeHTMLEntity(SegmentedString&, Vector<UChar, 16>& decodedEntity, bool& notEnoughCharacters, UChar additionalAllowedCharacter = '\0');
+
+// Used by the XML parser. Not suitable for use in HTML parsing. Use consumeHTMLEntity instead.
+UChar decodeNamedEntity(const char*);
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLEntitySearch.cpp b/Source/WebCore/html/parser/HTMLEntitySearch.cpp
new file mode 100644
index 0000000..56fb91a
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLEntitySearch.cpp
@@ -0,0 +1,134 @@
+/*
+ * 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 "HTMLEntitySearch.h"
+
+#include "HTMLEntityTable.h"
+
+namespace WebCore {
+
+namespace {
+
+const HTMLEntityTableEntry* halfway(const HTMLEntityTableEntry* left, const HTMLEntityTableEntry* right)
+{
+ return &left[(right - left) / 2];
+}
+
+}
+
+HTMLEntitySearch::HTMLEntitySearch()
+ : m_currentLength(0)
+ , m_currentValue(0)
+ , m_mostRecentMatch(0)
+ , m_first(HTMLEntityTable::firstEntry())
+ , m_last(HTMLEntityTable::lastEntry())
+{
+}
+
+HTMLEntitySearch::CompareResult HTMLEntitySearch::compare(const HTMLEntityTableEntry* entry, UChar nextCharacter) const
+{
+ if (entry->length < m_currentLength + 1)
+ return Before;
+ UChar entryNextCharacter = entry->entity[m_currentLength];
+ if (entryNextCharacter == nextCharacter)
+ return Prefix;
+ return entryNextCharacter < nextCharacter ? Before : After;
+}
+
+const HTMLEntityTableEntry* HTMLEntitySearch::findFirst(UChar nextCharacter) const
+{
+ const HTMLEntityTableEntry* left = m_first;
+ const HTMLEntityTableEntry* right = m_last;
+ if (left == right)
+ return left;
+ CompareResult result = compare(left, nextCharacter);
+ if (result == Prefix)
+ return left;
+ if (result == After)
+ return right;
+ while (left + 1 < right) {
+ const HTMLEntityTableEntry* probe = halfway(left, right);
+ result = compare(probe, nextCharacter);
+ if (result == Before)
+ left = probe;
+ else {
+ ASSERT(result == After || result == Prefix);
+ right = probe;
+ }
+ }
+ ASSERT(left + 1 == right);
+ return right;
+}
+
+const HTMLEntityTableEntry* HTMLEntitySearch::findLast(UChar nextCharacter) const
+{
+ const HTMLEntityTableEntry* left = m_first;
+ const HTMLEntityTableEntry* right = m_last;
+ if (left == right)
+ return right;
+ CompareResult result = compare(right, nextCharacter);
+ if (result == Prefix)
+ return right;
+ if (result == Before)
+ return left;
+ while (left + 1 < right) {
+ const HTMLEntityTableEntry* probe = halfway(left, right);
+ result = compare(probe, nextCharacter);
+ if (result == After)
+ right = probe;
+ else {
+ ASSERT(result == Before || result == Prefix);
+ left = probe;
+ }
+ }
+ ASSERT(left + 1 == right);
+ return left;
+}
+
+void HTMLEntitySearch::advance(UChar nextCharacter)
+{
+ ASSERT(isEntityPrefix());
+ if (!m_currentLength) {
+ m_first = HTMLEntityTable::firstEntryStartingWith(nextCharacter);
+ m_last = HTMLEntityTable::lastEntryStartingWith(nextCharacter);
+ if (!m_first || !m_last)
+ return fail();
+ } else {
+ m_first = findFirst(nextCharacter);
+ m_last = findLast(nextCharacter);
+ if (m_first == m_last && compare(m_first, nextCharacter) != Prefix)
+ return fail();
+ }
+ ++m_currentLength;
+ if (m_first->length != m_currentLength) {
+ m_currentValue = 0;
+ return;
+ }
+ m_mostRecentMatch = m_first;
+ m_currentValue = m_mostRecentMatch->value;
+}
+
+}
diff --git a/Source/WebCore/html/parser/HTMLEntitySearch.h b/Source/WebCore/html/parser/HTMLEntitySearch.h
new file mode 100644
index 0000000..0c66318
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLEntitySearch.h
@@ -0,0 +1,75 @@
+/*
+ * 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 HTMLEntitySearch_h
+#define HTMLEntitySearch_h
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+struct HTMLEntityTableEntry;
+
+class HTMLEntitySearch {
+public:
+ HTMLEntitySearch();
+
+ void advance(UChar);
+
+ bool isEntityPrefix() const { return !!m_first; }
+ UChar32 currentValue() const { return m_currentValue; }
+ int currentLength() const { return m_currentLength; }
+
+ const HTMLEntityTableEntry* mostRecentMatch() const { return m_mostRecentMatch; }
+
+private:
+ enum CompareResult {
+ Before,
+ Prefix,
+ After,
+ };
+
+ CompareResult compare(const HTMLEntityTableEntry*, UChar) const;
+ const HTMLEntityTableEntry* findFirst(UChar) const;
+ const HTMLEntityTableEntry* findLast(UChar) const;
+
+ void fail()
+ {
+ m_currentValue = 0;
+ m_first = 0;
+ m_last = 0;
+ }
+
+ int m_currentLength;
+ UChar32 m_currentValue;
+
+ const HTMLEntityTableEntry* m_mostRecentMatch;
+ const HTMLEntityTableEntry* m_first;
+ const HTMLEntityTableEntry* m_last;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLEntityTable.h b/Source/WebCore/html/parser/HTMLEntityTable.h
new file mode 100644
index 0000000..3b9ab4e
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLEntityTable.h
@@ -0,0 +1,52 @@
+/*
+ * 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 HTMLEntityTable_h
+#define HTMLEntityTable_h
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+struct HTMLEntityTableEntry {
+ UChar lastCharacter() const { return entity[length - 1]; }
+
+ const UChar* entity;
+ int length;
+ UChar32 value;
+};
+
+class HTMLEntityTable {
+public:
+ static const HTMLEntityTableEntry* firstEntry();
+ static const HTMLEntityTableEntry* lastEntry();
+
+ static const HTMLEntityTableEntry* firstEntryStartingWith(UChar);
+ static const HTMLEntityTableEntry* lastEntryStartingWith(UChar);
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLFormattingElementList.cpp b/Source/WebCore/html/parser/HTMLFormattingElementList.cpp
new file mode 100644
index 0000000..22bf03e
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLFormattingElementList.cpp
@@ -0,0 +1,134 @@
+/*
+ * 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 GOOGLE 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 GOOGLE 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 "HTMLFormattingElementList.h"
+
+#include "Element.h"
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+HTMLFormattingElementList::HTMLFormattingElementList()
+{
+}
+
+HTMLFormattingElementList::~HTMLFormattingElementList()
+{
+}
+
+Element* HTMLFormattingElementList::closestElementInScopeWithName(const AtomicString& targetName)
+{
+ for (unsigned i = 1; i <= m_entries.size(); ++i) {
+ const Entry& entry = m_entries[m_entries.size() - i];
+ if (entry.isMarker())
+ return 0;
+ if (entry.element()->hasLocalName(targetName))
+ return entry.element();
+ }
+ return 0;
+}
+
+bool HTMLFormattingElementList::contains(Element* element)
+{
+ return !!find(element);
+}
+
+HTMLFormattingElementList::Entry* HTMLFormattingElementList::find(Element* element)
+{
+ size_t index = m_entries.reverseFind(element);
+ if (index != notFound) {
+ // This is somewhat of a hack, and is why this method can't be const.
+ return &m_entries[index];
+ }
+ return 0;
+}
+
+HTMLFormattingElementList::Bookmark HTMLFormattingElementList::bookmarkFor(Element* element)
+{
+ size_t index = m_entries.reverseFind(element);
+ ASSERT(index != notFound);
+ return Bookmark(&at(index));
+}
+
+void HTMLFormattingElementList::swapTo(Element* oldElement, Element* newElement, const Bookmark& bookmark)
+{
+ ASSERT(contains(oldElement));
+ ASSERT(!contains(newElement));
+ if (!bookmark.hasBeenMoved()) {
+ ASSERT(bookmark.mark()->element() == oldElement);
+ bookmark.mark()->replaceElement(newElement);
+ return;
+ }
+ size_t index = bookmark.mark() - first();
+ ASSERT(index < size());
+ m_entries.insert(index + 1, newElement);
+ remove(oldElement);
+}
+
+void HTMLFormattingElementList::append(Element* element)
+{
+ m_entries.append(element);
+}
+
+void HTMLFormattingElementList::remove(Element* element)
+{
+ size_t index = m_entries.reverseFind(element);
+ if (index != notFound)
+ m_entries.remove(index);
+}
+
+void HTMLFormattingElementList::appendMarker()
+{
+ m_entries.append(Entry::MarkerEntry);
+}
+
+void HTMLFormattingElementList::clearToLastMarker()
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#clear-the-list-of-active-formatting-elements-up-to-the-last-marker
+ while (m_entries.size()) {
+ bool shouldStop = m_entries.last().isMarker();
+ m_entries.removeLast();
+ if (shouldStop)
+ break;
+ }
+}
+
+#ifndef NDEBUG
+
+void HTMLFormattingElementList::show()
+{
+ for (unsigned i = 1; i <= m_entries.size(); ++i) {
+ const Entry& entry = m_entries[m_entries.size() - i];
+ if (entry.isMarker())
+ fprintf(stderr, "marker\n");
+ else
+ entry.element()->showNode();
+ }
+}
+
+#endif
+
+}
diff --git a/Source/WebCore/html/parser/HTMLFormattingElementList.h b/Source/WebCore/html/parser/HTMLFormattingElementList.h
new file mode 100644
index 0000000..aca05bb
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLFormattingElementList.h
@@ -0,0 +1,134 @@
+/*
+ * 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 GOOGLE 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 GOOGLE 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 HTMLFormattingElementList_h
+#define HTMLFormattingElementList_h
+
+#include <wtf/Forward.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Element;
+
+// This may end up merged into HTMLElementStack.
+class HTMLFormattingElementList : public Noncopyable {
+public:
+ HTMLFormattingElementList();
+ ~HTMLFormattingElementList();
+
+ // Ideally Entry would be private, but HTMLTreeBuilder has to coordinate
+ // between the HTMLFormattingElementList and HTMLElementStack and needs
+ // access to Entry::isMarker() and Entry::replaceElement() to do so.
+ class Entry {
+ public:
+ // Inline because they're hot and Vector<T> uses them.
+ explicit Entry(Element* element)
+ : m_element(element)
+ {
+ ASSERT(element);
+ }
+ enum MarkerEntryType { MarkerEntry };
+ Entry(MarkerEntryType)
+ : m_element(0)
+ {
+ }
+ ~Entry() {}
+
+ bool isMarker() const { return !m_element; }
+
+ Element* element() const
+ {
+ // The fact that !m_element == isMarker() is an implementation detail
+ // callers should check isMarker() before calling element().
+ ASSERT(m_element);
+ return m_element.get();
+ }
+ void replaceElement(PassRefPtr<Element> element) { m_element = element; }
+
+ // Needed for use with Vector. These are super-hot and must be inline.
+ bool operator==(Element* element) const { return m_element == element; }
+ bool operator!=(Element* element) const { return m_element != element; }
+
+ private:
+ RefPtr<Element> m_element;
+ };
+
+ class Bookmark {
+ public:
+ Bookmark(Entry* entry)
+ : m_hasBeenMoved(false)
+ , m_mark(entry)
+ {
+ }
+
+ void moveToAfter(Entry* before)
+ {
+ m_hasBeenMoved = true;
+ m_mark = before;
+ }
+
+ bool hasBeenMoved() const { return m_hasBeenMoved; }
+ Entry* mark() const { return m_mark; }
+
+ private:
+ bool m_hasBeenMoved;
+ Entry* m_mark;
+ };
+
+ bool isEmpty() const { return !size(); }
+ size_t size() const { return m_entries.size(); }
+
+ Element* closestElementInScopeWithName(const AtomicString&);
+
+ Entry* find(Element*);
+ bool contains(Element*);
+ void append(Element*);
+ void remove(Element*);
+
+ Bookmark bookmarkFor(Element*);
+ void swapTo(Element* oldElement, Element* newElement, const Bookmark&);
+
+ void appendMarker();
+ // clearToLastMarker also clears the marker (per the HTML5 spec).
+ void clearToLastMarker();
+
+ const Entry& at(size_t i) const { return m_entries[i]; }
+ Entry& at(size_t i) { return m_entries[i]; }
+
+#ifndef NDEBUG
+ void show();
+#endif
+
+private:
+ Entry* first() { return &at(0); }
+
+ Vector<Entry> m_entries;
+};
+
+}
+
+#endif // HTMLFormattingElementList_h
diff --git a/Source/WebCore/html/parser/HTMLInputStream.h b/Source/WebCore/html/parser/HTMLInputStream.h
new file mode 100644
index 0000000..1bfbaf9
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLInputStream.h
@@ -0,0 +1,164 @@
+/*
+ * 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 HTMLInputStream_h
+#define HTMLInputStream_h
+
+#include "SegmentedString.h"
+
+namespace WebCore {
+
+// The InputStream is made up of a sequence of SegmentedStrings:
+//
+// [--current--][--next--][--next--] ... [--next--]
+// /\ (also called m_last)
+// L_ current insertion point
+//
+// The current segmented string is stored in InputStream. Each of the
+// afterInsertionPoint buffers are stored in InsertionPointRecords on the
+// stack.
+//
+// We remove characters from the "current" string in the InputStream.
+// document.write() will add characters at the current insertion point,
+// which appends them to the "current" string.
+//
+// m_last is a pointer to the last of the afterInsertionPoint strings.
+// The network adds data at the end of the InputStream, which appends
+// them to the "last" string.
+class HTMLInputStream : public Noncopyable {
+public:
+ HTMLInputStream()
+ : m_last(&m_first)
+ {
+ }
+
+ void appendToEnd(const SegmentedString& string)
+ {
+ m_last->append(string);
+ }
+
+ void insertAtCurrentInsertionPoint(const SegmentedString& string)
+ {
+ m_first.append(string);
+ }
+
+ bool hasInsertionPoint() const
+ {
+ if (&m_first != m_last)
+ return true;
+ if (!haveSeenEndOfFile()) {
+ // FIXME: Somehow we need to understand the difference between
+ // input streams that are coming off the network and streams that
+ // were created with document.open(). In the later case, we always
+ // have an isertion point at the end of the stream until someone
+ // calls document.close().
+ return true;
+ }
+ return false;
+ }
+
+ void markEndOfFile()
+ {
+ // FIXME: This should use InputStreamPreprocessor::endOfFileMarker
+ // once InputStreamPreprocessor is split off into its own header.
+ static const UChar endOfFileMarker = 0;
+ m_last->append(SegmentedString(String(&endOfFileMarker, 1)));
+ m_last->close();
+ }
+
+ bool haveSeenEndOfFile() const
+ {
+ return m_last->isClosed();
+ }
+
+ SegmentedString& current() { return m_first; }
+ const SegmentedString& current() const { return m_first; }
+
+ void splitInto(SegmentedString& next)
+ {
+ next = m_first;
+ m_first = SegmentedString();
+ if (m_last == &m_first) {
+ // We used to only have one SegmentedString in the InputStream
+ // but now we have two. That means m_first is no longer also
+ // the m_last string, |next| is now the last one.
+ m_last = &next;
+ }
+ }
+
+ void mergeFrom(SegmentedString& next)
+ {
+ m_first.append(next);
+ if (m_last == &next) {
+ // The string |next| used to be the last SegmentedString in
+ // the InputStream. Now that it's been merged into m_first,
+ // that makes m_first the last one.
+ m_last = &m_first;
+ }
+ if (next.isClosed()) {
+ // We also need to merge the "closed" state from next to
+ // m_first. Arguably, this work could be done in append().
+ m_first.close();
+ }
+ }
+
+private:
+ SegmentedString m_first;
+ SegmentedString* m_last;
+};
+
+class InsertionPointRecord : public Noncopyable {
+public:
+ explicit InsertionPointRecord(HTMLInputStream& inputStream)
+ : m_inputStream(&inputStream)
+ {
+ m_line = m_inputStream->current().currentLine();
+ m_column = m_inputStream->current().currentColumn();
+ m_inputStream->splitInto(m_next);
+ // We 'fork' current position and use it for the generated script part.
+ // This is a bit weird, because generated part does not have positions within an HTML document.
+ m_inputStream->current().setCurrentPosition(m_line, m_column, 0);
+ }
+
+ ~InsertionPointRecord()
+ {
+ // Some inserted text may have remained in input stream. E.g. if script has written "&amp" or "<table",
+ // it stays in buffer because it cannot be properly tokenized before we see next part.
+ int unparsedRemainderLength = m_inputStream->current().length();
+ m_inputStream->mergeFrom(m_next);
+ // We restore position for the character that goes right after unparsed remainder.
+ m_inputStream->current().setCurrentPosition(m_line, m_column, unparsedRemainderLength);
+ }
+
+private:
+ HTMLInputStream* m_inputStream;
+ SegmentedString m_next;
+ WTF::ZeroBasedNumber m_line;
+ WTF::ZeroBasedNumber m_column;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp b/Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp
new file mode 100644
index 0000000..eac7d28
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp
@@ -0,0 +1,200 @@
+/*
+ * 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 "HTMLMetaCharsetParser.h"
+
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "HTMLTokenizer.h"
+#include "PlatformString.h"
+#include "TextCodec.h"
+#include "TextEncodingRegistry.h"
+
+using namespace WTF;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLMetaCharsetParser::HTMLMetaCharsetParser()
+ : m_tokenizer(HTMLTokenizer::create(false)) // No pre-HTML5 parser quirks.
+ , m_assumedCodec(newTextCodec(Latin1Encoding()))
+ , m_inHeadSection(true)
+ , m_doneChecking(false)
+{
+}
+
+HTMLMetaCharsetParser::~HTMLMetaCharsetParser()
+{
+}
+
+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();
+
+ while (pos < length) {
+ pos = value.find(charsetString, pos, false);
+ if (pos == notFound)
+ break;
+
+ pos += charsetLength;
+
+ // Skip whitespace.
+ while (pos < length && value[pos] <= ' ')
+ ++pos;
+
+ if (value[pos] != '=')
+ continue;
+
+ ++pos;
+
+ while (pos < length && value[pos] <= ' ')
+ ++pos;
+
+ char quoteMark = 0;
+ if (pos < length && (value[pos] == '"' || value[pos] == '\'')) {
+ quoteMark = static_cast<char>(value[pos++]);
+ ASSERT(!(quoteMark & 0x80));
+ }
+
+ if (pos == length)
+ break;
+
+ unsigned end = pos;
+ while (end < length && ((quoteMark && value[end] != quoteMark) || (!quoteMark && value[end] > ' ' && value[end] != '"' && value[end] != '\'' && value[end] != ';')))
+ ++end;
+
+ if (quoteMark && (end == length))
+ break; // Close quote not found.
+
+ return value.substring(pos, end - pos);
+ }
+
+ return "";
+}
+
+bool HTMLMetaCharsetParser::processMeta()
+{
+ bool gotPragma = false;
+ Mode mode = None;
+ String charset;
+
+ const HTMLToken::AttributeList& attributes = m_token.attributes();
+ for (HTMLToken::AttributeList::const_iterator iter = attributes.begin();
+ iter != attributes.end(); ++iter) {
+ AtomicString attributeName(iter->m_name.data(), iter->m_name.size());
+ String attributeValue(iter->m_value.data(), iter->m_value.size());
+
+ if (attributeName == http_equivAttr) {
+ if (equalIgnoringCase(attributeValue, "content-type"))
+ gotPragma = true;
+ } else if (charset.isEmpty()) {
+ if (attributeName == charsetAttr) {
+ charset = attributeValue;
+ mode = Charset;
+ } else if (attributeName == contentAttr) {
+ charset = extractCharset(attributeValue);
+ if (charset.length())
+ mode = Pragma;
+ }
+ }
+ }
+
+ if (mode == Charset || (mode == Pragma && gotPragma)) {
+ m_encoding = TextEncoding(stripLeadingAndTrailingHTMLSpaces(charset));
+ if (m_encoding.isValid())
+ return true;
+ }
+
+ return false;
+}
+
+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)
+ return true;
+
+ ASSERT(!m_encoding.isValid());
+
+ // 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.
+
+ m_input.append(SegmentedString(m_assumedCodec->decode(data, length)));
+
+ 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().data(), m_token.name().size());
+ if (!end) {
+ m_tokenizer->updateStateFor(tagName, 0);
+ if (tagName == metaTag && processMeta()) {
+ m_doneChecking = true;
+ return true;
+ }
+ }
+
+ if (tagName != scriptTag && tagName != noscriptTag
+ && tagName != styleTag && tagName != linkTag
+ && tagName != metaTag && tagName != objectTag
+ && tagName != titleTag && tagName != baseTag
+ && (end || tagName != htmlTag) && (end || tagName != headTag)) {
+ m_inHeadSection = false;
+ }
+ }
+
+ if (!m_inHeadSection && m_input.numberOfCharactersConsumed() >= bytesToCheckUnconditionally) {
+ 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
new file mode 100644
index 0000000..c3136f5
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLMetaCharsetParser.h
@@ -0,0 +1,73 @@
+/*
+ * 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 HTMLMetaCharsetParser_h
+#define HTMLMetaCharsetParser_h
+
+#include "HTMLToken.h"
+#include "SegmentedString.h"
+#include "TextEncoding.h"
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class HTMLTokenizer;
+class TextCodec;
+
+class HTMLMetaCharsetParser : public Noncopyable {
+public:
+ static PassOwnPtr<HTMLMetaCharsetParser> create() { return adoptPtr(new 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; }
+
+private:
+ HTMLMetaCharsetParser();
+
+ bool processMeta();
+ String extractCharset(const String&);
+
+ enum Mode {
+ None,
+ Charset,
+ Pragma,
+ };
+
+ OwnPtr<HTMLTokenizer> m_tokenizer;
+ OwnPtr<TextCodec> m_assumedCodec;
+ SegmentedString m_input;
+ HTMLToken m_token;
+ bool m_inHeadSection;
+
+ bool m_doneChecking;
+ TextEncoding m_encoding;
+};
+
+}
+#endif
diff --git a/Source/WebCore/html/parser/HTMLParserIdioms.cpp b/Source/WebCore/html/parser/HTMLParserIdioms.cpp
new file mode 100644
index 0000000..91ff8d3
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLParserIdioms.cpp
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 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 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 "HTMLParserIdioms.h"
+
+#include <wtf/MathExtras.h>
+#include <wtf/dtoa.h>
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+String stripLeadingAndTrailingHTMLSpaces(const String& string)
+{
+ const UChar* characters = string.characters();
+ unsigned length = string.length();
+
+ unsigned numLeadingSpaces;
+ for (numLeadingSpaces = 0; numLeadingSpaces < length; ++numLeadingSpaces) {
+ if (isNotHTMLSpace(characters[numLeadingSpaces]))
+ break;
+ }
+
+ if (numLeadingSpaces == length)
+ return string.isNull() ? string : emptyAtom.string();
+
+ unsigned numTrailingSpaces;
+ for (numTrailingSpaces = 0; numTrailingSpaces < length; ++numTrailingSpaces) {
+ if (isNotHTMLSpace(characters[length - numTrailingSpaces - 1]))
+ break;
+ }
+
+ ASSERT(numLeadingSpaces + numTrailingSpaces < length);
+
+ return string.substring(numLeadingSpaces, length - (numLeadingSpaces + numTrailingSpaces));
+}
+
+String serializeForNumberType(double number)
+{
+ // According to HTML5, "the best representation of the number n as a floating
+ // point number" is a string produced by applying ToString() to n.
+ NumberToStringBuffer buffer;
+ unsigned length = numberToString(number, buffer);
+ return String(buffer, length);
+}
+
+bool parseToDoubleForNumberType(const String& string, double* result)
+{
+ // See HTML5 2.4.4.3 `Real numbers.'
+
+ // String::toDouble() accepts leading + and whitespace characters, which are not valid here.
+ UChar firstCharacter = string[0];
+ if (firstCharacter != '-' && !isASCIIDigit(firstCharacter))
+ return false;
+
+ bool valid = false;
+ double value = string.toDouble(&valid);
+ if (!valid)
+ return false;
+
+ // NaN and infinity are considered valid by String::toDouble, but not valid here.
+ if (!isfinite(value))
+ return false;
+
+ // Numbers are considered finite IEEE 754 single-precision floating point values.
+ // See HTML5 2.4.4.3 `Real numbers.'
+ if (-FLT_MAX > value || value > FLT_MAX)
+ return false;
+
+ if (result) {
+ // The following expression converts -0 to +0.
+ *result = value ? value : 0;
+ }
+
+ return true;
+}
+
+bool parseToDoubleForNumberTypeWithDecimalPlaces(const String& string, double *result, unsigned *decimalPlaces)
+{
+ if (decimalPlaces)
+ *decimalPlaces = 0;
+
+ if (!parseToDoubleForNumberType(string, result))
+ return false;
+
+ if (!decimalPlaces)
+ return true;
+
+ size_t dotIndex = string.find('.');
+ size_t eIndex = string.find('e');
+ if (eIndex == notFound)
+ eIndex = string.find('E');
+
+ unsigned baseDecimalPlaces = 0;
+ if (dotIndex != notFound) {
+ if (eIndex == notFound)
+ baseDecimalPlaces = string.length() - dotIndex - 1;
+ else
+ baseDecimalPlaces = eIndex - dotIndex - 1;
+ }
+
+ int exponent = 0;
+ if (eIndex != notFound) {
+ unsigned cursor = eIndex + 1, cursorSaved;
+ int digit, exponentSign;
+ int32_t exponent32;
+ size_t length = string.length();
+
+ // Not using String.toInt() in order to perform the same computation as dtoa() does.
+ exponentSign = 0;
+ switch (digit = string[cursor]) {
+ case '-':
+ exponentSign = 1;
+ case '+':
+ digit = string[++cursor];
+ }
+ if (digit >= '0' && digit <= '9') {
+ while (cursor < length && digit == '0')
+ digit = string[++cursor];
+ if (digit > '0' && digit <= '9') {
+ exponent32 = digit - '0';
+ cursorSaved = cursor;
+ while (cursor < length && (digit = string[++cursor]) >= '0' && digit <= '9')
+ exponent32 = (10 * exponent32) + digit - '0';
+ if (cursor - cursorSaved > 8 || exponent32 > 19999)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ exponent = 19999; /* safe for 16 bit ints */
+ else
+ exponent = static_cast<int>(exponent32);
+ if (exponentSign)
+ exponent = -exponent;
+ } else
+ exponent = 0;
+ }
+ }
+
+ int intDecimalPlaces = baseDecimalPlaces - exponent;
+ if (intDecimalPlaces < 0)
+ *decimalPlaces = 0;
+ else if (intDecimalPlaces > 19999)
+ *decimalPlaces = 19999;
+ else
+ *decimalPlaces = static_cast<unsigned>(intDecimalPlaces);
+
+ return true;
+}
+
+// http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers
+bool parseHTMLInteger(const String& input, int& value)
+{
+ // Step 1
+ // Step 2
+ const UChar* position = input.characters();
+ const UChar* end = position + input.length();
+
+ // Step 3
+ int sign = 1;
+
+ // Step 4
+ while (position < end) {
+ if (!isHTMLSpace(*position))
+ break;
+ ++position;
+ }
+
+ // Step 5
+ if (position == end)
+ return false;
+ ASSERT(position < end);
+
+ // Step 6
+ if (*position == '-') {
+ sign = -1;
+ ++position;
+ } else if (*position == '+')
+ ++position;
+ if (position == end)
+ return false;
+ ASSERT(position < end);
+
+ // Step 7
+ if (!isASCIIDigit(*position))
+ return false;
+
+ // Step 8
+ Vector<UChar, 16> digits;
+ while (position < end) {
+ if (!isASCIIDigit(*position))
+ break;
+ digits.append(*position++);
+ }
+
+ // Step 9
+ value = sign * charactersToIntStrict(digits.data(), digits.size());
+ return true;
+}
+
+}
diff --git a/Source/WebCore/html/parser/HTMLParserIdioms.h b/Source/WebCore/html/parser/HTMLParserIdioms.h
new file mode 100644
index 0000000..4e8e58f
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLParserIdioms.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 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 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 HTMLParserIdioms_h
+#define HTMLParserIdioms_h
+
+#include <wtf/Forward.h>
+#include <wtf/unicode/Unicode.h>
+
+namespace WebCore {
+
+// Space characters as defined by the HTML specification.
+bool isHTMLSpace(UChar);
+bool isNotHTMLSpace(UChar);
+
+// Strip leading and trailing whitespace as defined by the HTML specification.
+String stripLeadingAndTrailingHTMLSpaces(const String&);
+
+// An implementation of the HTML specification's algorithm to convert a number to a string for number and range types.
+String serializeForNumberType(double);
+
+// Convert the specified string to a double. If the conversion fails, the return value is false.
+// Leading or trailing illegal characters cause failure, as does passing an empty string.
+// The double* parameter may be 0 to check if the string can be parsed without getting the result.
+bool parseToDoubleForNumberType(const String&, double*);
+bool parseToDoubleForNumberTypeWithDecimalPlaces(const String&, double*, unsigned*);
+
+// http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers
+bool parseHTMLInteger(const String&, int&);
+
+// Inline implementations of some of the functions declared above.
+
+inline bool isHTMLSpace(UChar character)
+{
+ // Histogram from Apple's page load test combined with some ad hoc browsing some other test suites.
+ //
+ // 82%: 216330 non-space characters, all > U+0020
+ // 11%: 30017 plain space characters, U+0020
+ // 5%: 12099 newline characters, U+000A
+ // 2%: 5346 tab characters, U+0009
+ //
+ // No other characters seen. No U+000C or U+000D, and no other control characters.
+ // Accordingly, we check for non-spaces first, then space, then newline, then tab, then the other characters.
+
+ return character <= ' ' && (character == ' ' || character == '\n' || character == '\t' || character == '\r' || character == '\f');
+}
+
+inline bool isNotHTMLSpace(UChar character)
+{
+ return !isHTMLSpace(character);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLParserScheduler.cpp b/Source/WebCore/html/parser/HTMLParserScheduler.cpp
new file mode 100644
index 0000000..56db1aa
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLParserScheduler.cpp
@@ -0,0 +1,114 @@
+/*
+ * 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 "HTMLParserScheduler.h"
+
+#include "FrameView.h" // Only for isLayoutTimerActive
+#include "HTMLDocumentParser.h"
+#include "Document.h"
+
+// defaultParserChunkSize is used to define how many tokens the parser will
+// process before checking against parserTimeLimit and possibly yielding.
+// This is a performance optimization to prevent checking after every token.
+static const int defaultParserChunkSize = 4096;
+
+// defaultParserTimeLimit is the seconds the parser will run in one write() call
+// before yielding. Inline <script> execution can cause it to excede the limit.
+// FIXME: We would like this value to be 0.2.
+static const double defaultParserTimeLimit = 0.500;
+
+namespace WebCore {
+
+static double parserTimeLimit(Page* page)
+{
+ // We're using the poorly named customHTMLTokenizerTimeDelay setting.
+ if (page && page->hasCustomHTMLTokenizerTimeDelay())
+ return page->customHTMLTokenizerTimeDelay();
+ 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;
+}
+
+HTMLParserScheduler::HTMLParserScheduler(HTMLDocumentParser* parser)
+ : m_parser(parser)
+ , m_parserTimeLimit(parserTimeLimit(m_parser->document()->page()))
+ , m_parserChunkSize(parserChunkSize(m_parser->document()->page()))
+ , m_continueNextChunkTimer(this, &HTMLParserScheduler::continueNextChunkTimerFired)
+ , m_isSuspendedWithActiveTimer(false)
+{
+}
+
+HTMLParserScheduler::~HTMLParserScheduler()
+{
+ m_continueNextChunkTimer.stop();
+}
+
+// FIXME: This belongs on Document.
+static bool isLayoutTimerActive(Document* doc)
+{
+ ASSERT(doc);
+ return doc->view() && doc->view()->layoutPending() && !doc->minimumLayoutDelay();
+}
+
+void HTMLParserScheduler::continueNextChunkTimerFired(Timer<HTMLParserScheduler>* timer)
+{
+ 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.
+ if (isLayoutTimerActive(m_parser->document())) {
+ m_continueNextChunkTimer.startOneShot(0);
+ return;
+ }
+ m_parser->resumeParsingAfterYield();
+}
+
+void HTMLParserScheduler::suspend()
+{
+ ASSERT(!m_isSuspendedWithActiveTimer);
+ if (!m_continueNextChunkTimer.isActive())
+ return;
+ m_isSuspendedWithActiveTimer = true;
+ m_continueNextChunkTimer.stop();
+}
+
+void HTMLParserScheduler::resume()
+{
+ ASSERT(!m_continueNextChunkTimer.isActive());
+ if (!m_isSuspendedWithActiveTimer)
+ return;
+ m_isSuspendedWithActiveTimer = false;
+ m_continueNextChunkTimer.startOneShot(0);
+}
+
+}
diff --git a/Source/WebCore/html/parser/HTMLParserScheduler.h b/Source/WebCore/html/parser/HTMLParserScheduler.h
new file mode 100644
index 0000000..3a20b2b
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLParserScheduler.h
@@ -0,0 +1,94 @@
+/*
+ * 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 HTMLParserScheduler_h
+#define HTMLParserScheduler_h
+
+#include "Timer.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class HTMLDocumentParser;
+
+class HTMLParserScheduler : public Noncopyable {
+public:
+ static PassOwnPtr<HTMLParserScheduler> create(HTMLDocumentParser* parser)
+ {
+ return adoptPtr(new HTMLParserScheduler(parser));
+ }
+ ~HTMLParserScheduler();
+
+ struct PumpSession {
+ PumpSession()
+ : processedTokens(0)
+ , startTime(currentTime())
+ {
+ }
+
+ int processedTokens;
+ double startTime;
+ };
+
+ // Inline as this is called after every token in the parser.
+ bool shouldContinueParsing(PumpSession& session)
+ {
+ if (session.processedTokens > m_parserChunkSize) {
+ session.processedTokens = 0;
+ double elapsedTime = currentTime() - session.startTime;
+ if (elapsedTime > m_parserTimeLimit) {
+ // Schedule the parser to continue and yield from the parser.
+ m_continueNextChunkTimer.startOneShot(0);
+ return false;
+ }
+ }
+
+ ++session.processedTokens;
+ return true;
+ }
+
+ bool isScheduledForResume() const { return m_isSuspendedWithActiveTimer || m_continueNextChunkTimer.isActive(); }
+
+ void suspend();
+ void resume();
+
+private:
+ HTMLParserScheduler(HTMLDocumentParser*);
+
+ void continueNextChunkTimerFired(Timer<HTMLParserScheduler>*);
+
+ HTMLDocumentParser* m_parser;
+
+ double m_parserTimeLimit;
+ int m_parserChunkSize;
+ Timer<HTMLParserScheduler> m_continueNextChunkTimer;
+ bool m_isSuspendedWithActiveTimer;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
new file mode 100644
index 0000000..d23542f
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ *
+ * 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 "HTMLPreloadScanner.h"
+
+#include "CachedResourceLoader.h"
+#include "Document.h"
+#include "HTMLDocumentParser.h"
+#include "HTMLTokenizer.h"
+#include "HTMLLinkElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "MediaList.h"
+#include "MediaQueryEvaluator.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+namespace {
+
+class PreloadTask {
+public:
+ PreloadTask(const HTMLToken& token)
+ : m_tagName(token.name().data(), token.name().size())
+ , m_linkIsStyleSheet(false)
+ , m_linkMediaAttributeIsScreen(true)
+ {
+ processAttributes(token.attributes());
+ }
+
+ void processAttributes(const HTMLToken::AttributeList& attributes)
+ {
+ if (m_tagName != scriptTag && m_tagName != imgTag && m_tagName != linkTag)
+ return;
+
+ for (HTMLToken::AttributeList::const_iterator iter = attributes.begin();
+ iter != attributes.end(); ++iter) {
+ AtomicString attributeName(iter->m_name.data(), iter->m_name.size());
+ String attributeValue(iter->m_value.data(), iter->m_value.size());
+
+ if (attributeName == charsetAttr)
+ m_charset = attributeValue;
+
+ if (m_tagName == scriptTag || m_tagName == imgTag) {
+ if (attributeName == srcAttr)
+ setUrlToLoad(attributeValue);
+ } else if (m_tagName == linkTag) {
+ if (attributeName == hrefAttr)
+ setUrlToLoad(attributeValue);
+ else if (attributeName == relAttr)
+ m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue);
+ else if (attributeName == mediaAttr)
+ m_linkMediaAttributeIsScreen = linkMediaAttributeIsScreen(attributeValue);
+ }
+ }
+ }
+
+ static bool relAttributeIsStyleSheet(const String& attributeValue)
+ {
+ HTMLLinkElement::RelAttribute rel;
+ HTMLLinkElement::tokenizeRelAttribute(attributeValue, rel);
+ return rel.m_isStyleSheet && !rel.m_isAlternate && !rel.m_isIcon && !rel.m_isDNSPrefetch;
+ }
+
+ static bool linkMediaAttributeIsScreen(const String& attributeValue)
+ {
+ if (attributeValue.isEmpty())
+ return true;
+ RefPtr<MediaList> mediaList = MediaList::createAllowingDescriptionSyntax(attributeValue);
+
+ // Only preload screen media stylesheets. Used this way, the evaluator evaluates to true for any
+ // rules containing complex queries (full evaluation is possible but it requires a frame and a style selector which
+ // may be problematic here).
+ MediaQueryEvaluator mediaQueryEvaluator("screen");
+ return mediaQueryEvaluator.eval(mediaList.get());
+ }
+
+ void setUrlToLoad(const String& attributeValue)
+ {
+ // We only respect the first src/href, per HTML5:
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#attribute-name-state
+ if (!m_urlToLoad.isEmpty())
+ return;
+ m_urlToLoad = stripLeadingAndTrailingHTMLSpaces(attributeValue);
+ }
+
+ void preload(Document* document, bool scanningBody)
+ {
+ if (m_urlToLoad.isEmpty())
+ return;
+
+ CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
+ if (m_tagName == scriptTag)
+ cachedResourceLoader->preload(CachedResource::Script, m_urlToLoad, m_charset, scanningBody);
+ else if (m_tagName == imgTag)
+ cachedResourceLoader->preload(CachedResource::ImageResource, m_urlToLoad, String(), scanningBody);
+ else if (m_tagName == linkTag && m_linkIsStyleSheet && m_linkMediaAttributeIsScreen)
+ cachedResourceLoader->preload(CachedResource::CSSStyleSheet, m_urlToLoad, m_charset, scanningBody);
+ }
+
+ const AtomicString& tagName() const { return m_tagName; }
+
+private:
+ AtomicString m_tagName;
+ String m_urlToLoad;
+ String m_charset;
+ bool m_linkIsStyleSheet;
+ bool m_linkMediaAttributeIsScreen;
+};
+
+} // namespace
+
+HTMLPreloadScanner::HTMLPreloadScanner(Document* document)
+ : m_document(document)
+ , m_cssScanner(document)
+ , m_tokenizer(HTMLTokenizer::create(HTMLDocumentParser::usePreHTML5ParserQuirks(document)))
+ , m_bodySeen(false)
+ , m_inStyle(false)
+{
+}
+
+void HTMLPreloadScanner::appendToEnd(const SegmentedString& source)
+{
+ m_source.append(source);
+}
+
+void HTMLPreloadScanner::scan()
+{
+ // FIXME: We should save and re-use these tokens in HTMLDocumentParser if
+ // the pending script doesn't end up calling document.write.
+ while (m_tokenizer->nextToken(m_source, m_token)) {
+ processToken();
+ m_token.clear();
+ }
+}
+
+void HTMLPreloadScanner::processToken()
+{
+ if (m_inStyle) {
+ if (m_token.type() == HTMLToken::Character)
+ m_cssScanner.scan(m_token, scanningBody());
+ else if (m_token.type() == HTMLToken::EndTag) {
+ m_inStyle = false;
+ m_cssScanner.reset();
+ }
+ }
+
+ if (m_token.type() != HTMLToken::StartTag)
+ return;
+
+ PreloadTask task(m_token);
+ m_tokenizer->updateStateFor(task.tagName(), m_document->frame());
+
+ if (task.tagName() == bodyTag)
+ m_bodySeen = true;
+
+ if (task.tagName() == styleTag)
+ m_inStyle = true;
+
+ task.preload(m_document, scanningBody());
+}
+
+bool HTMLPreloadScanner::scanningBody() const
+{
+ return m_document->body() || m_bodySeen;
+}
+
+}
diff --git a/Source/WebCore/html/parser/HTMLPreloadScanner.h b/Source/WebCore/html/parser/HTMLPreloadScanner.h
new file mode 100644
index 0000000..94a90e6
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLPreloadScanner.h
@@ -0,0 +1,64 @@
+/*
+ * 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
+ * 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 HTMLPreloadScanner_h
+#define HTMLPreloadScanner_h
+
+#include "CSSPreloadScanner.h"
+#include "HTMLToken.h"
+#include "SegmentedString.h"
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class Document;
+class HTMLToken;
+class HTMLTokenizer;
+class SegmentedString;
+
+class HTMLPreloadScanner : public Noncopyable {
+public:
+ HTMLPreloadScanner(Document*);
+
+ void appendToEnd(const SegmentedString&);
+ void scan();
+
+private:
+ void processToken();
+ bool scanningBody() const;
+
+ Document* m_document;
+ SegmentedString m_source;
+ CSSPreloadScanner m_cssScanner;
+ OwnPtr<HTMLTokenizer> m_tokenizer;
+ HTMLToken m_token;
+ bool m_bodySeen;
+ bool m_inStyle;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLScriptRunner.cpp b/Source/WebCore/html/parser/HTMLScriptRunner.cpp
new file mode 100644
index 0000000..2fe1d30
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLScriptRunner.cpp
@@ -0,0 +1,321 @@
+/*
+ * 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 "HTMLScriptRunner.h"
+
+#include "Attribute.h"
+#include "CachedScript.h"
+#include "CachedResourceLoader.h"
+#include "Element.h"
+#include "Event.h"
+#include "Frame.h"
+#include "HTMLInputStream.h"
+#include "HTMLNames.h"
+#include "HTMLScriptRunnerHost.h"
+#include "IgnoreDestructiveWriteCountIncrementer.h"
+#include "NestingLevelIncrementer.h"
+#include "NotImplemented.h"
+#include "ScriptElement.h"
+#include "ScriptSourceCode.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLScriptRunner::HTMLScriptRunner(Document* document, HTMLScriptRunnerHost* host)
+ : m_document(document)
+ , m_host(host)
+ , m_scriptNestingLevel(0)
+ , m_hasScriptsWaitingForStylesheets(false)
+{
+ ASSERT(m_host);
+}
+
+HTMLScriptRunner::~HTMLScriptRunner()
+{
+ // FIXME: Should we be passed a "done loading/parsing" callback sooner than destruction?
+ if (m_parsingBlockingScript.cachedScript() && m_parsingBlockingScript.watchingForLoad())
+ stopWatchingForLoad(m_parsingBlockingScript);
+
+ while (!m_scriptsToExecuteAfterParsing.isEmpty()) {
+ PendingScript pendingScript = m_scriptsToExecuteAfterParsing.takeFirst();
+ if (pendingScript.cachedScript() && pendingScript.watchingForLoad())
+ stopWatchingForLoad(pendingScript);
+ }
+}
+
+void HTMLScriptRunner::detach()
+{
+ m_document = 0;
+}
+
+static KURL documentURLForScriptExecution(Document* document)
+{
+ if (!document || !document->frame())
+ return KURL();
+
+ // Use the URL of the currently active document for this frame.
+ return document->frame()->document()->url();
+}
+
+inline PassRefPtr<Event> createScriptLoadEvent()
+{
+ return Event::create(eventNames().loadEvent, false, false);
+}
+
+inline PassRefPtr<Event> createScriptErrorEvent()
+{
+ return Event::create(eventNames().errorEvent, true, false);
+}
+
+ScriptSourceCode HTMLScriptRunner::sourceFromPendingScript(const PendingScript& script, bool& errorOccurred) const
+{
+ if (script.cachedScript()) {
+ errorOccurred = script.cachedScript()->errorOccurred();
+ ASSERT(script.cachedScript()->isLoaded());
+ return ScriptSourceCode(script.cachedScript());
+ }
+ errorOccurred = false;
+ return ScriptSourceCode(script.element()->textContent(), documentURLForScriptExecution(m_document), script.startingPosition());
+}
+
+bool HTMLScriptRunner::isPendingScriptReady(const PendingScript& script)
+{
+ m_hasScriptsWaitingForStylesheets = !m_document->haveStylesheetsLoaded();
+ if (m_hasScriptsWaitingForStylesheets)
+ return false;
+ if (script.cachedScript() && !script.cachedScript()->isLoaded())
+ return false;
+ return true;
+}
+
+void HTMLScriptRunner::executeParsingBlockingScript()
+{
+ ASSERT(m_document);
+ ASSERT(!m_scriptNestingLevel);
+ ASSERT(m_document->haveStylesheetsLoaded());
+ ASSERT(isPendingScriptReady(m_parsingBlockingScript));
+
+ InsertionPointRecord insertionPointRecord(m_host->inputStream());
+ executePendingScriptAndDispatchEvent(m_parsingBlockingScript);
+}
+
+void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendingScript)
+{
+ bool errorOccurred = false;
+ ScriptSourceCode sourceCode = sourceFromPendingScript(pendingScript, errorOccurred);
+
+ // Stop watching loads before executeScript to prevent recursion if the script reloads itself.
+ if (pendingScript.cachedScript() && pendingScript.watchingForLoad())
+ stopWatchingForLoad(pendingScript);
+
+ // Clear the pending script before possible rentrancy from executeScript()
+ RefPtr<Element> element = pendingScript.releaseElementAndClear();
+ if (ScriptElement* scriptElement = toScriptElement(element.get())) {
+ NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);
+ IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(m_document);
+ if (errorOccurred)
+ element->dispatchEvent(createScriptErrorEvent());
+ else {
+ ASSERT(isExecutingScript());
+ scriptElement->executeScript(sourceCode);
+ element->dispatchEvent(createScriptLoadEvent());
+ }
+ }
+ ASSERT(!m_scriptNestingLevel);
+}
+
+void HTMLScriptRunner::watchForLoad(PendingScript& pendingScript)
+{
+ ASSERT(!pendingScript.watchingForLoad());
+ m_host->watchForLoad(pendingScript.cachedScript());
+ pendingScript.setWatchingForLoad(true);
+}
+
+void HTMLScriptRunner::stopWatchingForLoad(PendingScript& pendingScript)
+{
+ ASSERT(pendingScript.watchingForLoad());
+ m_host->stopWatchingForLoad(pendingScript.cachedScript());
+ pendingScript.setWatchingForLoad(false);
+}
+
+// This function should match 10.2.5.11 "An end tag whose tag name is 'script'"
+// Script handling lives outside the tree builder to keep the each class simple.
+bool HTMLScriptRunner::execute(PassRefPtr<Element> scriptElement, const TextPosition1& scriptStartPosition)
+{
+ ASSERT(scriptElement);
+ // FIXME: If scripting is disabled, always just return true;
+
+ // Try to execute the script given to us.
+ runScript(scriptElement.get(), scriptStartPosition);
+
+ if (haveParsingBlockingScript()) {
+ if (m_scriptNestingLevel)
+ return false; // Block the parser. Unwind to the outermost HTMLScriptRunner::execute before continuing parsing.
+ if (!executeParsingBlockingScripts())
+ return false; // We still have a parsing blocking script, block the parser.
+ }
+ return true; // Scripts executed as expected, continue parsing.
+}
+
+bool HTMLScriptRunner::haveParsingBlockingScript() const
+{
+ return !!m_parsingBlockingScript.element();
+}
+
+bool HTMLScriptRunner::executeParsingBlockingScripts()
+{
+ while (haveParsingBlockingScript()) {
+ // We only really need to check once.
+ if (!isPendingScriptReady(m_parsingBlockingScript))
+ return false;
+ executeParsingBlockingScript();
+ }
+ return true;
+}
+
+bool HTMLScriptRunner::executeScriptsWaitingForLoad(CachedResource* cachedScript)
+{
+ ASSERT(!m_scriptNestingLevel);
+ ASSERT(haveParsingBlockingScript());
+ ASSERT_UNUSED(cachedScript, m_parsingBlockingScript.cachedScript() == cachedScript);
+ ASSERT(m_parsingBlockingScript.cachedScript()->isLoaded());
+ return executeParsingBlockingScripts();
+}
+
+bool HTMLScriptRunner::executeScriptsWaitingForStylesheets()
+{
+ ASSERT(m_document);
+ // Callers should check hasScriptsWaitingForStylesheets() before calling
+ // to prevent parser or script re-entry during </style> parsing.
+ ASSERT(hasScriptsWaitingForStylesheets());
+ ASSERT(!m_scriptNestingLevel);
+ ASSERT(m_document->haveStylesheetsLoaded());
+ return executeParsingBlockingScripts();
+}
+
+bool HTMLScriptRunner::executeScriptsWaitingForParsing()
+{
+ while (!m_scriptsToExecuteAfterParsing.isEmpty()) {
+ ASSERT(!m_scriptNestingLevel);
+ ASSERT(!haveParsingBlockingScript());
+ ASSERT(m_scriptsToExecuteAfterParsing.first().cachedScript());
+ if (!m_scriptsToExecuteAfterParsing.first().cachedScript()->isLoaded()) {
+ watchForLoad(m_scriptsToExecuteAfterParsing.first());
+ return false;
+ }
+ PendingScript first = m_scriptsToExecuteAfterParsing.takeFirst();
+ executePendingScriptAndDispatchEvent(first);
+ if (!m_document)
+ return false;
+ }
+ return true;
+}
+
+void HTMLScriptRunner::requestParsingBlockingScript(Element* element)
+{
+ if (!requestPendingScript(m_parsingBlockingScript, element))
+ return;
+
+ ASSERT(m_parsingBlockingScript.cachedScript());
+
+ // We only care about a load callback if cachedScript is not already
+ // in the cache. Callers will attempt to run the m_parsingBlockingScript
+ // if possible before returning control to the parser.
+ if (!m_parsingBlockingScript.cachedScript()->isLoaded())
+ watchForLoad(m_parsingBlockingScript);
+}
+
+void HTMLScriptRunner::requestDeferredScript(Element* element)
+{
+ PendingScript pendingScript;
+ if (!requestPendingScript(pendingScript, element))
+ return;
+
+ ASSERT(pendingScript.cachedScript());
+ m_scriptsToExecuteAfterParsing.append(pendingScript);
+}
+
+bool HTMLScriptRunner::requestPendingScript(PendingScript& pendingScript, Element* script) const
+{
+ ASSERT(!pendingScript.element());
+ const AtomicString& srcValue = script->getAttribute(srcAttr);
+ // Allow the host to disllow script loads (using the XSSAuditor, etc.)
+ if (!m_host->shouldLoadExternalScriptFromSrc(srcValue))
+ return false;
+ // FIXME: We need to resolve the url relative to the element.
+ if (!script->dispatchBeforeLoadEvent(srcValue))
+ return false;
+ pendingScript.setElement(script);
+ // This should correctly return 0 for empty or invalid srcValues.
+ CachedScript* cachedScript = m_document->cachedResourceLoader()->requestScript(srcValue, toScriptElement(script)->scriptCharset());
+ if (!cachedScript) {
+ notImplemented(); // Dispatch error event.
+ return false;
+ }
+ pendingScript.setCachedScript(cachedScript);
+ return true;
+}
+
+// This method is meant to match the HTML5 definition of "running a script"
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#running-a-script
+void HTMLScriptRunner::runScript(Element* script, const TextPosition1& scriptStartPosition)
+{
+ ASSERT(m_document);
+ ASSERT(!haveParsingBlockingScript());
+ {
+ InsertionPointRecord insertionPointRecord(m_host->inputStream());
+ NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);
+
+ ScriptElement* scriptElement = toScriptElement(script);
+ ASSERT(scriptElement);
+ if (!scriptElement->shouldExecuteAsJavaScript())
+ return;
+
+ if (script->hasAttribute(srcAttr)) {
+ if (script->hasAttribute(asyncAttr)) // Async takes precendence over defer.
+ return; // Asynchronous scripts handle themselves.
+
+ if (script->hasAttribute(deferAttr))
+ requestDeferredScript(script);
+ else
+ requestParsingBlockingScript(script);
+ } else if (!m_document->haveStylesheetsLoaded() && m_scriptNestingLevel == 1) {
+ // Block inline script execution on stylesheet load, unless we are in document.write().
+ // The latter case can only happen if a script both triggers a stylesheet load
+ // and writes an inline script. Since write is blocking we have to execute the
+ // written script immediately, ignoring the pending sheets.
+ m_parsingBlockingScript.setElement(script);
+ m_parsingBlockingScript.setStartingPosition(scriptStartPosition);
+ } else {
+ ASSERT(isExecutingScript());
+ ScriptSourceCode sourceCode(script->textContent(), documentURLForScriptExecution(m_document), scriptStartPosition);
+ scriptElement->executeScript(sourceCode);
+ }
+ }
+}
+
+}
diff --git a/Source/WebCore/html/parser/HTMLScriptRunner.h b/Source/WebCore/html/parser/HTMLScriptRunner.h
new file mode 100644
index 0000000..6cf74d8
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLScriptRunner.h
@@ -0,0 +1,102 @@
+/*
+ * 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 HTMLScriptRunner_h
+#define HTMLScriptRunner_h
+
+#include "PendingScript.h"
+#include <wtf/Deque.h>
+#include <wtf/text/TextPosition.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class CachedResource;
+class CachedScript;
+class Document;
+class Element;
+class Frame;
+class HTMLScriptRunnerHost;
+class ScriptSourceCode;
+
+class HTMLScriptRunner : public Noncopyable {
+public:
+ static PassOwnPtr<HTMLScriptRunner> create(Document* document, HTMLScriptRunnerHost* host)
+ {
+ return adoptPtr(new HTMLScriptRunner(document, host));
+ }
+ ~HTMLScriptRunner();
+
+ void detach();
+
+ // Processes the passed in script and any pending scripts if possible.
+ bool execute(PassRefPtr<Element> scriptToProcess, const TextPosition1& scriptStartPosition);
+
+ bool executeScriptsWaitingForLoad(CachedResource*);
+ bool hasScriptsWaitingForStylesheets() const { return m_hasScriptsWaitingForStylesheets; }
+ bool executeScriptsWaitingForStylesheets();
+ bool executeScriptsWaitingForParsing();
+
+ bool isExecutingScript() const { return !!m_scriptNestingLevel; }
+
+private:
+ HTMLScriptRunner(Document*, HTMLScriptRunnerHost*);
+
+ Frame* frame() const;
+
+ void executeParsingBlockingScript();
+ void executePendingScriptAndDispatchEvent(PendingScript&);
+ bool haveParsingBlockingScript() const;
+ bool executeParsingBlockingScripts();
+
+ void requestParsingBlockingScript(Element*);
+ void requestDeferredScript(Element*);
+ bool requestPendingScript(PendingScript&, Element*) const;
+
+ void runScript(Element*, const TextPosition1& scriptStartPosition);
+
+ // Helpers for dealing with HTMLScriptRunnerHost
+ void watchForLoad(PendingScript&);
+ void stopWatchingForLoad(PendingScript&);
+ bool isPendingScriptReady(const PendingScript&);
+ ScriptSourceCode sourceFromPendingScript(const PendingScript&, bool& errorOccurred) const;
+
+ Document* m_document;
+ HTMLScriptRunnerHost* m_host;
+ PendingScript m_parsingBlockingScript;
+ Deque<PendingScript> m_scriptsToExecuteAfterParsing; // http://www.whatwg.org/specs/web-apps/current-work/#list-of-scripts-that-will-execute-when-the-document-has-finished-parsing
+ unsigned m_scriptNestingLevel;
+
+ // We only want stylesheet loads to trigger script execution if script
+ // execution is currently stopped due to stylesheet loads, otherwise we'd
+ // cause nested script execution when parsing <style> tags since </style>
+ // tags can cause Document to call executeScriptsWaitingForStylesheets.
+ bool m_hasScriptsWaitingForStylesheets;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLScriptRunnerHost.h b/Source/WebCore/html/parser/HTMLScriptRunnerHost.h
new file mode 100644
index 0000000..5b40a931
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLScriptRunnerHost.h
@@ -0,0 +1,54 @@
+/*
+ * 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 HTMLScriptRunnerHost_h
+#define HTMLScriptRunnerHost_h
+
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class CachedResource;
+class Element;
+class HTMLInputStream;
+class ScriptSourceCode;
+
+class HTMLScriptRunnerHost {
+public:
+ virtual ~HTMLScriptRunnerHost() { }
+
+ // Implementors should call cachedResource->addClient() here or soon after.
+ virtual void watchForLoad(CachedResource*) = 0;
+ // Implementors must call cachedResource->removeClient() immediately.
+ virtual void stopWatchingForLoad(CachedResource*) = 0;
+
+ // Implementors can block certain script loads (for XSSAuditor, etc.)
+ virtual bool shouldLoadExternalScriptFromSrc(const AtomicString&) = 0;
+ virtual HTMLInputStream& inputStream() = 0;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLToken.h b/Source/WebCore/html/parser/HTMLToken.h
new file mode 100644
index 0000000..42cddb8
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLToken.h
@@ -0,0 +1,526 @@
+/*
+ * 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 HTMLToken_h
+#define HTMLToken_h
+
+#include "NamedNodeMap.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class HTMLToken : public Noncopyable {
+public:
+ enum Type {
+ Uninitialized,
+ DOCTYPE,
+ StartTag,
+ EndTag,
+ Comment,
+ Character,
+ EndOfFile,
+ };
+
+ class Range {
+ public:
+ int m_start;
+ int m_end;
+ };
+
+ class Attribute {
+ public:
+ Range m_nameRange;
+ Range m_valueRange;
+ WTF::Vector<UChar, 32> m_name;
+ WTF::Vector<UChar, 32> m_value;
+ };
+
+ typedef WTF::Vector<Attribute, 10> AttributeList;
+ typedef WTF::Vector<UChar, 1024> DataVector;
+
+ HTMLToken() { clear(); }
+
+ void clear(int startIndex = 0)
+ {
+ m_type = Uninitialized;
+ m_range.m_start = startIndex;
+ m_range.m_end = startIndex;
+ m_data.clear();
+ }
+
+ int startIndex() const { return m_range.m_start; }
+ int endIndex() const { return m_range.m_end; }
+
+ void end(int endIndex)
+ {
+ m_range.m_end = endIndex;
+ }
+
+ void makeEndOfFile()
+ {
+ ASSERT(m_type == Uninitialized);
+ m_type = EndOfFile;
+ }
+
+ 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);
+ }
+
+ template<typename T>
+ void beginEndTag(T characters)
+ {
+ ASSERT(m_type == Uninitialized);
+ m_type = EndTag;
+ m_selfClosing = false;
+ m_currentAttribute = 0;
+ m_attributes.clear();
+
+ m_data.append(characters);
+ }
+
+ // 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;
+ }
+
+ void beginComment()
+ {
+ ASSERT(m_type == Uninitialized);
+ m_type = Comment;
+ }
+
+ void beginDOCTYPE()
+ {
+ ASSERT(m_type == Uninitialized);
+ m_type = DOCTYPE;
+ m_doctypeData = adoptPtr(new DoctypeData());
+ }
+
+ void beginDOCTYPE(UChar character)
+ {
+ ASSERT(character);
+ beginDOCTYPE();
+ m_data.append(character);
+ }
+
+ void appendToName(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == StartTag || m_type == EndTag || m_type == DOCTYPE);
+ m_data.append(character);
+ }
+
+ template<typename T>
+ void appendToCharacter(T characters)
+ {
+ ASSERT(m_type == Character);
+ m_data.append(characters);
+ }
+
+ void appendToComment(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == Comment);
+ m_data.append(character);
+ }
+
+ 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->m_nameRange.m_start = 0;
+ m_currentAttribute->m_nameRange.m_end = 0;
+ m_currentAttribute->m_valueRange.m_start = 0;
+ m_currentAttribute->m_valueRange.m_end = 0;
+#endif
+ }
+
+ void beginAttributeName(int index)
+ {
+ m_currentAttribute->m_nameRange.m_start = index;
+ }
+
+ void endAttributeName(int index)
+ {
+ m_currentAttribute->m_nameRange.m_end = index;
+ m_currentAttribute->m_valueRange.m_start = index;
+ m_currentAttribute->m_valueRange.m_end = index;
+ }
+
+ void beginAttributeValue(int index)
+ {
+ m_currentAttribute->m_valueRange.m_start = index;
+#ifndef NDEBUG
+ m_currentAttribute->m_valueRange.m_end = 0;
+#endif
+ }
+
+ void endAttributeValue(int index)
+ {
+ m_currentAttribute->m_valueRange.m_end = index;
+ }
+
+ void appendToAttributeName(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == StartTag || m_type == EndTag);
+ ASSERT(m_currentAttribute->m_nameRange.m_start);
+ m_currentAttribute->m_name.append(character);
+ }
+
+ void appendToAttributeValue(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == StartTag || m_type == EndTag);
+ ASSERT(m_currentAttribute->m_valueRange.m_start);
+ m_currentAttribute->m_value.append(character);
+ }
+
+ Type type() const { return m_type; }
+
+ bool selfClosing() const
+ {
+ ASSERT(m_type == StartTag || m_type == EndTag);
+ return m_selfClosing;
+ }
+
+ void setSelfClosing()
+ {
+ ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
+ m_selfClosing = true;
+ }
+
+ const AttributeList& attributes() const
+ {
+ ASSERT(m_type == StartTag || m_type == EndTag);
+ return m_attributes;
+ }
+
+ const DataVector& name() const
+ {
+ ASSERT(m_type == StartTag || m_type == EndTag || m_type == DOCTYPE);
+ return m_data;
+ }
+
+ const DataVector& characters() const
+ {
+ ASSERT(m_type == Character);
+ return m_data;
+ }
+
+ const DataVector& comment() const
+ {
+ ASSERT(m_type == Comment);
+ return m_data;
+ }
+
+ // 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;
+ }
+
+ // 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;
+ }
+
+ void setPublicIdentifierToEmptyString()
+ {
+ ASSERT(m_type == DOCTYPE);
+ m_doctypeData->m_hasPublicIdentifier = true;
+ m_doctypeData->m_publicIdentifier.clear();
+ }
+
+ void setSystemIdentifierToEmptyString()
+ {
+ ASSERT(m_type == DOCTYPE);
+ m_doctypeData->m_hasSystemIdentifier = true;
+ m_doctypeData->m_systemIdentifier.clear();
+ }
+
+ bool forceQuirks() const
+ {
+ ASSERT(m_type == DOCTYPE);
+ return m_doctypeData->m_forceQuirks;
+ }
+
+ void setForceQuirks()
+ {
+ ASSERT(m_type == DOCTYPE);
+ m_doctypeData->m_forceQuirks = true;
+ }
+
+ void appendToPublicIdentifier(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == DOCTYPE);
+ ASSERT(m_doctypeData->m_hasPublicIdentifier);
+ m_doctypeData->m_publicIdentifier.append(character);
+ }
+
+ void appendToSystemIdentifier(UChar character)
+ {
+ ASSERT(character);
+ ASSERT(m_type == DOCTYPE);
+ ASSERT(m_doctypeData->m_hasSystemIdentifier);
+ m_doctypeData->m_systemIdentifier.append(character);
+ }
+
+private:
+ // FIXME: I'm not sure what the final relationship between HTMLToken and
+ // AtomicHTMLToken will be. I'm marking this a friend for now, but we'll
+ // want to end up with a cleaner interface between the two classes.
+ friend class AtomicHTMLToken;
+
+ class DoctypeData : public Noncopyable {
+ public:
+ DoctypeData()
+ : m_hasPublicIdentifier(false)
+ , m_hasSystemIdentifier(false)
+ , m_forceQuirks(false)
+ {
+ }
+
+ bool m_hasPublicIdentifier;
+ bool m_hasSystemIdentifier;
+ bool m_forceQuirks;
+ WTF::Vector<UChar> m_publicIdentifier;
+ WTF::Vector<UChar> m_systemIdentifier;
+ };
+
+ Type m_type;
+
+ // Which characters from the input stream are represented by this token.
+ Range m_range;
+
+ // "name" for DOCTYPE, StartTag, and EndTag
+ // "characters" for Character
+ // "data" for Comment
+ DataVector m_data;
+
+ // For DOCTYPE
+ OwnPtr<DoctypeData> m_doctypeData;
+
+ // For StartTag and EndTag
+ bool m_selfClosing;
+ AttributeList m_attributes;
+
+ // A pointer into m_attributes used during lexing.
+ Attribute* m_currentAttribute;
+};
+
+// FIXME: This class should eventually be named HTMLToken once we move the
+// exiting HTMLToken to be internal to the HTMLTokenizer.
+class AtomicHTMLToken : public Noncopyable {
+public:
+ 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().data(), token.name().size());
+ m_doctypeData = token.m_doctypeData.release();
+ break;
+ case HTMLToken::EndOfFile:
+ break;
+ case HTMLToken::StartTag:
+ case HTMLToken::EndTag: {
+ m_selfClosing = token.selfClosing();
+ m_name = AtomicString(token.name().data(), token.name().size());
+ const HTMLToken::AttributeList& attributes = token.attributes();
+ for (HTMLToken::AttributeList::const_iterator iter = attributes.begin();
+ iter != attributes.end(); ++iter) {
+ if (!iter->m_name.isEmpty()) {
+ String name(iter->m_name.data(), iter->m_name.size());
+ String value(iter->m_value.data(), iter->m_value.size());
+ ASSERT(iter->m_nameRange.m_start);
+ ASSERT(iter->m_nameRange.m_end);
+ ASSERT(iter->m_valueRange.m_start);
+ ASSERT(iter->m_valueRange.m_end);
+ RefPtr<Attribute> mappedAttribute = Attribute::createMapped(name, value);
+ if (!m_attributes) {
+ m_attributes = NamedNodeMap::create();
+ // Reserving capacity here improves the parser
+ // benchmark. It might be worth experimenting with
+ // the constant to see where the optimal point is.
+ m_attributes->reserveInitialCapacity(10);
+ }
+ m_attributes->insertAttribute(mappedAttribute.release(), false);
+ }
+ }
+ break;
+ }
+ case HTMLToken::Comment:
+ m_data = String(token.comment().data(), token.comment().size());
+ break;
+ case HTMLToken::Character:
+ m_externalCharacters = &token.characters();
+ break;
+ }
+ }
+
+ AtomicHTMLToken(HTMLToken::Type type, AtomicString name, PassRefPtr<NamedNodeMap> attributes = 0)
+ : m_type(type)
+ , m_name(name)
+ , m_attributes(attributes)
+ {
+ ASSERT(usesName());
+ }
+
+ HTMLToken::Type type() const { return m_type; }
+
+ const AtomicString& name() const
+ {
+ ASSERT(usesName());
+ return m_name;
+ }
+
+ void setName(const AtomicString& name)
+ {
+ ASSERT(usesName());
+ m_name = name;
+ }
+
+ bool selfClosing() const
+ {
+ ASSERT(m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag);
+ return m_selfClosing;
+ }
+
+ Attribute* getAttributeItem(const QualifiedName& attributeName)
+ {
+ ASSERT(usesAttributes());
+ if (!m_attributes)
+ return 0;
+ return m_attributes->getAttributeItem(attributeName);
+ }
+
+ NamedNodeMap* attributes() const
+ {
+ ASSERT(usesAttributes());
+ return m_attributes.get();
+ }
+
+ PassRefPtr<NamedNodeMap> takeAtributes()
+ {
+ ASSERT(usesAttributes());
+ return m_attributes.release();
+ }
+
+ const HTMLToken::DataVector& characters() const
+ {
+ ASSERT(m_type == HTMLToken::Character);
+ return *m_externalCharacters;
+ }
+
+ const String& comment() const
+ {
+ ASSERT(m_type == HTMLToken::Comment);
+ return m_data;
+ }
+
+ // FIXME: Distinguish between a missing public identifer and an empty one.
+ WTF::Vector<UChar>& publicIdentifier() const
+ {
+ ASSERT(m_type == HTMLToken::DOCTYPE);
+ return m_doctypeData->m_publicIdentifier;
+ }
+
+ // FIXME: Distinguish between a missing system identifer and an empty one.
+ WTF::Vector<UChar>& systemIdentifier() const
+ {
+ ASSERT(m_type == HTMLToken::DOCTYPE);
+ return m_doctypeData->m_systemIdentifier;
+ }
+
+ bool forceQuirks() const
+ {
+ ASSERT(m_type == HTMLToken::DOCTYPE);
+ return m_doctypeData->m_forceQuirks;
+ }
+
+private:
+ HTMLToken::Type m_type;
+
+ bool usesName() const
+ {
+ return m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag || m_type == HTMLToken::DOCTYPE;
+ }
+
+ bool usesAttributes() const
+ {
+ return m_type == HTMLToken::StartTag || m_type == HTMLToken::EndTag;
+ }
+
+ // "name" for DOCTYPE, StartTag, and EndTag
+ AtomicString m_name;
+
+ // "data" for Comment
+ String m_data;
+
+ // "characters" for Character
+ //
+ // 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 destructed.
+ const HTMLToken::DataVector* m_externalCharacters;
+
+ // For DOCTYPE
+ OwnPtr<HTMLToken::DoctypeData> m_doctypeData;
+
+ // For StartTag and EndTag
+ bool m_selfClosing;
+
+ RefPtr<NamedNodeMap> m_attributes;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLTokenizer.cpp b/Source/WebCore/html/parser/HTMLTokenizer.cpp
new file mode 100644
index 0000000..305fca2
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLTokenizer.cpp
@@ -0,0 +1,1698 @@
+/*
+ * 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.
+ *
+ * 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 "HTMLTokenizer.h"
+
+#include "HTMLEntityParser.h"
+#include "HTMLToken.h"
+#include "HTMLTreeBuilder.h"
+#include "HTMLNames.h"
+#include "NotImplemented.h"
+#include <wtf/ASCIICType.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/UnusedParam.h>
+#include <wtf/text/AtomicString.h>
+#include <wtf/text/CString.h>
+#include <wtf/unicode/Unicode.h>
+
+using namespace WTF;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+const UChar HTMLTokenizer::InputStreamPreprocessor::endOfFileMarker = 0;
+
+namespace {
+
+inline UChar toLowerCase(UChar cc)
+{
+ ASSERT(isASCIIUpper(cc));
+ const int lowerCaseOffset = 0x20;
+ return cc + lowerCaseOffset;
+}
+
+inline bool isTokenizerWhitespace(UChar cc)
+{
+ return cc == ' ' || cc == '\x0A' || cc == '\x09' || cc == '\x0C';
+}
+
+inline void advanceStringAndASSERTIgnoringCase(SegmentedString& source, const char* expectedCharacters)
+{
+ while (*expectedCharacters)
+ source.advanceAndASSERTIgnoringCase(*expectedCharacters++);
+}
+
+inline void advanceStringAndASSERT(SegmentedString& source, const char* expectedCharacters)
+{
+ while (*expectedCharacters)
+ source.advanceAndASSERT(*expectedCharacters++);
+}
+
+inline bool vectorEqualsString(const Vector<UChar, 32>& vector, const String& string)
+{
+ if (vector.size() != string.length())
+ return false;
+ const UChar* stringData = string.characters();
+ const UChar* vectorData = vector.data();
+ // FIXME: Is there a higher-level function we should be calling here?
+ return !memcmp(stringData, vectorData, vector.size() * sizeof(UChar));
+}
+
+inline bool isEndTagBufferingState(HTMLTokenizer::State state)
+{
+ 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;
+ }
+}
+
+}
+
+HTMLTokenizer::HTMLTokenizer(bool usePreHTML5ParserQuirks)
+ : m_inputStreamPreprocessor(this)
+ , m_usePreHTML5ParserQuirks(usePreHTML5ParserQuirks)
+{
+ reset();
+}
+
+HTMLTokenizer::~HTMLTokenizer()
+{
+}
+
+void HTMLTokenizer::reset()
+{
+ m_state = DataState;
+ m_token = 0;
+ m_lineNumber = 0;
+ m_skipLeadingNewLineForListing = false;
+ m_forceNullCharacterReplacement = false;
+ m_shouldAllowCDATA = false;
+ m_additionalAllowedCharacter = '\0';
+}
+
+inline bool HTMLTokenizer::processEntity(SegmentedString& source)
+{
+ bool notEnoughCharacters = false;
+ Vector<UChar, 16> decodedEntity;
+ bool success = consumeHTMLEntity(source, decodedEntity, notEnoughCharacters);
+ if (notEnoughCharacters)
+ return false;
+ if (!success) {
+ ASSERT(decodedEntity.isEmpty());
+ bufferCharacter('&');
+ } else {
+ Vector<UChar>::const_iterator iter = decodedEntity.begin();
+ for (; iter != decodedEntity.end(); ++iter)
+ bufferCharacter(*iter);
+ }
+ return true;
+}
+
+#if COMPILER(MSVC)
+// We need to disable the "unreachable code" warning because we want to assert
+// that some code points aren't reached in the state machine.
+#pragma warning(disable: 4702)
+#endif
+
+#define BEGIN_STATE(stateName) case stateName: stateName:
+#define END_STATE() ASSERT_NOT_REACHED(); break;
+
+// We use this macro when the HTML5 spec says "reconsume the current input
+// character in the <mumble> state."
+#define RECONSUME_IN(stateName) \
+ do { \
+ m_state = stateName; \
+ goto stateName; \
+ } while (false)
+
+// We use this macro when the HTML5 spec says "consume the next input
+// character ... and switch to the <mumble> state."
+#define ADVANCE_TO(stateName) \
+ do { \
+ m_state = stateName; \
+ if (!m_inputStreamPreprocessor.advance(source, m_lineNumber)) \
+ return haveBufferedCharacterToken(); \
+ cc = m_inputStreamPreprocessor.nextInputCharacter(); \
+ goto stateName; \
+ } while (false)
+
+// Sometimes there's more complicated logic in the spec that separates when
+// we consume the next input character and when we switch to a particular
+// state. We handle those cases by advancing the source directly and using
+// this macro to switch to the indicated state.
+#define SWITCH_TO(stateName) \
+ do { \
+ m_state = stateName; \
+ if (source.isEmpty() || !m_inputStreamPreprocessor.peek(source, m_lineNumber)) \
+ return haveBufferedCharacterToken(); \
+ cc = m_inputStreamPreprocessor.nextInputCharacter(); \
+ goto stateName; \
+ } while (false)
+
+
+inline void HTMLTokenizer::saveEndTagNameIfNeeded()
+{
+ ASSERT(m_token->type() != HTMLToken::Uninitialized);
+ if (m_token->type() == HTMLToken::StartTag)
+ m_appropriateEndTagName = m_token->name();
+}
+
+// We use this function when the HTML5 spec says "Emit the current <mumble>
+// token. Switch to the <mumble> state." We use the word "resume" instead of
+// switch to indicate that this macro actually returns and that we'll end up
+// in the state when we "resume" (i.e., are called again).
+bool HTMLTokenizer::emitAndResumeIn(SegmentedString& source, State state)
+{
+ m_state = state;
+ source.advance(m_lineNumber);
+ saveEndTagNameIfNeeded();
+ return true;
+}
+
+// Identical to emitAndResumeIn, except does not advance.
+bool HTMLTokenizer::emitAndReconsumeIn(SegmentedString&, State state)
+{
+ m_state = state;
+ saveEndTagNameIfNeeded();
+ return true;
+}
+
+// Used to emit the EndOfFile token.
+// Check if we have buffered characters to emit first before emitting the EOF.
+bool HTMLTokenizer::emitEndOfFile(SegmentedString& source)
+{
+ if (haveBufferedCharacterToken())
+ return true;
+ m_state = DataState;
+ source.advance(m_lineNumber);
+ m_token->clear();
+ m_token->makeEndOfFile();
+ return true;
+}
+
+bool HTMLTokenizer::flushBufferedEndTag(SegmentedString& source)
+{
+ ASSERT(m_token->type() == HTMLToken::Character || m_token->type() == HTMLToken::Uninitialized);
+ source.advance(m_lineNumber);
+ if (m_token->type() == HTMLToken::Character)
+ return true;
+ m_token->beginEndTag(m_bufferedEndTagName);
+ m_bufferedEndTagName.clear();
+ return false;
+}
+
+#define FLUSH_AND_ADVANCE_TO(stateName) \
+ do { \
+ m_state = stateName; \
+ if (flushBufferedEndTag(source)) \
+ return true; \
+ if (source.isEmpty() \
+ || !m_inputStreamPreprocessor.peek(source, m_lineNumber)) \
+ return haveBufferedCharacterToken(); \
+ cc = m_inputStreamPreprocessor.nextInputCharacter(); \
+ goto stateName; \
+ } while (false)
+
+bool HTMLTokenizer::flushEmitAndResumeIn(SegmentedString& source, State state)
+{
+ m_state = state;
+ flushBufferedEndTag(source);
+ return true;
+}
+
+bool HTMLTokenizer::nextToken(SegmentedString& source, HTMLToken& token)
+{
+ // 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();
+ if (m_state == DataState) {
+ // We're back in the data state, so we must be done with the tag.
+ return true;
+ }
+ }
+
+ if (source.isEmpty() || !m_inputStreamPreprocessor.peek(source, m_lineNumber))
+ return haveBufferedCharacterToken();
+ UChar cc = m_inputStreamPreprocessor.nextInputCharacter();
+
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-inbody
+ // Note that this logic is different than the generic \r\n collapsing
+ // handled in the input stream preprocessor. This logic is here as an
+ // "authoring convenience" so folks can write:
+ //
+ // <pre>
+ // lorem ipsum
+ // lorem ipsum
+ // </pre>
+ //
+ // without getting an extra newline at the start of their <pre> element.
+ if (m_skipLeadingNewLineForListing) {
+ m_skipLeadingNewLineForListing = false;
+ if (cc == '\n') {
+ if (m_state == DataState)
+ ADVANCE_TO(DataState);
+ if (m_state == RCDATAState)
+ ADVANCE_TO(RCDATAState);
+ // When parsing text/plain documents, we run the tokenizer in the
+ // PLAINTEXTState and ignore m_skipLeadingNewLineForListing.
+ ASSERT(m_state == PLAINTEXTState);
+ }
+ }
+
+ // Source: http://www.whatwg.org/specs/web-apps/current-work/#tokenisation0
+ switch (m_state) {
+ BEGIN_STATE(DataState) {
+ if (cc == '&')
+ 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;
+ }
+ ADVANCE_TO(TagOpenState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker)
+ return emitEndOfFile(source);
+ else {
+ bufferCharacter(cc);
+ ADVANCE_TO(DataState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(CharacterReferenceInDataState) {
+ if (!processEntity(source))
+ return haveBufferedCharacterToken();
+ SWITCH_TO(DataState);
+ }
+ END_STATE()
+
+ BEGIN_STATE(RCDATAState) {
+ if (cc == '&')
+ ADVANCE_TO(CharacterReferenceInRCDATAState);
+ else if (cc == '<')
+ ADVANCE_TO(RCDATALessThanSignState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker)
+ return emitEndOfFile(source);
+ else {
+ bufferCharacter(cc);
+ ADVANCE_TO(RCDATAState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(CharacterReferenceInRCDATAState) {
+ if (!processEntity(source))
+ return haveBufferedCharacterToken();
+ SWITCH_TO(RCDATAState);
+ }
+ END_STATE()
+
+ BEGIN_STATE(RAWTEXTState) {
+ if (cc == '<')
+ ADVANCE_TO(RAWTEXTLessThanSignState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker)
+ return emitEndOfFile(source);
+ else {
+ bufferCharacter(cc);
+ ADVANCE_TO(RAWTEXTState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataState) {
+ if (cc == '<')
+ ADVANCE_TO(ScriptDataLessThanSignState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker)
+ return emitEndOfFile(source);
+ else {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(PLAINTEXTState) {
+ if (cc == InputStreamPreprocessor::endOfFileMarker)
+ return emitEndOfFile(source);
+ else
+ bufferCharacter(cc);
+ ADVANCE_TO(PLAINTEXTState);
+ }
+ END_STATE()
+
+ BEGIN_STATE(TagOpenState) {
+ if (cc == '!')
+ ADVANCE_TO(MarkupDeclarationOpenState);
+ else if (cc == '/')
+ ADVANCE_TO(EndTagOpenState);
+ else if (isASCIIUpper(cc)) {
+ m_token->beginStartTag(toLowerCase(cc));
+ ADVANCE_TO(TagNameState);
+ } else if (isASCIILower(cc)) {
+ m_token->beginStartTag(cc);
+ 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);
+ } else {
+ parseError();
+ bufferCharacter('<');
+ RECONSUME_IN(DataState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(EndTagOpenState) {
+ if (isASCIIUpper(cc)) {
+ m_token->beginEndTag(toLowerCase(cc));
+ ADVANCE_TO(TagNameState);
+ } else if (isASCIILower(cc)) {
+ m_token->beginEndTag(cc);
+ ADVANCE_TO(TagNameState);
+ } else if (cc == '>') {
+ parseError();
+ ADVANCE_TO(DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ bufferCharacter('<');
+ bufferCharacter('/');
+ RECONSUME_IN(DataState);
+ } else {
+ parseError();
+ RECONSUME_IN(BogusCommentState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(TagNameState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(BeforeAttributeNameState);
+ else if (cc == '/')
+ ADVANCE_TO(SelfClosingStartTagState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (m_usePreHTML5ParserQuirks && cc == '<')
+ return emitAndReconsumeIn(source, DataState);
+ else if (isASCIIUpper(cc)) {
+ m_token->appendToName(toLowerCase(cc));
+ ADVANCE_TO(TagNameState);
+ } if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ RECONSUME_IN(DataState);
+ } else {
+ m_token->appendToName(cc);
+ ADVANCE_TO(TagNameState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(RCDATALessThanSignState) {
+ if (cc == '/') {
+ m_temporaryBuffer.clear();
+ ASSERT(m_bufferedEndTagName.isEmpty());
+ ADVANCE_TO(RCDATAEndTagOpenState);
+ } else {
+ bufferCharacter('<');
+ RECONSUME_IN(RCDATAState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(RCDATAEndTagOpenState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(toLowerCase(cc));
+ ADVANCE_TO(RCDATAEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(cc);
+ ADVANCE_TO(RCDATAEndTagNameState);
+ } else {
+ bufferCharacter('<');
+ bufferCharacter('/');
+ RECONSUME_IN(RCDATAState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(RCDATAEndTagNameState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(toLowerCase(cc));
+ ADVANCE_TO(RCDATAEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(cc);
+ ADVANCE_TO(RCDATAEndTagNameState);
+ } else {
+ if (isTokenizerWhitespace(cc)) {
+ if (isAppropriateEndTag())
+ FLUSH_AND_ADVANCE_TO(BeforeAttributeNameState);
+ } else if (cc == '/') {
+ if (isAppropriateEndTag())
+ FLUSH_AND_ADVANCE_TO(SelfClosingStartTagState);
+ } else if (cc == '>') {
+ if (isAppropriateEndTag())
+ return flushEmitAndResumeIn(source, DataState);
+ }
+ bufferCharacter('<');
+ bufferCharacter('/');
+ m_token->appendToCharacter(m_temporaryBuffer);
+ m_bufferedEndTagName.clear();
+ RECONSUME_IN(RCDATAState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(RAWTEXTLessThanSignState) {
+ if (cc == '/') {
+ m_temporaryBuffer.clear();
+ ASSERT(m_bufferedEndTagName.isEmpty());
+ ADVANCE_TO(RAWTEXTEndTagOpenState);
+ } else {
+ bufferCharacter('<');
+ RECONSUME_IN(RAWTEXTState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(RAWTEXTEndTagOpenState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(toLowerCase(cc));
+ ADVANCE_TO(RAWTEXTEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(cc);
+ ADVANCE_TO(RAWTEXTEndTagNameState);
+ } else {
+ bufferCharacter('<');
+ bufferCharacter('/');
+ RECONSUME_IN(RAWTEXTState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(RAWTEXTEndTagNameState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(toLowerCase(cc));
+ ADVANCE_TO(RAWTEXTEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(cc);
+ ADVANCE_TO(RAWTEXTEndTagNameState);
+ } else {
+ if (isTokenizerWhitespace(cc)) {
+ if (isAppropriateEndTag())
+ FLUSH_AND_ADVANCE_TO(BeforeAttributeNameState);
+ } else if (cc == '/') {
+ if (isAppropriateEndTag())
+ FLUSH_AND_ADVANCE_TO(SelfClosingStartTagState);
+ } else if (cc == '>') {
+ if (isAppropriateEndTag())
+ return flushEmitAndResumeIn(source, DataState);
+ }
+ bufferCharacter('<');
+ bufferCharacter('/');
+ m_token->appendToCharacter(m_temporaryBuffer);
+ m_bufferedEndTagName.clear();
+ RECONSUME_IN(RAWTEXTState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataLessThanSignState) {
+ if (cc == '/') {
+ m_temporaryBuffer.clear();
+ ASSERT(m_bufferedEndTagName.isEmpty());
+ ADVANCE_TO(ScriptDataEndTagOpenState);
+ } else if (cc == '!') {
+ bufferCharacter('<');
+ bufferCharacter('!');
+ ADVANCE_TO(ScriptDataEscapeStartState);
+ } else {
+ bufferCharacter('<');
+ RECONSUME_IN(ScriptDataState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataEndTagOpenState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(toLowerCase(cc));
+ ADVANCE_TO(ScriptDataEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(cc);
+ ADVANCE_TO(ScriptDataEndTagNameState);
+ } else {
+ bufferCharacter('<');
+ bufferCharacter('/');
+ RECONSUME_IN(ScriptDataState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataEndTagNameState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(toLowerCase(cc));
+ ADVANCE_TO(ScriptDataEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(cc);
+ ADVANCE_TO(ScriptDataEndTagNameState);
+ } else {
+ if (isTokenizerWhitespace(cc)) {
+ if (isAppropriateEndTag())
+ FLUSH_AND_ADVANCE_TO(BeforeAttributeNameState);
+ } else if (cc == '/') {
+ if (isAppropriateEndTag())
+ FLUSH_AND_ADVANCE_TO(SelfClosingStartTagState);
+ } else if (cc == '>') {
+ if (isAppropriateEndTag())
+ return flushEmitAndResumeIn(source, DataState);
+ }
+ bufferCharacter('<');
+ bufferCharacter('/');
+ m_token->appendToCharacter(m_temporaryBuffer);
+ m_bufferedEndTagName.clear();
+ RECONSUME_IN(ScriptDataState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataEscapeStartState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataEscapeStartDashState);
+ } else
+ RECONSUME_IN(ScriptDataState);
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataEscapeStartDashState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataEscapedDashDashState);
+ } else
+ RECONSUME_IN(ScriptDataState);
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataEscapedState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataEscapedDashState);
+ } else if (cc == '<')
+ ADVANCE_TO(ScriptDataEscapedLessThanSignState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ RECONSUME_IN(DataState);
+ } else {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataEscapedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataEscapedDashState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataEscapedDashDashState);
+ } else if (cc == '<')
+ ADVANCE_TO(ScriptDataEscapedLessThanSignState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ RECONSUME_IN(DataState);
+ } else {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataEscapedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataEscapedDashDashState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataEscapedDashDashState);
+ } else if (cc == '<')
+ ADVANCE_TO(ScriptDataEscapedLessThanSignState);
+ else if (cc == '>') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataState);
+ } if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ RECONSUME_IN(DataState);
+ } else {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataEscapedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataEscapedLessThanSignState) {
+ if (cc == '/') {
+ m_temporaryBuffer.clear();
+ ASSERT(m_bufferedEndTagName.isEmpty());
+ ADVANCE_TO(ScriptDataEscapedEndTagOpenState);
+ } else if (isASCIIUpper(cc)) {
+ bufferCharacter('<');
+ bufferCharacter(cc);
+ m_temporaryBuffer.clear();
+ m_temporaryBuffer.append(toLowerCase(cc));
+ ADVANCE_TO(ScriptDataDoubleEscapeStartState);
+ } else if (isASCIILower(cc)) {
+ bufferCharacter('<');
+ bufferCharacter(cc);
+ m_temporaryBuffer.clear();
+ m_temporaryBuffer.append(cc);
+ ADVANCE_TO(ScriptDataDoubleEscapeStartState);
+ } else {
+ bufferCharacter('<');
+ RECONSUME_IN(ScriptDataEscapedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataEscapedEndTagOpenState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(toLowerCase(cc));
+ ADVANCE_TO(ScriptDataEscapedEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(cc);
+ ADVANCE_TO(ScriptDataEscapedEndTagNameState);
+ } else {
+ bufferCharacter('<');
+ bufferCharacter('/');
+ RECONSUME_IN(ScriptDataEscapedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataEscapedEndTagNameState) {
+ if (isASCIIUpper(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(toLowerCase(cc));
+ ADVANCE_TO(ScriptDataEscapedEndTagNameState);
+ } else if (isASCIILower(cc)) {
+ m_temporaryBuffer.append(cc);
+ addToPossibleEndTag(cc);
+ ADVANCE_TO(ScriptDataEscapedEndTagNameState);
+ } else {
+ if (isTokenizerWhitespace(cc)) {
+ if (isAppropriateEndTag())
+ FLUSH_AND_ADVANCE_TO(BeforeAttributeNameState);
+ } else if (cc == '/') {
+ if (isAppropriateEndTag())
+ FLUSH_AND_ADVANCE_TO(SelfClosingStartTagState);
+ } else if (cc == '>') {
+ if (isAppropriateEndTag())
+ return flushEmitAndResumeIn(source, DataState);
+ }
+ bufferCharacter('<');
+ bufferCharacter('/');
+ m_token->appendToCharacter(m_temporaryBuffer);
+ m_bufferedEndTagName.clear();
+ RECONSUME_IN(ScriptDataEscapedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataDoubleEscapeStartState) {
+ if (isTokenizerWhitespace(cc) || cc == '/' || cc == '>') {
+ bufferCharacter(cc);
+ if (temporaryBufferIs(scriptTag.localName()))
+ ADVANCE_TO(ScriptDataDoubleEscapedState);
+ else
+ ADVANCE_TO(ScriptDataEscapedState);
+ } else if (isASCIIUpper(cc)) {
+ bufferCharacter(cc);
+ m_temporaryBuffer.append(toLowerCase(cc));
+ ADVANCE_TO(ScriptDataDoubleEscapeStartState);
+ } else if (isASCIILower(cc)) {
+ bufferCharacter(cc);
+ m_temporaryBuffer.append(cc);
+ ADVANCE_TO(ScriptDataDoubleEscapeStartState);
+ } else
+ RECONSUME_IN(ScriptDataEscapedState);
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataDoubleEscapedState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataDoubleEscapedDashState);
+ } else if (cc == '<') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ RECONSUME_IN(DataState);
+ } else {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataDoubleEscapedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataDoubleEscapedDashState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataDoubleEscapedDashDashState);
+ } else if (cc == '<') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ RECONSUME_IN(DataState);
+ } else {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataDoubleEscapedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataDoubleEscapedDashDashState) {
+ if (cc == '-') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataDoubleEscapedDashDashState);
+ } else if (cc == '<') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
+ } else if (cc == '>') {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ RECONSUME_IN(DataState);
+ } else {
+ bufferCharacter(cc);
+ ADVANCE_TO(ScriptDataDoubleEscapedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataDoubleEscapedLessThanSignState) {
+ if (cc == '/') {
+ bufferCharacter(cc);
+ m_temporaryBuffer.clear();
+ ADVANCE_TO(ScriptDataDoubleEscapeEndState);
+ } else
+ RECONSUME_IN(ScriptDataDoubleEscapedState);
+ }
+ END_STATE()
+
+ BEGIN_STATE(ScriptDataDoubleEscapeEndState) {
+ if (isTokenizerWhitespace(cc) || cc == '/' || cc == '>') {
+ bufferCharacter(cc);
+ if (temporaryBufferIs(scriptTag.localName()))
+ ADVANCE_TO(ScriptDataEscapedState);
+ else
+ ADVANCE_TO(ScriptDataDoubleEscapedState);
+ } else if (isASCIIUpper(cc)) {
+ bufferCharacter(cc);
+ m_temporaryBuffer.append(toLowerCase(cc));
+ ADVANCE_TO(ScriptDataDoubleEscapeEndState);
+ } else if (isASCIILower(cc)) {
+ bufferCharacter(cc);
+ m_temporaryBuffer.append(cc);
+ ADVANCE_TO(ScriptDataDoubleEscapeEndState);
+ } else
+ RECONSUME_IN(ScriptDataDoubleEscapedState);
+ }
+ END_STATE()
+
+ BEGIN_STATE(BeforeAttributeNameState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(BeforeAttributeNameState);
+ else if (cc == '/')
+ ADVANCE_TO(SelfClosingStartTagState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (m_usePreHTML5ParserQuirks && cc == '<')
+ return emitAndReconsumeIn(source, DataState);
+ else if (isASCIIUpper(cc)) {
+ m_token->addNewAttribute();
+ m_token->beginAttributeName(source.numberOfCharactersConsumed());
+ m_token->appendToAttributeName(toLowerCase(cc));
+ ADVANCE_TO(AttributeNameState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ RECONSUME_IN(DataState);
+ } else {
+ if (cc == '"' || cc == '\'' || cc == '<' || cc == '=')
+ parseError();
+ m_token->addNewAttribute();
+ m_token->beginAttributeName(source.numberOfCharactersConsumed());
+ m_token->appendToAttributeName(cc);
+ ADVANCE_TO(AttributeNameState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(AttributeNameState) {
+ if (isTokenizerWhitespace(cc)) {
+ m_token->endAttributeName(source.numberOfCharactersConsumed());
+ ADVANCE_TO(AfterAttributeNameState);
+ } else if (cc == '/') {
+ m_token->endAttributeName(source.numberOfCharactersConsumed());
+ ADVANCE_TO(SelfClosingStartTagState);
+ } else if (cc == '=') {
+ m_token->endAttributeName(source.numberOfCharactersConsumed());
+ ADVANCE_TO(BeforeAttributeValueState);
+ } else if (cc == '>') {
+ m_token->endAttributeName(source.numberOfCharactersConsumed());
+ return emitAndResumeIn(source, DataState);
+ } else if (m_usePreHTML5ParserQuirks && cc == '<') {
+ m_token->endAttributeName(source.numberOfCharactersConsumed());
+ return emitAndReconsumeIn(source, DataState);
+ } else if (isASCIIUpper(cc)) {
+ m_token->appendToAttributeName(toLowerCase(cc));
+ ADVANCE_TO(AttributeNameState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->endAttributeName(source.numberOfCharactersConsumed());
+ RECONSUME_IN(DataState);
+ } else {
+ if (cc == '"' || cc == '\'' || cc == '<' || cc == '=')
+ parseError();
+ m_token->appendToAttributeName(cc);
+ ADVANCE_TO(AttributeNameState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(AfterAttributeNameState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(AfterAttributeNameState);
+ else if (cc == '/')
+ ADVANCE_TO(SelfClosingStartTagState);
+ else if (cc == '=')
+ ADVANCE_TO(BeforeAttributeValueState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (m_usePreHTML5ParserQuirks && cc == '<')
+ return emitAndReconsumeIn(source, DataState);
+ else if (isASCIIUpper(cc)) {
+ m_token->addNewAttribute();
+ m_token->beginAttributeName(source.numberOfCharactersConsumed());
+ m_token->appendToAttributeName(toLowerCase(cc));
+ ADVANCE_TO(AttributeNameState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ RECONSUME_IN(DataState);
+ } else {
+ if (cc == '"' || cc == '\'' || cc == '<')
+ parseError();
+ m_token->addNewAttribute();
+ m_token->beginAttributeName(source.numberOfCharactersConsumed());
+ m_token->appendToAttributeName(cc);
+ ADVANCE_TO(AttributeNameState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(BeforeAttributeValueState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(BeforeAttributeValueState);
+ else if (cc == '"') {
+ m_token->beginAttributeValue(source.numberOfCharactersConsumed() + 1);
+ ADVANCE_TO(AttributeValueDoubleQuotedState);
+ } else if (cc == '&') {
+ m_token->beginAttributeValue(source.numberOfCharactersConsumed());
+ RECONSUME_IN(AttributeValueUnquotedState);
+ } else if (cc == '\'') {
+ m_token->beginAttributeValue(source.numberOfCharactersConsumed() + 1);
+ ADVANCE_TO(AttributeValueSingleQuotedState);
+ } else if (cc == '>') {
+ parseError();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ RECONSUME_IN(DataState);
+ } else {
+ if (cc == '<' || cc == '=' || cc == '`')
+ parseError();
+ m_token->beginAttributeValue(source.numberOfCharactersConsumed());
+ m_token->appendToAttributeValue(cc);
+ ADVANCE_TO(AttributeValueUnquotedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(AttributeValueDoubleQuotedState) {
+ if (cc == '"') {
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ ADVANCE_TO(AfterAttributeValueQuotedState);
+ } else if (cc == '&') {
+ m_additionalAllowedCharacter = '"';
+ ADVANCE_TO(CharacterReferenceInAttributeValueState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ RECONSUME_IN(DataState);
+ } else {
+ m_token->appendToAttributeValue(cc);
+ ADVANCE_TO(AttributeValueDoubleQuotedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(AttributeValueSingleQuotedState) {
+ if (cc == '\'') {
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ ADVANCE_TO(AfterAttributeValueQuotedState);
+ } else if (cc == '&') {
+ m_additionalAllowedCharacter = '\'';
+ ADVANCE_TO(CharacterReferenceInAttributeValueState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ RECONSUME_IN(DataState);
+ } else {
+ m_token->appendToAttributeValue(cc);
+ ADVANCE_TO(AttributeValueSingleQuotedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(AttributeValueUnquotedState) {
+ if (isTokenizerWhitespace(cc)) {
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ ADVANCE_TO(BeforeAttributeNameState);
+ } else if (cc == '&') {
+ m_additionalAllowedCharacter = '>';
+ ADVANCE_TO(CharacterReferenceInAttributeValueState);
+ } else if (cc == '>') {
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->endAttributeValue(source.numberOfCharactersConsumed());
+ RECONSUME_IN(DataState);
+ } else {
+ if (cc == '"' || cc == '\'' || cc == '<' || cc == '=' || cc == '`')
+ parseError();
+ m_token->appendToAttributeValue(cc);
+ ADVANCE_TO(AttributeValueUnquotedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(CharacterReferenceInAttributeValueState) {
+ bool notEnoughCharacters = false;
+ Vector<UChar, 16> decodedEntity;
+ bool success = consumeHTMLEntity(source, decodedEntity, notEnoughCharacters, m_additionalAllowedCharacter);
+ if (notEnoughCharacters)
+ return haveBufferedCharacterToken();
+ if (!success) {
+ ASSERT(decodedEntity.isEmpty());
+ m_token->appendToAttributeValue('&');
+ } else {
+ Vector<UChar>::const_iterator iter = decodedEntity.begin();
+ for (; iter != decodedEntity.end(); ++iter)
+ m_token->appendToAttributeValue(*iter);
+ }
+ // 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);
+ else if (m_additionalAllowedCharacter == '\'')
+ SWITCH_TO(AttributeValueSingleQuotedState);
+ else if (m_additionalAllowedCharacter == '>')
+ SWITCH_TO(AttributeValueUnquotedState);
+ else
+ ASSERT_NOT_REACHED();
+ }
+ END_STATE()
+
+ BEGIN_STATE(AfterAttributeValueQuotedState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(BeforeAttributeNameState);
+ else if (cc == '/')
+ ADVANCE_TO(SelfClosingStartTagState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (m_usePreHTML5ParserQuirks && cc == '<')
+ return emitAndReconsumeIn(source, DataState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ RECONSUME_IN(DataState);
+ } else {
+ parseError();
+ RECONSUME_IN(BeforeAttributeNameState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(SelfClosingStartTagState) {
+ if (cc == '>') {
+ m_token->setSelfClosing();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ RECONSUME_IN(DataState);
+ } else {
+ parseError();
+ RECONSUME_IN(BeforeAttributeNameState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(BogusCommentState) {
+ m_token->beginComment();
+ RECONSUME_IN(ContinueBogusCommentState);
+ }
+ END_STATE()
+
+ BEGIN_STATE(ContinueBogusCommentState) {
+ if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker)
+ return emitAndReconsumeIn(source, DataState);
+ else {
+ m_token->appendToComment(cc);
+ ADVANCE_TO(ContinueBogusCommentState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(MarkupDeclarationOpenState) {
+ DEFINE_STATIC_LOCAL(String, dashDashString, ("--"));
+ DEFINE_STATIC_LOCAL(String, doctypeString, ("doctype"));
+ DEFINE_STATIC_LOCAL(String, cdataString, ("[CDATA["));
+ if (cc == '-') {
+ SegmentedString::LookAheadResult result = source.lookAhead(dashDashString);
+ if (result == SegmentedString::DidMatch) {
+ source.advanceAndASSERT('-');
+ source.advanceAndASSERT('-');
+ m_token->beginComment();
+ 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");
+ 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[");
+ SWITCH_TO(CDATASectionState);
+ } else if (result == SegmentedString::NotEnoughCharacters)
+ return haveBufferedCharacterToken();
+ }
+ parseError();
+ RECONSUME_IN(BogusCommentState);
+ }
+ END_STATE()
+
+ BEGIN_STATE(CommentStartState) {
+ if (cc == '-')
+ ADVANCE_TO(CommentStartDashState);
+ else if (cc == '>') {
+ parseError();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ m_token->appendToComment(cc);
+ ADVANCE_TO(CommentState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(CommentStartDashState) {
+ if (cc == '-')
+ ADVANCE_TO(CommentEndState);
+ else if (cc == '>') {
+ parseError();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ m_token->appendToComment('-');
+ m_token->appendToComment(cc);
+ ADVANCE_TO(CommentState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(CommentState) {
+ if (cc == '-')
+ ADVANCE_TO(CommentEndDashState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ m_token->appendToComment(cc);
+ ADVANCE_TO(CommentState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(CommentEndDashState) {
+ if (cc == '-')
+ ADVANCE_TO(CommentEndState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ m_token->appendToComment('-');
+ m_token->appendToComment(cc);
+ ADVANCE_TO(CommentState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(CommentEndState) {
+ if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (cc == '!') {
+ parseError();
+ ADVANCE_TO(CommentEndBangState);
+ } else if (cc == '-') {
+ parseError();
+ m_token->appendToComment('-');
+ ADVANCE_TO(CommentEndState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ parseError();
+ m_token->appendToComment('-');
+ m_token->appendToComment('-');
+ m_token->appendToComment(cc);
+ ADVANCE_TO(CommentState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(CommentEndBangState) {
+ if (cc == '-') {
+ m_token->appendToComment('-');
+ m_token->appendToComment('-');
+ m_token->appendToComment('!');
+ ADVANCE_TO(CommentEndDashState);
+ } else if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ m_token->appendToComment('-');
+ m_token->appendToComment('-');
+ m_token->appendToComment('!');
+ m_token->appendToComment(cc);
+ ADVANCE_TO(CommentState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(DOCTYPEState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(BeforeDOCTYPENameState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->beginDOCTYPE();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ parseError();
+ RECONSUME_IN(BeforeDOCTYPENameState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(BeforeDOCTYPENameState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(BeforeDOCTYPENameState);
+ else if (isASCIIUpper(cc)) {
+ m_token->beginDOCTYPE(toLowerCase(cc));
+ ADVANCE_TO(DOCTYPENameState);
+ } else if (cc == '>') {
+ parseError();
+ m_token->beginDOCTYPE();
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->beginDOCTYPE();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ m_token->beginDOCTYPE(cc);
+ ADVANCE_TO(DOCTYPENameState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(DOCTYPENameState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(AfterDOCTYPENameState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (isASCIIUpper(cc)) {
+ m_token->appendToName(toLowerCase(cc));
+ ADVANCE_TO(DOCTYPENameState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ m_token->appendToName(cc);
+ ADVANCE_TO(DOCTYPENameState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(AfterDOCTYPENameState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(AfterDOCTYPENameState);
+ if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ DEFINE_STATIC_LOCAL(String, publicString, ("public"));
+ DEFINE_STATIC_LOCAL(String, systemString, ("system"));
+ if (cc == 'P' || cc == 'p') {
+ SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(publicString);
+ if (result == SegmentedString::DidMatch) {
+ advanceStringAndASSERTIgnoringCase(source, "public");
+ 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");
+ SWITCH_TO(AfterDOCTYPESystemKeywordState);
+ } else if (result == SegmentedString::NotEnoughCharacters)
+ return haveBufferedCharacterToken();
+ }
+ parseError();
+ m_token->setForceQuirks();
+ ADVANCE_TO(BogusDOCTYPEState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(AfterDOCTYPEPublicKeywordState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(BeforeDOCTYPEPublicIdentifierState);
+ else if (cc == '"') {
+ parseError();
+ m_token->setPublicIdentifierToEmptyString();
+ ADVANCE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
+ } else if (cc == '\'') {
+ parseError();
+ m_token->setPublicIdentifierToEmptyString();
+ ADVANCE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
+ } else if (cc == '>') {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ parseError();
+ m_token->setForceQuirks();
+ ADVANCE_TO(BogusDOCTYPEState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(BeforeDOCTYPEPublicIdentifierState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(BeforeDOCTYPEPublicIdentifierState);
+ else if (cc == '"') {
+ m_token->setPublicIdentifierToEmptyString();
+ ADVANCE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
+ } else if (cc == '\'') {
+ m_token->setPublicIdentifierToEmptyString();
+ ADVANCE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
+ } else if (cc == '>') {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ parseError();
+ m_token->setForceQuirks();
+ ADVANCE_TO(BogusDOCTYPEState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(DOCTYPEPublicIdentifierDoubleQuotedState) {
+ if (cc == '"')
+ ADVANCE_TO(AfterDOCTYPEPublicIdentifierState);
+ else if (cc == '>') {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ m_token->appendToPublicIdentifier(cc);
+ ADVANCE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(DOCTYPEPublicIdentifierSingleQuotedState) {
+ if (cc == '\'')
+ ADVANCE_TO(AfterDOCTYPEPublicIdentifierState);
+ else if (cc == '>') {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ m_token->appendToPublicIdentifier(cc);
+ ADVANCE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(AfterDOCTYPEPublicIdentifierState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(BetweenDOCTYPEPublicAndSystemIdentifiersState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (cc == '"') {
+ parseError();
+ m_token->setSystemIdentifierToEmptyString();
+ ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
+ } else if (cc == '\'') {
+ parseError();
+ m_token->setSystemIdentifierToEmptyString();
+ ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ parseError();
+ m_token->setForceQuirks();
+ ADVANCE_TO(BogusDOCTYPEState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(BetweenDOCTYPEPublicAndSystemIdentifiersState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(BetweenDOCTYPEPublicAndSystemIdentifiersState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (cc == '"') {
+ m_token->setSystemIdentifierToEmptyString();
+ ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
+ } else if (cc == '\'') {
+ m_token->setSystemIdentifierToEmptyString();
+ ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ parseError();
+ m_token->setForceQuirks();
+ ADVANCE_TO(BogusDOCTYPEState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(AfterDOCTYPESystemKeywordState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(BeforeDOCTYPESystemIdentifierState);
+ else if (cc == '"') {
+ parseError();
+ m_token->setSystemIdentifierToEmptyString();
+ ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
+ } else if (cc == '\'') {
+ parseError();
+ m_token->setSystemIdentifierToEmptyString();
+ ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
+ } else if (cc == '>') {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ parseError();
+ m_token->setForceQuirks();
+ ADVANCE_TO(BogusDOCTYPEState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(BeforeDOCTYPESystemIdentifierState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(BeforeDOCTYPESystemIdentifierState);
+ if (cc == '"') {
+ m_token->setSystemIdentifierToEmptyString();
+ ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
+ } else if (cc == '\'') {
+ m_token->setSystemIdentifierToEmptyString();
+ ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
+ } else if (cc == '>') {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ parseError();
+ m_token->setForceQuirks();
+ ADVANCE_TO(BogusDOCTYPEState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(DOCTYPESystemIdentifierDoubleQuotedState) {
+ if (cc == '"')
+ ADVANCE_TO(AfterDOCTYPESystemIdentifierState);
+ else if (cc == '>') {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ m_token->appendToSystemIdentifier(cc);
+ ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(DOCTYPESystemIdentifierSingleQuotedState) {
+ if (cc == '\'')
+ ADVANCE_TO(AfterDOCTYPESystemIdentifierState);
+ else if (cc == '>') {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndResumeIn(source, DataState);
+ } else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ m_token->appendToSystemIdentifier(cc);
+ ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(AfterDOCTYPESystemIdentifierState) {
+ if (isTokenizerWhitespace(cc))
+ ADVANCE_TO(AfterDOCTYPESystemIdentifierState);
+ else if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker) {
+ parseError();
+ m_token->setForceQuirks();
+ return emitAndReconsumeIn(source, DataState);
+ } else {
+ parseError();
+ ADVANCE_TO(BogusDOCTYPEState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(BogusDOCTYPEState) {
+ if (cc == '>')
+ return emitAndResumeIn(source, DataState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker)
+ return emitAndReconsumeIn(source, DataState);
+ ADVANCE_TO(BogusDOCTYPEState);
+ }
+ END_STATE()
+
+ BEGIN_STATE(CDATASectionState) {
+ if (cc == ']')
+ ADVANCE_TO(CDATASectionRightSquareBracketState);
+ else if (cc == InputStreamPreprocessor::endOfFileMarker)
+ RECONSUME_IN(DataState);
+ else {
+ bufferCharacter(cc);
+ ADVANCE_TO(CDATASectionState);
+ }
+ }
+ END_STATE()
+
+ BEGIN_STATE(CDATASectionRightSquareBracketState) {
+ if (cc == ']')
+ ADVANCE_TO(CDATASectionDoubleRightSquareBracketState);
+ else {
+ bufferCharacter(']');
+ RECONSUME_IN(CDATASectionState);
+ }
+ }
+
+ BEGIN_STATE(CDATASectionDoubleRightSquareBracketState) {
+ if (cc == '>')
+ ADVANCE_TO(DataState);
+ else {
+ bufferCharacter(']');
+ bufferCharacter(']');
+ RECONSUME_IN(CDATASectionState);
+ }
+ }
+ END_STATE()
+
+ }
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+void HTMLTokenizer::updateStateFor(const AtomicString& tagName, Frame* frame)
+{
+ if (tagName == textareaTag || tagName == titleTag)
+ setState(RCDATAState);
+ else if (tagName == plaintextTag)
+ setState(PLAINTEXTState);
+ else if (tagName == scriptTag)
+ setState(ScriptDataState);
+ else if (tagName == styleTag
+ || tagName == iframeTag
+ || tagName == xmpTag
+ || (tagName == noembedTag && HTMLTreeBuilder::pluginsEnabled(frame))
+ || tagName == noframesTag
+ || (tagName == noscriptTag && HTMLTreeBuilder::scriptEnabled(frame)))
+ setState(RAWTEXTState);
+}
+
+inline bool HTMLTokenizer::temporaryBufferIs(const String& expectedString)
+{
+ return vectorEqualsString(m_temporaryBuffer, expectedString);
+}
+
+inline void HTMLTokenizer::addToPossibleEndTag(UChar cc)
+{
+ ASSERT(isEndTagBufferingState(m_state));
+ m_bufferedEndTagName.append(cc);
+}
+
+inline bool HTMLTokenizer::isAppropriateEndTag()
+{
+ return m_bufferedEndTagName == m_appropriateEndTagName;
+}
+
+inline void HTMLTokenizer::bufferCharacter(UChar character)
+{
+ ASSERT(character != InputStreamPreprocessor::endOfFileMarker);
+ m_token->ensureIsCharacterToken();
+ m_token->appendToCharacter(character);
+}
+
+inline void HTMLTokenizer::parseError()
+{
+ notImplemented();
+}
+
+inline bool HTMLTokenizer::haveBufferedCharacterToken()
+{
+ return m_token->type() == HTMLToken::Character;
+}
+
+}
diff --git a/Source/WebCore/html/parser/HTMLTokenizer.h b/Source/WebCore/html/parser/HTMLTokenizer.h
new file mode 100644
index 0000000..f16b049
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLTokenizer.h
@@ -0,0 +1,316 @@
+/*
+ * 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
+ * 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 HTMLTokenizer_h
+#define HTMLTokenizer_h
+
+#include "SegmentedString.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+class Element;
+class Frame;
+class HTMLToken;
+
+class HTMLTokenizer : public Noncopyable {
+public:
+ enum State {
+ DataState,
+ CharacterReferenceInDataState,
+ RCDATAState,
+ CharacterReferenceInRCDATAState,
+ RAWTEXTState,
+ ScriptDataState,
+ PLAINTEXTState,
+ TagOpenState,
+ EndTagOpenState,
+ TagNameState,
+ RCDATALessThanSignState,
+ RCDATAEndTagOpenState,
+ RCDATAEndTagNameState,
+ RAWTEXTLessThanSignState,
+ RAWTEXTEndTagOpenState,
+ RAWTEXTEndTagNameState,
+ ScriptDataLessThanSignState,
+ ScriptDataEndTagOpenState,
+ ScriptDataEndTagNameState,
+ ScriptDataEscapeStartState,
+ ScriptDataEscapeStartDashState,
+ ScriptDataEscapedState,
+ ScriptDataEscapedDashState,
+ ScriptDataEscapedDashDashState,
+ ScriptDataEscapedLessThanSignState,
+ ScriptDataEscapedEndTagOpenState,
+ ScriptDataEscapedEndTagNameState,
+ ScriptDataDoubleEscapeStartState,
+ ScriptDataDoubleEscapedState,
+ ScriptDataDoubleEscapedDashState,
+ ScriptDataDoubleEscapedDashDashState,
+ ScriptDataDoubleEscapedLessThanSignState,
+ ScriptDataDoubleEscapeEndState,
+ BeforeAttributeNameState,
+ AttributeNameState,
+ AfterAttributeNameState,
+ BeforeAttributeValueState,
+ AttributeValueDoubleQuotedState,
+ AttributeValueSingleQuotedState,
+ AttributeValueUnquotedState,
+ CharacterReferenceInAttributeValueState,
+ AfterAttributeValueQuotedState,
+ SelfClosingStartTagState,
+ BogusCommentState,
+ // 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,
+ CommentState,
+ CommentEndDashState,
+ CommentEndState,
+ CommentEndBangState,
+ DOCTYPEState,
+ BeforeDOCTYPENameState,
+ DOCTYPENameState,
+ AfterDOCTYPENameState,
+ AfterDOCTYPEPublicKeywordState,
+ BeforeDOCTYPEPublicIdentifierState,
+ DOCTYPEPublicIdentifierDoubleQuotedState,
+ DOCTYPEPublicIdentifierSingleQuotedState,
+ AfterDOCTYPEPublicIdentifierState,
+ BetweenDOCTYPEPublicAndSystemIdentifiersState,
+ AfterDOCTYPESystemKeywordState,
+ BeforeDOCTYPESystemIdentifierState,
+ DOCTYPESystemIdentifierDoubleQuotedState,
+ DOCTYPESystemIdentifierSingleQuotedState,
+ AfterDOCTYPESystemIdentifierState,
+ BogusDOCTYPEState,
+ CDATASectionState,
+ // These CDATA states are not in the HTML5 spec, but we use them internally.
+ CDATASectionRightSquareBracketState,
+ CDATASectionDoubleRightSquareBracketState,
+ };
+
+ static PassOwnPtr<HTMLTokenizer> create(bool usePreHTML5ParserQuirks) { return adoptPtr(new HTMLTokenizer(usePreHTML5ParserQuirks)); }
+ ~HTMLTokenizer();
+
+ void reset();
+
+ // 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&);
+
+ int lineNumber() const { return m_lineNumber; }
+ int columnNumber() const { return 1; } // Matches LegacyHTMLDocumentParser.h behavior.
+
+ State state() const { return m_state; }
+ void setState(State state) { m_state = state; }
+
+ // 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, Frame*);
+
+ // Hack to skip leading newline in <pre>/<listing> for authoring ease.
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-inbody
+ void setSkipLeadingNewLineForListing(bool value) { m_skipLeadingNewLineForListing = value; }
+
+ bool forceNullCharacterReplacement() const { return m_forceNullCharacterReplacement; }
+ void setForceNullCharacterReplacement(bool value) { m_forceNullCharacterReplacement = value; }
+
+ bool shouldAllowCDATA() const { return m_shouldAllowCDATA; }
+ void setShouldAllowCDATA(bool value) { m_shouldAllowCDATA = value; }
+
+ bool shouldSkipNullCharacters() const
+ {
+ return !m_forceNullCharacterReplacement
+ && (m_state == DataState
+ || m_state == RCDATAState
+ || m_state == RAWTEXTState
+ || m_state == PLAINTEXTState);
+ }
+
+private:
+ // http://www.whatwg.org/specs/web-apps/current-work/#preprocessing-the-input-stream
+ class InputStreamPreprocessor : public Noncopyable {
+ public:
+ InputStreamPreprocessor(HTMLTokenizer* tokenizer)
+ : m_tokenizer(tokenizer)
+ , m_nextInputCharacter('\0')
+ , m_skipNextNewLine(false)
+ {
+ }
+
+ UChar nextInputCharacter() const { return m_nextInputCharacter; }
+
+ // 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, int& lineNumber)
+ {
+ PeekAgain:
+ m_nextInputCharacter = *source;
+
+ // Every branch in this function is expensive, so we have a
+ // fast-reject branch for characters that don't require special
+ // handling. Please run the parser benchmark whenever you touch
+ // this function. It's very hot.
+ static const UChar specialCharacterMask = '\n' | '\r' | '\0';
+ if (m_nextInputCharacter & ~specialCharacterMask) {
+ m_skipNextNewLine = false;
+ return true;
+ }
+
+ if (m_nextInputCharacter == '\n' && m_skipNextNewLine) {
+ m_skipNextNewLine = false;
+ source.advancePastNewline(lineNumber);
+ if (source.isEmpty())
+ return false;
+ m_nextInputCharacter = *source;
+ }
+ if (m_nextInputCharacter == '\r') {
+ m_nextInputCharacter = '\n';
+ m_skipNextNewLine = true;
+ } else {
+ m_skipNextNewLine = false;
+ // FIXME: The spec indicates that the surrogate pair range as well as
+ // a number of specific character values are parse errors and should be replaced
+ // 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 (m_tokenizer->shouldSkipNullCharacters()) {
+ source.advancePastNonNewline();
+ if (source.isEmpty())
+ return false;
+ goto PeekAgain;
+ }
+ m_nextInputCharacter = 0xFFFD;
+ }
+ }
+ return true;
+ }
+
+ // Returns whether there are more characters in |source| after advancing.
+ bool advance(SegmentedString& source, int& lineNumber)
+ {
+ source.advance(lineNumber);
+ if (source.isEmpty())
+ return false;
+ return peek(source, lineNumber);
+ }
+
+ static const UChar endOfFileMarker;
+
+ private:
+ bool shouldTreatNullAsEndOfFileMarker(SegmentedString& source) const
+ {
+ return source.isClosed() && source.length() == 1;
+ }
+
+ HTMLTokenizer* m_tokenizer;
+
+ // http://www.whatwg.org/specs/web-apps/current-work/#next-input-character
+ UChar m_nextInputCharacter;
+ bool m_skipNextNewLine;
+ };
+
+ HTMLTokenizer(bool usePreHTML5ParserQuirks);
+
+ inline bool processEntity(SegmentedString&);
+
+ inline void parseError();
+ inline void bufferCharacter(UChar);
+ inline void bufferCodePoint(unsigned);
+
+ inline bool emitAndResumeIn(SegmentedString&, State);
+ inline bool emitAndReconsumeIn(SegmentedString&, State);
+ inline bool emitEndOfFile(SegmentedString&);
+ inline bool flushEmitAndResumeIn(SegmentedString&, State);
+
+ // 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&);
+
+ // 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(UChar cc);
+ inline void saveEndTagNameIfNeeded();
+ inline bool isAppropriateEndTag();
+
+ inline bool haveBufferedCharacterToken();
+
+ State m_state;
+
+ Vector<UChar, 32> m_appropriateEndTagName;
+
+ // 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;
+ int m_lineNumber;
+
+ bool m_skipLeadingNewLineForListing;
+ bool m_forceNullCharacterReplacement;
+ bool m_shouldAllowCDATA;
+
+ // http://www.whatwg.org/specs/web-apps/current-work/#temporary-buffer
+ Vector<UChar, 32> m_temporaryBuffer;
+
+ // 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<UChar, 32> m_bufferedEndTagName;
+
+ // http://www.whatwg.org/specs/web-apps/current-work/#additional-allowed-character
+ UChar m_additionalAllowedCharacter;
+
+ // http://www.whatwg.org/specs/web-apps/current-work/#preprocessing-the-input-stream
+ InputStreamPreprocessor m_inputStreamPreprocessor;
+
+ bool m_usePreHTML5ParserQuirks;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp
new file mode 100644
index 0000000..02713e5
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp
@@ -0,0 +1,2822 @@
+/*
+ * 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 GOOGLE 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 GOOGLE 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 "HTMLTreeBuilder.h"
+
+#include "CharacterNames.h"
+#include "Comment.h"
+#include "DocumentFragment.h"
+#include "DocumentType.h"
+#include "Frame.h"
+#include "HTMLDocument.h"
+#include "HTMLDocumentParser.h"
+#include "HTMLElementFactory.h"
+#include "HTMLFormElement.h"
+#include "HTMLHtmlElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "HTMLScriptElement.h"
+#include "HTMLToken.h"
+#include "HTMLTokenizer.h"
+#include "LocalizedStrings.h"
+#include "MathMLNames.h"
+#include "NotImplemented.h"
+#include "SVGNames.h"
+#include "ScriptController.h"
+#include "Text.h"
+#include "XLinkNames.h"
+#include "XMLNSNames.h"
+#include "XMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static const int uninitializedLineNumberValue = -1;
+
+static TextPosition1 uninitializedPositionValue1()
+{
+ return TextPosition1(WTF::OneBasedNumber::fromOneBasedInt(-1), WTF::OneBasedNumber::base());
+}
+
+namespace {
+
+inline bool isHTMLSpaceOrReplacementCharacter(UChar character)
+{
+ return isHTMLSpace(character) || character == replacementCharacter;
+}
+
+inline bool isAllWhitespace(const String& string)
+{
+ return string.isAllSpecialCharacters<isHTMLSpace>();
+}
+
+inline bool isAllWhitespaceOrReplacementCharacters(const String& string)
+{
+ return string.isAllSpecialCharacters<isHTMLSpaceOrReplacementCharacter>();
+}
+
+bool isNumberedHeaderTag(const AtomicString& tagName)
+{
+ return tagName == h1Tag
+ || tagName == h2Tag
+ || tagName == h3Tag
+ || tagName == h4Tag
+ || tagName == h5Tag
+ || tagName == h6Tag;
+}
+
+bool isCaptionColOrColgroupTag(const AtomicString& tagName)
+{
+ return tagName == captionTag
+ || tagName == colTag
+ || tagName == colgroupTag;
+}
+
+bool isTableCellContextTag(const AtomicString& tagName)
+{
+ return tagName == thTag || tagName == tdTag;
+}
+
+bool isTableBodyContextTag(const AtomicString& tagName)
+{
+ return tagName == tbodyTag
+ || tagName == tfootTag
+ || tagName == theadTag;
+}
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#special
+bool isSpecialNode(Node* node)
+{
+ if (node->hasTagName(MathMLNames::miTag)
+ || node->hasTagName(MathMLNames::moTag)
+ || node->hasTagName(MathMLNames::mnTag)
+ || node->hasTagName(MathMLNames::msTag)
+ || node->hasTagName(MathMLNames::mtextTag)
+ || node->hasTagName(MathMLNames::annotation_xmlTag)
+ || node->hasTagName(SVGNames::foreignObjectTag)
+ || node->hasTagName(SVGNames::descTag)
+ || node->hasTagName(SVGNames::titleTag))
+ return true;
+ if (node->namespaceURI() != xhtmlNamespaceURI)
+ return false;
+ const AtomicString& tagName = node->localName();
+ return tagName == addressTag
+ || tagName == appletTag
+ || tagName == areaTag
+ || tagName == articleTag
+ || tagName == asideTag
+ || tagName == baseTag
+ || tagName == basefontTag
+ || tagName == bgsoundTag
+ || tagName == blockquoteTag
+ || tagName == bodyTag
+ || tagName == brTag
+ || tagName == buttonTag
+ || tagName == captionTag
+ || tagName == centerTag
+ || tagName == colTag
+ || tagName == colgroupTag
+ || tagName == commandTag
+ || tagName == ddTag
+ || tagName == detailsTag
+ || tagName == dirTag
+ || tagName == divTag
+ || tagName == dlTag
+ || tagName == dtTag
+ || tagName == embedTag
+ || tagName == fieldsetTag
+ || tagName == figcaptionTag
+ || tagName == figureTag
+ || tagName == footerTag
+ || tagName == formTag
+ || tagName == frameTag
+ || tagName == framesetTag
+ || isNumberedHeaderTag(tagName)
+ || tagName == headTag
+ || tagName == headerTag
+ || tagName == hgroupTag
+ || tagName == hrTag
+ || tagName == htmlTag
+ || tagName == iframeTag
+ || tagName == imgTag
+ || tagName == inputTag
+ || tagName == isindexTag
+ || tagName == liTag
+ || tagName == linkTag
+ || tagName == listingTag
+ || tagName == marqueeTag
+ || tagName == menuTag
+ || tagName == metaTag
+ || tagName == navTag
+ || tagName == noembedTag
+ || tagName == noframesTag
+ || tagName == noscriptTag
+ || tagName == objectTag
+ || tagName == olTag
+ || tagName == pTag
+ || tagName == paramTag
+ || tagName == plaintextTag
+ || tagName == preTag
+ || tagName == scriptTag
+ || tagName == sectionTag
+ || tagName == selectTag
+ || tagName == styleTag
+ || tagName == summaryTag
+ || tagName == tableTag
+ || isTableBodyContextTag(tagName)
+ || tagName == tdTag
+ || tagName == textareaTag
+ || tagName == thTag
+ || tagName == titleTag
+ || tagName == trTag
+ || tagName == ulTag
+ || tagName == wbrTag
+ || tagName == xmpTag;
+}
+
+bool isNonAnchorNonNobrFormattingTag(const AtomicString& tagName)
+{
+ return tagName == bTag
+ || tagName == bigTag
+ || tagName == codeTag
+ || tagName == emTag
+ || tagName == fontTag
+ || tagName == iTag
+ || tagName == sTag
+ || tagName == smallTag
+ || tagName == strikeTag
+ || tagName == strongTag
+ || tagName == ttTag
+ || tagName == uTag;
+}
+
+bool isNonAnchorFormattingTag(const AtomicString& tagName)
+{
+ return tagName == nobrTag
+ || isNonAnchorNonNobrFormattingTag(tagName);
+}
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#formatting
+bool isFormattingTag(const AtomicString& tagName)
+{
+ return tagName == aTag || isNonAnchorFormattingTag(tagName);
+}
+
+HTMLFormElement* closestFormAncestor(Element* element)
+{
+ while (element) {
+ if (element->hasTagName(formTag))
+ return static_cast<HTMLFormElement*>(element);
+ ContainerNode* parent = element->parentNode();
+ if (!parent || !parent->isElementNode())
+ return 0;
+ element = static_cast<Element*>(parent);
+ }
+ return 0;
+}
+
+} // namespace
+
+class HTMLTreeBuilder::ExternalCharacterTokenBuffer : public Noncopyable {
+public:
+ explicit ExternalCharacterTokenBuffer(AtomicHTMLToken& token)
+ : m_current(token.characters().data())
+ , m_end(m_current + token.characters().size())
+ {
+ ASSERT(!isEmpty());
+ }
+
+ explicit ExternalCharacterTokenBuffer(const String& string)
+ : m_current(string.characters())
+ , m_end(m_current + string.length())
+ {
+ ASSERT(!isEmpty());
+ }
+
+ ~ExternalCharacterTokenBuffer()
+ {
+ ASSERT(isEmpty());
+ }
+
+ bool isEmpty() const { return m_current == m_end; }
+
+ void skipLeadingWhitespace()
+ {
+ skipLeading<isHTMLSpace>();
+ }
+
+ String takeLeadingWhitespace()
+ {
+ return takeLeading<isHTMLSpace>();
+ }
+
+ String takeLeadingNonWhitespace()
+ {
+ return takeLeading<isNotHTMLSpace>();
+ }
+
+ String takeRemaining()
+ {
+ ASSERT(!isEmpty());
+ const UChar* start = m_current;
+ m_current = m_end;
+ return String(start, m_current - start);
+ }
+
+ void giveRemainingTo(Vector<UChar>& recipient)
+ {
+ recipient.append(m_current, m_end - m_current);
+ m_current = m_end;
+ }
+
+ String takeRemainingWhitespace()
+ {
+ ASSERT(!isEmpty());
+ Vector<UChar> whitespace;
+ do {
+ 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()
+ {
+ ASSERT(!isEmpty());
+ while (characterPredicate(*m_current)) {
+ if (++m_current == m_end)
+ return;
+ }
+ }
+
+ template<bool characterPredicate(UChar)>
+ String takeLeading()
+ {
+ ASSERT(!isEmpty());
+ const UChar* start = m_current;
+ skipLeading<characterPredicate>();
+ if (start == m_current)
+ return String();
+ return String(start, m_current - start);
+ }
+
+ const UChar* m_current;
+ const UChar* m_end;
+};
+
+
+HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* document, bool reportErrors, bool usePreHTML5ParserQuirks)
+ : m_framesetOk(true)
+ , m_document(document)
+ , m_tree(document, FragmentScriptingAllowed, false)
+ , m_reportErrors(reportErrors)
+ , m_isPaused(false)
+ , m_insertionMode(InitialMode)
+ , m_originalInsertionMode(InitialMode)
+ , m_parser(parser)
+ , m_scriptToProcessStartPosition(uninitializedPositionValue1())
+ , m_lastScriptElementStartPosition(TextPosition0::belowRangePosition())
+ , m_usePreHTML5ParserQuirks(usePreHTML5ParserQuirks)
+ , m_hasPendingForeignInsertionModeSteps(false)
+{
+}
+
+// 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, FragmentScriptingPermission scriptingPermission, bool usePreHTML5ParserQuirks)
+ : m_framesetOk(true)
+ , m_fragmentContext(fragment, contextElement, scriptingPermission)
+ , m_document(m_fragmentContext.document())
+ , m_tree(m_document, scriptingPermission, true)
+ , m_reportErrors(false) // FIXME: Why not report errors in fragments?
+ , m_isPaused(false)
+ , m_insertionMode(InitialMode)
+ , m_originalInsertionMode(InitialMode)
+ , m_parser(parser)
+ , m_scriptToProcessStartPosition(uninitializedPositionValue1())
+ , m_lastScriptElementStartPosition(TextPosition0::belowRangePosition())
+ , m_usePreHTML5ParserQuirks(usePreHTML5ParserQuirks)
+ , m_hasPendingForeignInsertionModeSteps(false)
+{
+ 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
+ m_document->setCompatibilityMode(contextElement->document()->compatibilityMode());
+ processFakeStartTag(htmlTag);
+ resetInsertionModeAppropriately();
+ m_tree.setForm(closestFormAncestor(contextElement));
+ }
+}
+
+HTMLTreeBuilder::~HTMLTreeBuilder()
+{
+}
+
+void HTMLTreeBuilder::detach()
+{
+ // This call makes little sense in fragment mode, but for consistency
+ // DocumentParser expects detach() to always be called before it's destroyed.
+ m_document = 0;
+ // 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)
+ , m_scriptingPermission(FragmentScriptingAllowed)
+{
+}
+
+HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
+ : m_dummyDocumentForFragmentParsing(HTMLDocument::create(0, KURL(), fragment->document()->baseURI()))
+ , m_fragment(fragment)
+ , m_contextElement(contextElement)
+ , m_scriptingPermission(scriptingPermission)
+{
+ m_dummyDocumentForFragmentParsing->setCompatibilityMode(fragment->document()->compatibilityMode());
+}
+
+Document* HTMLTreeBuilder::FragmentParsingContext::document() const
+{
+ ASSERT(m_fragment);
+ return m_dummyDocumentForFragmentParsing.get();
+}
+
+void HTMLTreeBuilder::FragmentParsingContext::finished()
+{
+ // Populate the DocumentFragment with the parsed content now that we're done.
+ ContainerNode* root = m_dummyDocumentForFragmentParsing.get();
+ if (m_contextElement)
+ root = m_dummyDocumentForFragmentParsing->documentElement();
+ m_fragment->takeAllChildrenFrom(root);
+}
+
+HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext()
+{
+}
+
+PassRefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition1& scriptStartPosition)
+{
+ // 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.
+ m_isPaused = false;
+ scriptStartPosition = m_scriptToProcessStartPosition;
+ m_scriptToProcessStartPosition = uninitializedPositionValue1();
+ return m_scriptToProcess.release();
+}
+
+void HTMLTreeBuilder::constructTreeFromToken(HTMLToken& rawToken)
+{
+ AtomicHTMLToken token(rawToken);
+ constructTreeFromAtomicToken(token);
+}
+
+void HTMLTreeBuilder::constructTreeFromAtomicToken(AtomicHTMLToken& token)
+{
+ processToken(token);
+
+ // Swallowing U+0000 characters isn't in the HTML5 spec, but turning all
+ // the U+0000 characters into replacement characters has compatibility
+ // problems.
+ m_parser->tokenizer()->setForceNullCharacterReplacement(m_insertionMode == TextMode || m_insertionMode == InForeignContentMode);
+ m_parser->tokenizer()->setShouldAllowCDATA(m_insertionMode == InForeignContentMode && m_tree.currentElement()->namespaceURI() != xhtmlNamespaceURI);
+}
+
+void HTMLTreeBuilder::processToken(AtomicHTMLToken& token)
+{
+ switch (token.type()) {
+ case HTMLToken::Uninitialized:
+ ASSERT_NOT_REACHED();
+ break;
+ case HTMLToken::DOCTYPE:
+ processDoctypeToken(token);
+ break;
+ case HTMLToken::StartTag:
+ processStartTag(token);
+ break;
+ case HTMLToken::EndTag:
+ processEndTag(token);
+ break;
+ case HTMLToken::Comment:
+ processComment(token);
+ return;
+ case HTMLToken::Character:
+ processCharacter(token);
+ break;
+ case HTMLToken::EndOfFile:
+ processEndOfFile(token);
+ break;
+ }
+}
+
+void HTMLTreeBuilder::processDoctypeToken(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::DOCTYPE);
+ if (m_insertionMode == InitialMode) {
+ m_tree.insertDoctype(token);
+ setInsertionMode(BeforeHTMLMode);
+ return;
+ }
+ if (m_insertionMode == InTableTextMode) {
+ defaultForInTableText();
+ processDoctypeToken(token);
+ return;
+ }
+ parseError(token);
+}
+
+void HTMLTreeBuilder::processFakeStartTag(const QualifiedName& tagName, PassRefPtr<NamedNodeMap> attributes)
+{
+ // FIXME: We'll need a fancier conversion than just "localName" for SVG/MathML tags.
+ AtomicHTMLToken fakeToken(HTMLToken::StartTag, tagName.localName(), attributes);
+ processStartTag(fakeToken);
+}
+
+void HTMLTreeBuilder::processFakeEndTag(const QualifiedName& tagName)
+{
+ // FIXME: We'll need a fancier conversion than just "localName" for SVG/MathML tags.
+ AtomicHTMLToken fakeToken(HTMLToken::EndTag, tagName.localName());
+ processEndTag(fakeToken);
+}
+
+void HTMLTreeBuilder::processFakeCharacters(const String& characters)
+{
+ ASSERT(!characters.isEmpty());
+ ExternalCharacterTokenBuffer buffer(characters);
+ processCharacterBuffer(buffer);
+}
+
+void HTMLTreeBuilder::processFakePEndTagIfPInButtonScope()
+{
+ if (!m_tree.openElements()->inButtonScope(pTag.localName()))
+ return;
+ AtomicHTMLToken endP(HTMLToken::EndTag, pTag.localName());
+ processEndTag(endP);
+}
+
+PassRefPtr<NamedNodeMap> HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken& token)
+{
+ RefPtr<NamedNodeMap> attributes = token.takeAtributes();
+ if (!attributes)
+ attributes = NamedNodeMap::create();
+ else {
+ attributes->removeAttribute(nameAttr);
+ attributes->removeAttribute(actionAttr);
+ attributes->removeAttribute(promptAttr);
+ }
+
+ RefPtr<Attribute> mappedAttribute = Attribute::createMapped(nameAttr, isindexTag.localName());
+ attributes->insertAttribute(mappedAttribute.release(), false);
+ return attributes.release();
+}
+
+void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::StartTag);
+ ASSERT(token.name() == isindexTag);
+ parseError(token);
+ if (m_tree.form())
+ return;
+ notImplemented(); // Acknowledge self-closing flag
+ processFakeStartTag(formTag);
+ RefPtr<Attribute> actionAttribute = token.getAttributeItem(actionAttr);
+ if (actionAttribute) {
+ ASSERT(m_tree.currentElement()->hasTagName(formTag));
+ m_tree.currentElement()->setAttribute(actionAttr, actionAttribute->value());
+ }
+ processFakeStartTag(hrTag);
+ processFakeStartTag(labelTag);
+ RefPtr<Attribute> promptAttribute = token.getAttributeItem(promptAttr);
+ if (promptAttribute)
+ processFakeCharacters(promptAttribute->value());
+ else
+ processFakeCharacters(searchableIndexIntroduction());
+ processFakeStartTag(inputTag, attributesForIsindexInput(token));
+ notImplemented(); // This second set of characters may be needed by non-english locales.
+ processFakeEndTag(labelTag);
+ processFakeStartTag(hrTag);
+ processFakeEndTag(formTag);
+}
+
+namespace {
+
+bool isLi(const Element* element)
+{
+ return element->hasTagName(liTag);
+}
+
+bool isDdOrDt(const Element* element)
+{
+ return element->hasTagName(ddTag)
+ || element->hasTagName(dtTag);
+}
+
+}
+
+template <bool shouldClose(const Element*)>
+void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken& token)
+{
+ m_framesetOk = false;
+ HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
+ while (1) {
+ Element* node = nodeRecord->element();
+ if (shouldClose(node)) {
+ processFakeEndTag(node->tagQName());
+ break;
+ }
+ if (isSpecialNode(node) && !node->hasTagName(addressTag) && !node->hasTagName(divTag) && !node->hasTagName(pTag))
+ break;
+ nodeRecord = nodeRecord->next();
+ }
+ processFakePEndTagIfPInButtonScope();
+ m_tree.insertHTMLElement(token);
+}
+
+namespace {
+
+typedef HashMap<AtomicString, QualifiedName> PrefixedNameToQualifiedNameMap;
+
+void mapLoweredLocalNameToName(PrefixedNameToQualifiedNameMap* map, QualifiedName** names, size_t length)
+{
+ 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);
+ }
+}
+
+void adjustSVGTagNameCase(AtomicHTMLToken& token)
+{
+ static PrefixedNameToQualifiedNameMap* caseMap = 0;
+ if (!caseMap) {
+ caseMap = new PrefixedNameToQualifiedNameMap;
+ size_t length = 0;
+ QualifiedName** svgTags = SVGNames::getSVGTags(&length);
+ mapLoweredLocalNameToName(caseMap, svgTags, length);
+ }
+
+ const QualifiedName& casedName = caseMap->get(token.name());
+ if (casedName.localName().isNull())
+ return;
+ token.setName(casedName.localName());
+}
+
+template<QualifiedName** getAttrs(size_t* length)>
+void adjustAttributes(AtomicHTMLToken& token)
+{
+ static PrefixedNameToQualifiedNameMap* caseMap = 0;
+ if (!caseMap) {
+ caseMap = new PrefixedNameToQualifiedNameMap;
+ size_t length = 0;
+ QualifiedName** attrs = getAttrs(&length);
+ mapLoweredLocalNameToName(caseMap, attrs, length);
+ }
+
+ NamedNodeMap* attributes = token.attributes();
+ if (!attributes)
+ return;
+
+ for (unsigned x = 0; x < attributes->length(); ++x) {
+ Attribute* attribute = attributes->attributeItem(x);
+ const QualifiedName& casedName = caseMap->get(attribute->localName());
+ if (!casedName.localName().isNull())
+ attribute->parserSetName(casedName);
+ }
+}
+
+void adjustSVGAttributes(AtomicHTMLToken& token)
+{
+ adjustAttributes<SVGNames::getSVGAttrs>(token);
+}
+
+void adjustMathMLAttributes(AtomicHTMLToken& token)
+{
+ adjustAttributes<MathMLNames::getMathMLAttrs>(token);
+}
+
+void addNamesWithPrefix(PrefixedNameToQualifiedNameMap* map, const AtomicString& prefix, QualifiedName** names, size_t length)
+{
+ for (size_t i = 0; i < length; ++i) {
+ QualifiedName* name = names[i];
+ const AtomicString& localName = name->localName();
+ AtomicString prefixColonLocalName(prefix + ":" + localName);
+ QualifiedName nameWithPrefix(prefix, localName, name->namespaceURI());
+ map->add(prefixColonLocalName, nameWithPrefix);
+ }
+}
+
+void adjustForeignAttributes(AtomicHTMLToken& token)
+{
+ static PrefixedNameToQualifiedNameMap* map = 0;
+ if (!map) {
+ map = new PrefixedNameToQualifiedNameMap;
+ size_t length = 0;
+ QualifiedName** attrs = XLinkNames::getXLinkAttrs(&length);
+ addNamesWithPrefix(map, "xlink", attrs, length);
+
+ attrs = XMLNames::getXMLAttrs(&length);
+ addNamesWithPrefix(map, "xml", attrs, length);
+
+ map->add("xmlns", XMLNSNames::xmlnsAttr);
+ map->add("xmlns:xlink", QualifiedName("xmlns", "xlink", XMLNSNames::xmlnsNamespaceURI));
+ }
+
+ NamedNodeMap* attributes = token.attributes();
+ if (!attributes)
+ return;
+
+ for (unsigned x = 0; x < attributes->length(); ++x) {
+ Attribute* attribute = attributes->attributeItem(x);
+ const QualifiedName& name = map->get(attribute->localName());
+ if (!name.localName().isNull())
+ attribute->parserSetName(name);
+ }
+}
+
+}
+
+void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::StartTag);
+ if (token.name() == htmlTag) {
+ m_tree.insertHTMLHtmlStartTagInBody(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) {
+ bool didProcess = processStartTagForInHead(token);
+ ASSERT_UNUSED(didProcess, didProcess);
+ return;
+ }
+ if (token.name() == bodyTag) {
+ if (!m_tree.openElements()->secondElementIsHTMLBodyElement() || m_tree.openElements()->hasOnlyOneElement()) {
+ ASSERT(isParsingFragment());
+ return;
+ }
+ m_tree.insertHTMLBodyStartTagInBody(token);
+ return;
+ }
+ if (token.name() == framesetTag) {
+ parseError(token);
+ if (!m_tree.openElements()->secondElementIsHTMLBodyElement() || m_tree.openElements()->hasOnlyOneElement()) {
+ ASSERT(isParsingFragment());
+ return;
+ }
+ if (!m_framesetOk)
+ return;
+ ExceptionCode ec = 0;
+ m_tree.openElements()->bodyElement()->remove(ec);
+ ASSERT(!ec);
+ 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(InFramesetMode);
+ 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() == menuTag
+ || token.name() == navTag
+ || token.name() == olTag
+ || token.name() == pTag
+ || token.name() == sectionTag
+ || token.name() == summaryTag
+ || token.name() == ulTag) {
+ processFakePEndTagIfPInButtonScope();
+ m_tree.insertHTMLElement(token);
+ return;
+ }
+ if (isNumberedHeaderTag(token.name())) {
+ processFakePEndTagIfPInButtonScope();
+ if (isNumberedHeaderTag(m_tree.currentElement()->localName())) {
+ parseError(token);
+ m_tree.openElements()->pop();
+ }
+ m_tree.insertHTMLElement(token);
+ return;
+ }
+ if (token.name() == preTag || token.name() == listingTag) {
+ processFakePEndTagIfPInButtonScope();
+ m_tree.insertHTMLElement(token);
+ m_parser->tokenizer()->setSkipLeadingNewLineForListing(true);
+ m_framesetOk = false;
+ return;
+ }
+ if (token.name() == formTag) {
+ if (m_tree.form()) {
+ parseError(token);
+ return;
+ }
+ processFakePEndTagIfPInButtonScope();
+ m_tree.insertHTMLFormElement(token);
+ return;
+ }
+ if (token.name() == liTag) {
+ processCloseWhenNestedTag<isLi>(token);
+ return;
+ }
+ if (token.name() == ddTag || token.name() == dtTag) {
+ processCloseWhenNestedTag<isDdOrDt>(token);
+ return;
+ }
+ if (token.name() == plaintextTag) {
+ processFakePEndTagIfPInButtonScope();
+ m_tree.insertHTMLElement(token);
+ m_parser->tokenizer()->setState(HTMLTokenizer::PLAINTEXTState);
+ return;
+ }
+ if (token.name() == buttonTag) {
+ if (m_tree.openElements()->inScope(buttonTag)) {
+ parseError(token);
+ processFakeEndTag(buttonTag);
+ reprocessStartTag(token); // FIXME: Could we just fall through here?
+ return;
+ }
+ m_tree.reconstructTheActiveFormattingElements();
+ m_tree.insertHTMLElement(token);
+ m_framesetOk = false;
+ return;
+ }
+ 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.reconstructTheActiveFormattingElements();
+ m_tree.insertFormattingElement(token);
+ return;
+ }
+ if (isNonAnchorNonNobrFormattingTag(token.name())) {
+ m_tree.reconstructTheActiveFormattingElements();
+ m_tree.insertFormattingElement(token);
+ return;
+ }
+ if (token.name() == nobrTag) {
+ m_tree.reconstructTheActiveFormattingElements();
+ if (m_tree.openElements()->inScope(nobrTag)) {
+ parseError(token);
+ processFakeEndTag(nobrTag);
+ m_tree.reconstructTheActiveFormattingElements();
+ }
+ m_tree.insertFormattingElement(token);
+ return;
+ }
+ if (token.name() == appletTag
+ || token.name() == marqueeTag
+ || token.name() == objectTag) {
+ m_tree.reconstructTheActiveFormattingElements();
+ m_tree.insertHTMLElement(token);
+ m_tree.activeFormattingElements()->appendMarker();
+ m_framesetOk = false;
+ return;
+ }
+ if (token.name() == tableTag) {
+ if (!m_document->inQuirksMode() && m_tree.openElements()->inButtonScope(pTag))
+ processFakeEndTag(pTag);
+ m_tree.insertHTMLElement(token);
+ m_framesetOk = false;
+ setInsertionMode(InTableMode);
+ return;
+ }
+ if (token.name() == imageTag) {
+ parseError(token);
+ // Apparently we're not supposed to ask.
+ token.setName(imgTag.localName());
+ prepareToReprocessToken();
+ // 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) {
+ m_tree.reconstructTheActiveFormattingElements();
+ m_tree.insertSelfClosingHTMLElement(token);
+ m_framesetOk = false;
+ return;
+ }
+ if (token.name() == inputTag) {
+ RefPtr<Attribute> typeAttribute = token.getAttributeItem(typeAttr);
+ m_tree.reconstructTheActiveFormattingElements();
+ 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);
+ return;
+ }
+ if (token.name() == hrTag) {
+ processFakePEndTagIfPInButtonScope();
+ m_tree.insertSelfClosingHTMLElement(token);
+ m_framesetOk = false;
+ return;
+ }
+ if (token.name() == isindexTag) {
+ processIsindexStartTagForInBody(token);
+ return;
+ }
+ if (token.name() == textareaTag) {
+ m_tree.insertHTMLElement(token);
+ m_parser->tokenizer()->setSkipLeadingNewLineForListing(true);
+ m_parser->tokenizer()->setState(HTMLTokenizer::RCDATAState);
+ m_originalInsertionMode = m_insertionMode;
+ m_framesetOk = false;
+ setInsertionMode(TextMode);
+ return;
+ }
+ if (token.name() == xmpTag) {
+ processFakePEndTagIfPInButtonScope();
+ m_tree.reconstructTheActiveFormattingElements();
+ m_framesetOk = false;
+ processGenericRawTextStartTag(token);
+ return;
+ }
+ if (token.name() == iframeTag) {
+ m_framesetOk = false;
+ processGenericRawTextStartTag(token);
+ return;
+ }
+ if (token.name() == noembedTag && pluginsEnabled(m_document->frame())) {
+ processGenericRawTextStartTag(token);
+ return;
+ }
+ if (token.name() == noscriptTag && scriptEnabled(m_document->frame())) {
+ processGenericRawTextStartTag(token);
+ return;
+ }
+ if (token.name() == selectTag) {
+ m_tree.reconstructTheActiveFormattingElements();
+ m_tree.insertHTMLElement(token);
+ m_framesetOk = false;
+ if (m_insertionMode == InTableMode
+ || m_insertionMode == InCaptionMode
+ || m_insertionMode == InColumnGroupMode
+ || m_insertionMode == InTableBodyMode
+ || m_insertionMode == InRowMode
+ || m_insertionMode == InCellMode)
+ setInsertionMode(InSelectInTableMode);
+ else
+ setInsertionMode(InSelectMode);
+ return;
+ }
+ if (token.name() == optgroupTag || token.name() == optionTag) {
+ if (m_tree.openElements()->inScope(optionTag.localName())) {
+ AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
+ processEndTag(endOption);
+ }
+ m_tree.reconstructTheActiveFormattingElements();
+ m_tree.insertHTMLElement(token);
+ return;
+ }
+ if (token.name() == rpTag || token.name() == rtTag) {
+ if (m_tree.openElements()->inScope(rubyTag.localName())) {
+ m_tree.generateImpliedEndTags();
+ if (!m_tree.currentElement()->hasTagName(rubyTag)) {
+ parseError(token);
+ m_tree.openElements()->popUntil(rubyTag.localName());
+ }
+ }
+ m_tree.insertHTMLElement(token);
+ return;
+ }
+ if (token.name() == MathMLNames::mathTag.localName()) {
+ m_tree.reconstructTheActiveFormattingElements();
+ adjustMathMLAttributes(token);
+ adjustForeignAttributes(token);
+ m_tree.insertForeignElement(token, MathMLNames::mathmlNamespaceURI);
+ if (m_insertionMode != InForeignContentMode)
+ setInsertionMode(InForeignContentMode);
+ return;
+ }
+ if (token.name() == SVGNames::svgTag.localName()) {
+ m_tree.reconstructTheActiveFormattingElements();
+ adjustSVGAttributes(token);
+ adjustForeignAttributes(token);
+ m_tree.insertForeignElement(token, SVGNames::svgNamespaceURI);
+ if (m_insertionMode != InForeignContentMode)
+ setInsertionMode(InForeignContentMode);
+ return;
+ }
+ if (isCaptionColOrColgroupTag(token.name())
+ || token.name() == frameTag
+ || token.name() == headTag
+ || isTableBodyContextTag(token.name())
+ || isTableCellContextTag(token.name())
+ || token.name() == trTag) {
+ parseError(token);
+ return;
+ }
+ m_tree.reconstructTheActiveFormattingElements();
+ m_tree.insertHTMLElement(token);
+}
+
+bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
+{
+ if (m_tree.currentElement() == m_tree.openElements()->htmlElement()) {
+ ASSERT(isParsingFragment());
+ // FIXME: parse error
+ return false;
+ }
+ m_tree.openElements()->pop();
+ setInsertionMode(InTableMode);
+ return true;
+}
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#close-the-cell
+void HTMLTreeBuilder::closeTheCell()
+{
+ ASSERT(insertionMode() == InCellMode);
+ if (m_tree.openElements()->inTableScope(tdTag)) {
+ ASSERT(!m_tree.openElements()->inTableScope(thTag));
+ processFakeEndTag(tdTag);
+ return;
+ }
+ ASSERT(m_tree.openElements()->inTableScope(thTag));
+ processFakeEndTag(thTag);
+ ASSERT(insertionMode() == InRowMode);
+}
+
+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);
+ setInsertionMode(InCaptionMode);
+ return;
+ }
+ if (token.name() == colgroupTag) {
+ m_tree.openElements()->popUntilTableScopeMarker();
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InColumnGroupMode);
+ return;
+ }
+ if (token.name() == colTag) {
+ processFakeStartTag(colgroupTag);
+ ASSERT(InColumnGroupMode);
+ reprocessStartTag(token);
+ return;
+ }
+ if (isTableBodyContextTag(token.name())) {
+ m_tree.openElements()->popUntilTableScopeMarker();
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InTableBodyMode);
+ return;
+ }
+ if (isTableCellContextTag(token.name())
+ || token.name() == trTag) {
+ processFakeStartTag(tbodyTag);
+ ASSERT(insertionMode() == InTableBodyMode);
+ reprocessStartTag(token);
+ return;
+ }
+ if (token.name() == tableTag) {
+ parseError(token);
+ if (!processTableEndTagForInTable()) {
+ ASSERT(isParsingFragment());
+ return;
+ }
+ reprocessStartTag(token);
+ return;
+ }
+ if (token.name() == styleTag || token.name() == scriptTag) {
+ processStartTagForInHead(token);
+ return;
+ }
+ if (token.name() == inputTag) {
+ Attribute* typeAttribute = token.getAttributeItem(typeAttr);
+ if (typeAttribute && equalIgnoringCase(typeAttribute->value(), "hidden")) {
+ parseError(token);
+ m_tree.insertSelfClosingHTMLElement(token);
+ return;
+ }
+ // Fall through to "anything else" case.
+ }
+ if (token.name() == formTag) {
+ parseError(token);
+ if (m_tree.form())
+ return;
+ m_tree.insertHTMLFormElement(token, true);
+ m_tree.openElements()->pop();
+ return;
+ }
+ parseError(token);
+ HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree);
+ processStartTagForInBody(token);
+}
+
+namespace {
+
+bool shouldProcessForeignContentUsingInBodyInsertionMode(AtomicHTMLToken& token, Element* currentElement)
+{
+ ASSERT(token.type() == HTMLToken::StartTag);
+ if (currentElement->hasTagName(MathMLNames::miTag)
+ || currentElement->hasTagName(MathMLNames::moTag)
+ || currentElement->hasTagName(MathMLNames::mnTag)
+ || currentElement->hasTagName(MathMLNames::msTag)
+ || currentElement->hasTagName(MathMLNames::mtextTag)) {
+ return token.name() != MathMLNames::mglyphTag
+ && token.name() != MathMLNames::malignmarkTag;
+ }
+ if (currentElement->hasTagName(MathMLNames::annotation_xmlTag))
+ return token.name() == SVGNames::svgTag;
+ if (currentElement->hasTagName(SVGNames::foreignObjectTag)
+ || currentElement->hasTagName(SVGNames::descTag)
+ || currentElement->hasTagName(SVGNames::titleTag))
+ return true;
+ return currentElement->namespaceURI() == HTMLNames::xhtmlNamespaceURI;
+}
+
+}
+
+void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::StartTag);
+ switch (insertionMode()) {
+ case InitialMode:
+ ASSERT(insertionMode() == InitialMode);
+ defaultForInitial();
+ // Fall through.
+ case BeforeHTMLMode:
+ ASSERT(insertionMode() == BeforeHTMLMode);
+ if (token.name() == htmlTag) {
+ m_tree.insertHTMLHtmlStartTagBeforeHTML(token);
+ setInsertionMode(BeforeHeadMode);
+ return;
+ }
+ defaultForBeforeHTML();
+ // Fall through.
+ case BeforeHeadMode:
+ ASSERT(insertionMode() == BeforeHeadMode);
+ if (token.name() == htmlTag) {
+ m_tree.insertHTMLHtmlStartTagInBody(token);
+ return;
+ }
+ if (token.name() == headTag) {
+ m_tree.insertHTMLHeadElement(token);
+ setInsertionMode(InHeadMode);
+ return;
+ }
+ defaultForBeforeHead();
+ // Fall through.
+ case InHeadMode:
+ ASSERT(insertionMode() == InHeadMode);
+ if (processStartTagForInHead(token))
+ return;
+ defaultForInHead();
+ // Fall through.
+ case AfterHeadMode:
+ ASSERT(insertionMode() == AfterHeadMode);
+ if (token.name() == htmlTag) {
+ m_tree.insertHTMLHtmlStartTagInBody(token);
+ return;
+ }
+ if (token.name() == bodyTag) {
+ m_framesetOk = false;
+ m_tree.insertHTMLBodyElement(token);
+ setInsertionMode(InBodyMode);
+ return;
+ }
+ if (token.name() == framesetTag) {
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InFramesetMode);
+ 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
+ || token.name() == titleTag) {
+ parseError(token);
+ ASSERT(m_tree.head());
+ m_tree.openElements()->pushHTMLHeadElement(m_tree.head());
+ processStartTagForInHead(token);
+ m_tree.openElements()->removeHTMLHeadElement(m_tree.head());
+ return;
+ }
+ if (token.name() == headTag) {
+ parseError(token);
+ return;
+ }
+ defaultForAfterHead();
+ // Fall through
+ case InBodyMode:
+ ASSERT(insertionMode() == InBodyMode);
+ processStartTagForInBody(token);
+ break;
+ case InTableMode:
+ ASSERT(insertionMode() == InTableMode);
+ processStartTagForInTable(token);
+ break;
+ case InCaptionMode:
+ ASSERT(insertionMode() == InCaptionMode);
+ if (isCaptionColOrColgroupTag(token.name())
+ || isTableBodyContextTag(token.name())
+ || isTableCellContextTag(token.name())
+ || token.name() == trTag) {
+ parseError(token);
+ if (!processCaptionEndTagForInCaption()) {
+ ASSERT(isParsingFragment());
+ return;
+ }
+ reprocessStartTag(token);
+ return;
+ }
+ processStartTagForInBody(token);
+ break;
+ case InColumnGroupMode:
+ ASSERT(insertionMode() == InColumnGroupMode);
+ if (token.name() == htmlTag) {
+ m_tree.insertHTMLHtmlStartTagInBody(token);
+ return;
+ }
+ if (token.name() == colTag) {
+ m_tree.insertSelfClosingHTMLElement(token);
+ return;
+ }
+ if (!processColgroupEndTagForInColumnGroup()) {
+ ASSERT(isParsingFragment());
+ return;
+ }
+ reprocessStartTag(token);
+ break;
+ case InTableBodyMode:
+ ASSERT(insertionMode() == InTableBodyMode);
+ if (token.name() == trTag) {
+ m_tree.openElements()->popUntilTableBodyScopeMarker(); // How is there ever anything to pop?
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InRowMode);
+ return;
+ }
+ if (isTableCellContextTag(token.name())) {
+ parseError(token);
+ processFakeStartTag(trTag);
+ ASSERT(insertionMode() == InRowMode);
+ reprocessStartTag(token);
+ return;
+ }
+ if (isCaptionColOrColgroupTag(token.name()) || isTableBodyContextTag(token.name())) {
+ // FIXME: This is slow.
+ if (!m_tree.openElements()->inTableScope(tbodyTag.localName()) && !m_tree.openElements()->inTableScope(theadTag.localName()) && !m_tree.openElements()->inTableScope(tfootTag.localName())) {
+ ASSERT(isParsingFragment());
+ parseError(token);
+ return;
+ }
+ m_tree.openElements()->popUntilTableBodyScopeMarker();
+ ASSERT(isTableBodyContextTag(m_tree.currentElement()->localName()));
+ processFakeEndTag(m_tree.currentElement()->tagQName());
+ reprocessStartTag(token);
+ return;
+ }
+ processStartTagForInTable(token);
+ break;
+ case InRowMode:
+ ASSERT(insertionMode() == InRowMode);
+ if (isTableCellContextTag(token.name())) {
+ m_tree.openElements()->popUntilTableRowScopeMarker();
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InCellMode);
+ m_tree.activeFormattingElements()->appendMarker();
+ return;
+ }
+ if (token.name() == trTag
+ || isCaptionColOrColgroupTag(token.name())
+ || isTableBodyContextTag(token.name())) {
+ if (!processTrEndTagForInRow()) {
+ ASSERT(isParsingFragment());
+ return;
+ }
+ ASSERT(insertionMode() == InTableBodyMode);
+ reprocessStartTag(token);
+ return;
+ }
+ processStartTagForInTable(token);
+ break;
+ case InCellMode:
+ ASSERT(insertionMode() == InCellMode);
+ 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)) {
+ ASSERT(isParsingFragment());
+ parseError(token);
+ return;
+ }
+ closeTheCell();
+ reprocessStartTag(token);
+ return;
+ }
+ processStartTagForInBody(token);
+ break;
+ case AfterBodyMode:
+ case AfterAfterBodyMode:
+ ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
+ if (token.name() == htmlTag) {
+ m_tree.insertHTMLHtmlStartTagInBody(token);
+ return;
+ }
+ setInsertionMode(InBodyMode);
+ reprocessStartTag(token);
+ break;
+ case InHeadNoscriptMode:
+ ASSERT(insertionMode() == InHeadNoscriptMode);
+ if (token.name() == htmlTag) {
+ m_tree.insertHTMLHtmlStartTagInBody(token);
+ return;
+ }
+ 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) {
+ parseError(token);
+ return;
+ }
+ defaultForInHeadNoscript();
+ processToken(token);
+ break;
+ case InFramesetMode:
+ ASSERT(insertionMode() == InFramesetMode);
+ if (token.name() == htmlTag) {
+ m_tree.insertHTMLHtmlStartTagInBody(token);
+ return;
+ }
+ if (token.name() == framesetTag) {
+ m_tree.insertHTMLElement(token);
+ return;
+ }
+ if (token.name() == frameTag) {
+ m_tree.insertSelfClosingHTMLElement(token);
+ return;
+ }
+ if (token.name() == noframesTag) {
+ processStartTagForInHead(token);
+ return;
+ }
+ parseError(token);
+ break;
+ case AfterFramesetMode:
+ case AfterAfterFramesetMode:
+ ASSERT(insertionMode() == AfterFramesetMode || insertionMode() == AfterAfterFramesetMode);
+ if (token.name() == htmlTag) {
+ m_tree.insertHTMLHtmlStartTagInBody(token);
+ return;
+ }
+ if (token.name() == noframesTag) {
+ processStartTagForInHead(token);
+ return;
+ }
+ parseError(token);
+ break;
+ case InSelectInTableMode:
+ ASSERT(insertionMode() == InSelectInTableMode);
+ 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);
+ reprocessStartTag(token);
+ return;
+ }
+ // Fall through
+ case InSelectMode:
+ ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode);
+ if (token.name() == htmlTag) {
+ m_tree.insertHTMLHtmlStartTagInBody(token);
+ return;
+ }
+ if (token.name() == optionTag) {
+ if (m_tree.currentElement()->hasTagName(optionTag)) {
+ AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
+ processEndTag(endOption);
+ }
+ m_tree.insertHTMLElement(token);
+ return;
+ }
+ if (token.name() == optgroupTag) {
+ if (m_tree.currentElement()->hasTagName(optionTag)) {
+ AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
+ processEndTag(endOption);
+ }
+ if (m_tree.currentElement()->hasTagName(optgroupTag)) {
+ AtomicHTMLToken endOptgroup(HTMLToken::EndTag, optgroupTag.localName());
+ processEndTag(endOptgroup);
+ }
+ m_tree.insertHTMLElement(token);
+ return;
+ }
+ if (token.name() == selectTag) {
+ parseError(token);
+ AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
+ processEndTag(endSelect);
+ return;
+ }
+ if (token.name() == inputTag
+ || token.name() == keygenTag
+ || token.name() == textareaTag) {
+ parseError(token);
+ if (!m_tree.openElements()->inSelectScope(selectTag)) {
+ ASSERT(isParsingFragment());
+ return;
+ }
+ AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
+ processEndTag(endSelect);
+ reprocessStartTag(token);
+ return;
+ }
+ if (token.name() == scriptTag) {
+ bool didProcess = processStartTagForInHead(token);
+ ASSERT_UNUSED(didProcess, didProcess);
+ return;
+ }
+ break;
+ case InTableTextMode:
+ defaultForInTableText();
+ processStartTag(token);
+ break;
+ case InForeignContentMode: {
+ if (shouldProcessForeignContentUsingInBodyInsertionMode(token, m_tree.currentElement())) {
+ processForeignContentUsingInBodyModeAndResetMode(token);
+ return;
+ }
+ 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();
+ resetInsertionModeAppropriately();
+ reprocessStartTag(token);
+ return;
+ }
+ const AtomicString& currentNamespace = m_tree.currentElement()->namespaceURI();
+ if (currentNamespace == MathMLNames::mathmlNamespaceURI)
+ adjustMathMLAttributes(token);
+ if (currentNamespace == SVGNames::svgNamespaceURI) {
+ adjustSVGTagNameCase(token);
+ adjustSVGAttributes(token);
+ }
+ adjustForeignAttributes(token);
+ m_tree.insertForeignElement(token, currentNamespace);
+ break;
+ }
+ case TextMode:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+bool HTMLTreeBuilder::processBodyEndTagForInBody(AtomicHTMLToken& token)
+{
+ 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.
+ setInsertionMode(AfterBodyMode);
+ return true;
+}
+
+void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::EndTag);
+ HTMLElementStack::ElementRecord* record = m_tree.openElements()->topRecord();
+ while (1) {
+ Element* node = record->element();
+ if (node->hasLocalName(token.name())) {
+ m_tree.generateImpliedEndTags();
+ if (!m_tree.currentElement()->hasLocalName(token.name())) {
+ parseError(token);
+ // FIXME: This is either a bug in the spec, or a bug in our
+ // implementation. Filed a bug with HTML5:
+ // http://www.w3.org/Bugs/Public/show_bug.cgi?id=10080
+ // We might have already popped the node for the token in
+ // generateImpliedEndTags, just abort.
+ if (!m_tree.openElements()->contains(node))
+ return;
+ }
+ m_tree.openElements()->popUntilPopped(node);
+ return;
+ }
+ if (isSpecialNode(node)) {
+ parseError(token);
+ return;
+ }
+ record = record->next();
+ }
+}
+
+// FIXME: This probably belongs on HTMLElementStack.
+HTMLElementStack::ElementRecord* HTMLTreeBuilder::furthestBlockForFormattingElement(Element* formattingElement)
+{
+ HTMLElementStack::ElementRecord* furthestBlock = 0;
+ HTMLElementStack::ElementRecord* record = m_tree.openElements()->topRecord();
+ for (; record; record = record->next()) {
+ if (record->element() == formattingElement)
+ return furthestBlock;
+ if (isSpecialNode(record->element()))
+ furthestBlock = record;
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-inbody
+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 copied from the
+ // legacy tree builder and might need to be tweaked in the future.
+ static const int adoptionAgencyIterationLimit = 10;
+
+ for (int i = 0; i < adoptionAgencyIterationLimit; ++i) {
+ // 1.
+ Element* formattingElement = m_tree.activeFormattingElements()->closestElementInScopeWithName(token.name());
+ if (!formattingElement || ((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;
+ }
+ HTMLElementStack::ElementRecord* formattingElementRecord = m_tree.openElements()->find(formattingElement);
+ if (!formattingElementRecord) {
+ parseError(token);
+ m_tree.activeFormattingElements()->remove(formattingElement);
+ return;
+ }
+ if (formattingElement != m_tree.currentElement())
+ parseError(token);
+ // 2.
+ HTMLElementStack::ElementRecord* furthestBlock = furthestBlockForFormattingElement(formattingElement);
+ // 3.
+ if (!furthestBlock) {
+ m_tree.openElements()->popUntilPopped(formattingElement);
+ m_tree.activeFormattingElements()->remove(formattingElement);
+ return;
+ }
+ // 4.
+ ASSERT(furthestBlock->isAbove(formattingElementRecord));
+ Element* commonAncestor = formattingElementRecord->next()->element();
+ // 5.
+ HTMLFormattingElementList::Bookmark bookmark = m_tree.activeFormattingElements()->bookmarkFor(formattingElement);
+ // 6.
+ HTMLElementStack::ElementRecord* node = furthestBlock;
+ HTMLElementStack::ElementRecord* nextNode = node->next();
+ HTMLElementStack::ElementRecord* lastNode = furthestBlock;
+ for (int i = 0; i < adoptionAgencyIterationLimit; ++i) {
+ // 6.1
+ node = nextNode;
+ ASSERT(node);
+ nextNode = node->next(); // Save node->next() for the next iteration in case node is deleted in 6.2.
+ // 6.2
+ if (!m_tree.activeFormattingElements()->contains(node->element())) {
+ m_tree.openElements()->remove(node->element());
+ node = 0;
+ continue;
+ }
+ // 6.3
+ if (node == formattingElementRecord)
+ break;
+ // 6.5
+ RefPtr<Element> newElement = m_tree.createHTMLElementFromElementRecord(node);
+ HTMLFormattingElementList::Entry* nodeEntry = m_tree.activeFormattingElements()->find(node->element());
+ nodeEntry->replaceElement(newElement.get());
+ node->replaceElement(newElement.release());
+ // 6.4 -- Intentionally out of order to handle the case where node
+ // was replaced in 6.5.
+ // http://www.w3.org/Bugs/Public/show_bug.cgi?id=10096
+ if (lastNode == furthestBlock)
+ bookmark.moveToAfter(nodeEntry);
+ // 6.6
+ if (Element* parent = lastNode->element()->parentElement())
+ parent->parserRemoveChild(lastNode->element());
+ node->element()->parserAddChild(lastNode->element());
+ if (lastNode->element()->parentElement()->attached() && !lastNode->element()->attached())
+ lastNode->element()->lazyAttach();
+ // 6.7
+ lastNode = node;
+ }
+ // 7
+ const AtomicString& commonAncestorTag = commonAncestor->localName();
+ if (Element* parent = lastNode->element()->parentElement())
+ parent->parserRemoveChild(lastNode->element());
+ // FIXME: If this moves to HTMLConstructionSite, this check should use
+ // causesFosterParenting(tagName) instead.
+ if (commonAncestorTag == tableTag
+ || commonAncestorTag == trTag
+ || isTableBodyContextTag(commonAncestorTag))
+ m_tree.fosterParent(lastNode->element());
+ else {
+ commonAncestor->parserAddChild(lastNode->element());
+ if (lastNode->element()->parentElement()->attached() && !lastNode->element()->attached())
+ lastNode->element()->lazyAttach();
+ }
+ // 8
+ RefPtr<Element> newElement = m_tree.createHTMLElementFromElementRecord(formattingElementRecord);
+ // 9
+ newElement->takeAllChildrenFrom(furthestBlock->element());
+ // 10
+ Element* furthestBlockElement = furthestBlock->element();
+ // FIXME: All this creation / parserAddChild / attach business should
+ // be in HTMLConstructionSite. My guess is that steps 8--12
+ // should all be in some HTMLConstructionSite function.
+ furthestBlockElement->parserAddChild(newElement);
+ if (furthestBlockElement->attached() && !newElement->attached()) {
+ // Notice that newElement might already be attached if, for example, one of the reparented
+ // children is a style element, which attaches itself automatically.
+ newElement->attach();
+ }
+ // 11
+ m_tree.activeFormattingElements()->swapTo(formattingElement, newElement.get(), bookmark);
+ // 12
+ m_tree.openElements()->remove(formattingElement);
+ m_tree.openElements()->insertAbove(newElement, furthestBlock);
+ }
+}
+
+void HTMLTreeBuilder::resetInsertionModeAppropriately()
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#reset-the-insertion-mode-appropriately
+ bool last = false;
+ HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
+ while (1) {
+ Element* node = nodeRecord->element();
+ if (node == m_tree.openElements()->bottom()) {
+ ASSERT(isParsingFragment());
+ last = true;
+ node = m_fragmentContext.contextElement();
+ }
+ if (node->hasTagName(selectTag)) {
+ ASSERT(isParsingFragment());
+ return setInsertionMode(InSelectMode);
+ }
+ if (node->hasTagName(tdTag) || node->hasTagName(thTag))
+ return setInsertionMode(InCellMode);
+ if (node->hasTagName(trTag))
+ return setInsertionMode(InRowMode);
+ if (node->hasTagName(tbodyTag) || node->hasTagName(theadTag) || node->hasTagName(tfootTag))
+ return setInsertionMode(InTableBodyMode);
+ if (node->hasTagName(captionTag))
+ return setInsertionMode(InCaptionMode);
+ if (node->hasTagName(colgroupTag)) {
+ ASSERT(isParsingFragment());
+ return setInsertionMode(InColumnGroupMode);
+ }
+ if (node->hasTagName(tableTag))
+ return setInsertionMode(InTableMode);
+ if (node->hasTagName(headTag)) {
+ ASSERT(isParsingFragment());
+ return setInsertionMode(InBodyMode);
+ }
+ if (node->hasTagName(bodyTag))
+ return setInsertionMode(InBodyMode);
+ if (node->hasTagName(framesetTag)) {
+ ASSERT(isParsingFragment());
+ return setInsertionMode(InFramesetMode);
+ }
+ if (node->hasTagName(htmlTag)) {
+ ASSERT(isParsingFragment());
+ return setInsertionMode(BeforeHeadMode);
+ }
+ if (node->namespaceURI() == SVGNames::svgNamespaceURI
+ || node->namespaceURI() == MathMLNames::mathmlNamespaceURI)
+ return setInsertionMode(InForeignContentMode);
+ if (last) {
+ ASSERT(isParsingFragment());
+ return setInsertionMode(InBodyMode);
+ }
+ nodeRecord = nodeRecord->next();
+ }
+}
+
+void HTMLTreeBuilder::processEndTagForInTableBody(AtomicHTMLToken& token)
+{
+ 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();
+ setInsertionMode(InTableMode);
+ return;
+ }
+ if (token.name() == tableTag) {
+ // FIXME: This is slow.
+ if (!m_tree.openElements()->inTableScope(tbodyTag.localName()) && !m_tree.openElements()->inTableScope(theadTag.localName()) && !m_tree.openElements()->inTableScope(tfootTag.localName())) {
+ ASSERT(isParsingFragment());
+ parseError(token);
+ return;
+ }
+ m_tree.openElements()->popUntilTableBodyScopeMarker();
+ ASSERT(isTableBodyContextTag(m_tree.currentElement()->localName()));
+ processFakeEndTag(m_tree.currentElement()->tagQName());
+ reprocessEndTag(token);
+ return;
+ }
+ 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)
+{
+ ASSERT(token.type() == HTMLToken::EndTag);
+ if (token.name() == trTag) {
+ processTrEndTagForInRow();
+ return;
+ }
+ if (token.name() == tableTag) {
+ if (!processTrEndTagForInRow()) {
+ ASSERT(isParsingFragment());
+ return;
+ }
+ ASSERT(insertionMode() == InTableBodyMode);
+ reprocessEndTag(token);
+ return;
+ }
+ if (isTableBodyContextTag(token.name())) {
+ if (!m_tree.openElements()->inTableScope(token.name())) {
+ parseError(token);
+ return;
+ }
+ processFakeEndTag(trTag);
+ ASSERT(insertionMode() == InTableBodyMode);
+ reprocessEndTag(token);
+ return;
+ }
+ if (token.name() == bodyTag
+ || isCaptionColOrColgroupTag(token.name())
+ || token.name() == htmlTag
+ || isTableCellContextTag(token.name())) {
+ parseError(token);
+ return;
+ }
+ processEndTagForInTable(token);
+}
+
+void HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken& token)
+{
+ 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.currentElement()->hasLocalName(token.name()))
+ parseError(token);
+ m_tree.openElements()->popUntilPopped(token.name());
+ m_tree.activeFormattingElements()->clearToLastMarker();
+ setInsertionMode(InRowMode);
+ return;
+ }
+ 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())) {
+ ASSERT(isTableBodyContextTag(token.name()) || isParsingFragment());
+ parseError(token);
+ return;
+ }
+ closeTheCell();
+ reprocessEndTag(token);
+ return;
+ }
+ processEndTagForInBody(token);
+}
+
+void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::EndTag);
+ if (token.name() == bodyTag) {
+ processBodyEndTagForInBody(token);
+ return;
+ }
+ if (token.name() == htmlTag) {
+ AtomicHTMLToken endBody(HTMLToken::EndTag, bodyTag.localName());
+ if (processBodyEndTagForInBody(endBody))
+ reprocessEndTag(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() == 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.currentElement()->hasLocalName(token.name()))
+ parseError(token);
+ m_tree.openElements()->popUntilPopped(token.name());
+ return;
+ }
+ if (token.name() == formTag) {
+ RefPtr<Element> node = m_tree.takeForm();
+ if (!node || !m_tree.openElements()->inScope(node.get())) {
+ parseError(token);
+ return;
+ }
+ m_tree.generateImpliedEndTags();
+ if (m_tree.currentElement() != node.get())
+ parseError(token);
+ m_tree.openElements()->remove(node.get());
+ }
+ if (token.name() == pTag) {
+ if (!m_tree.openElements()->inButtonScope(token.name())) {
+ parseError(token);
+ processFakeStartTag(pTag);
+ ASSERT(m_tree.openElements()->inScope(token.name()));
+ reprocessEndTag(token);
+ return;
+ }
+ m_tree.generateImpliedEndTagsWithExclusion(token.name());
+ if (!m_tree.currentElement()->hasLocalName(token.name()))
+ parseError(token);
+ m_tree.openElements()->popUntilPopped(token.name());
+ return;
+ }
+ if (token.name() == liTag) {
+ if (!m_tree.openElements()->inListItemScope(token.name())) {
+ parseError(token);
+ return;
+ }
+ m_tree.generateImpliedEndTagsWithExclusion(token.name());
+ if (!m_tree.currentElement()->hasLocalName(token.name()))
+ parseError(token);
+ m_tree.openElements()->popUntilPopped(token.name());
+ return;
+ }
+ 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.currentElement()->hasLocalName(token.name()))
+ parseError(token);
+ m_tree.openElements()->popUntilPopped(token.name());
+ return;
+ }
+ if (isNumberedHeaderTag(token.name())) {
+ if (!m_tree.openElements()->hasNumberedHeaderElementInScope()) {
+ parseError(token);
+ return;
+ }
+ m_tree.generateImpliedEndTags();
+ if (!m_tree.currentElement()->hasLocalName(token.name()))
+ parseError(token);
+ m_tree.openElements()->popUntilNumberedHeaderElementPopped();
+ return;
+ }
+ if (isFormattingTag(token.name())) {
+ callTheAdoptionAgency(token);
+ return;
+ }
+ 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.currentElement()->hasLocalName(token.name()))
+ parseError(token);
+ m_tree.openElements()->popUntilPopped(token.name());
+ m_tree.activeFormattingElements()->clearToLastMarker();
+ return;
+ }
+ if (token.name() == brTag) {
+ parseError(token);
+ processFakeStartTag(brTag);
+ return;
+ }
+ processAnyOtherEndTagForInBody(token);
+}
+
+bool HTMLTreeBuilder::processCaptionEndTagForInCaption()
+{
+ if (!m_tree.openElements()->inTableScope(captionTag.localName())) {
+ ASSERT(isParsingFragment());
+ // FIXME: parse error
+ return false;
+ }
+ m_tree.generateImpliedEndTags();
+ // FIXME: parse error if (!m_tree.currentElement()->hasTagName(captionTag))
+ m_tree.openElements()->popUntilPopped(captionTag.localName());
+ m_tree.activeFormattingElements()->clearToLastMarker();
+ setInsertionMode(InTableMode);
+ return true;
+}
+
+bool HTMLTreeBuilder::processTrEndTagForInRow()
+{
+ if (!m_tree.openElements()->inTableScope(trTag.localName())) {
+ ASSERT(isParsingFragment());
+ // FIXME: parse error
+ return false;
+ }
+ m_tree.openElements()->popUntilTableRowScopeMarker();
+ ASSERT(m_tree.currentElement()->hasTagName(trTag));
+ m_tree.openElements()->pop();
+ setInsertionMode(InTableBodyMode);
+ return true;
+}
+
+bool HTMLTreeBuilder::processTableEndTagForInTable()
+{
+ if (!m_tree.openElements()->inTableScope(tableTag)) {
+ ASSERT(isParsingFragment());
+ // FIXME: parse error.
+ return false;
+ }
+ m_tree.openElements()->popUntilPopped(tableTag.localName());
+ resetInsertionModeAppropriately();
+ return true;
+}
+
+void HTMLTreeBuilder::processEndTagForInTable(AtomicHTMLToken& token)
+{
+ 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) {
+ parseError(token);
+ return;
+ }
+ // Is this redirection necessary here?
+ HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree);
+ processEndTagForInBody(token);
+}
+
+void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::EndTag);
+ switch (insertionMode()) {
+ case InitialMode:
+ ASSERT(insertionMode() == InitialMode);
+ defaultForInitial();
+ // Fall through.
+ case BeforeHTMLMode:
+ ASSERT(insertionMode() == BeforeHTMLMode);
+ if (token.name() != headTag && token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
+ parseError(token);
+ return;
+ }
+ defaultForBeforeHTML();
+ // Fall through.
+ case BeforeHeadMode:
+ ASSERT(insertionMode() == BeforeHeadMode);
+ if (token.name() != headTag && token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
+ parseError(token);
+ return;
+ }
+ defaultForBeforeHead();
+ // Fall through.
+ case InHeadMode:
+ ASSERT(insertionMode() == InHeadMode);
+ if (token.name() == headTag) {
+ m_tree.openElements()->popHTMLHeadElement();
+ setInsertionMode(AfterHeadMode);
+ return;
+ }
+ if (token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
+ parseError(token);
+ return;
+ }
+ defaultForInHead();
+ // Fall through.
+ case AfterHeadMode:
+ ASSERT(insertionMode() == AfterHeadMode);
+ if (token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
+ parseError(token);
+ return;
+ }
+ defaultForAfterHead();
+ // Fall through
+ case InBodyMode:
+ ASSERT(insertionMode() == InBodyMode);
+ processEndTagForInBody(token);
+ break;
+ case InTableMode:
+ ASSERT(insertionMode() == InTableMode);
+ processEndTagForInTable(token);
+ break;
+ case InCaptionMode:
+ ASSERT(insertionMode() == InCaptionMode);
+ if (token.name() == captionTag) {
+ processCaptionEndTagForInCaption();
+ return;
+ }
+ if (token.name() == tableTag) {
+ parseError(token);
+ if (!processCaptionEndTagForInCaption()) {
+ ASSERT(isParsingFragment());
+ return;
+ }
+ reprocessEndTag(token);
+ return;
+ }
+ 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 InColumnGroupMode:
+ ASSERT(insertionMode() == InColumnGroupMode);
+ if (token.name() == colgroupTag) {
+ processColgroupEndTagForInColumnGroup();
+ return;
+ }
+ if (token.name() == colTag) {
+ parseError(token);
+ return;
+ }
+ if (!processColgroupEndTagForInColumnGroup()) {
+ ASSERT(isParsingFragment());
+ return;
+ }
+ reprocessEndTag(token);
+ break;
+ case InRowMode:
+ ASSERT(insertionMode() == InRowMode);
+ processEndTagForInRow(token);
+ break;
+ case InCellMode:
+ ASSERT(insertionMode() == InCellMode);
+ processEndTagForInCell(token);
+ break;
+ case InTableBodyMode:
+ ASSERT(insertionMode() == InTableBodyMode);
+ processEndTagForInTableBody(token);
+ break;
+ case AfterBodyMode:
+ ASSERT(insertionMode() == AfterBodyMode);
+ if (token.name() == htmlTag) {
+ if (isParsingFragment()) {
+ parseError(token);
+ return;
+ }
+ setInsertionMode(AfterAfterBodyMode);
+ return;
+ }
+ prepareToReprocessToken();
+ // Fall through.
+ case AfterAfterBodyMode:
+ ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
+ parseError(token);
+ setInsertionMode(InBodyMode);
+ reprocessEndTag(token);
+ break;
+ case InHeadNoscriptMode:
+ ASSERT(insertionMode() == InHeadNoscriptMode);
+ if (token.name() == noscriptTag) {
+ ASSERT(m_tree.currentElement()->hasTagName(noscriptTag));
+ m_tree.openElements()->pop();
+ ASSERT(m_tree.currentElement()->hasTagName(headTag));
+ setInsertionMode(InHeadMode);
+ return;
+ }
+ if (token.name() != brTag) {
+ parseError(token);
+ return;
+ }
+ defaultForInHeadNoscript();
+ processToken(token);
+ break;
+ case TextMode:
+ if (token.name() == scriptTag) {
+ // Pause ourselves so that parsing stops until the script can be processed by the caller.
+ m_isPaused = true;
+ ASSERT(m_tree.currentElement()->hasTagName(scriptTag));
+ m_scriptToProcess = m_tree.currentElement();
+ m_scriptToProcessStartPosition = WTF::toOneBasedTextPosition(m_lastScriptElementStartPosition);
+ m_tree.openElements()->pop();
+ if (isParsingFragment() && m_fragmentContext.scriptingPermission() == FragmentScriptingNotAllowed)
+ m_scriptToProcess->removeAllChildren();
+ setInsertionMode(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()->state() == HTMLTokenizer::DataState || m_usePreHTML5ParserQuirks);
+ m_parser->tokenizer()->setState(HTMLTokenizer::DataState);
+ return;
+ }
+ m_tree.openElements()->pop();
+ setInsertionMode(m_originalInsertionMode);
+ break;
+ case InFramesetMode:
+ ASSERT(insertionMode() == InFramesetMode);
+ if (token.name() == framesetTag) {
+ if (m_tree.currentElement() == m_tree.openElements()->htmlElement()) {
+ parseError(token);
+ return;
+ }
+ m_tree.openElements()->pop();
+ if (!isParsingFragment() && !m_tree.currentElement()->hasTagName(framesetTag))
+ setInsertionMode(AfterFramesetMode);
+ return;
+ }
+ break;
+ case AfterFramesetMode:
+ ASSERT(insertionMode() == AfterFramesetMode);
+ if (token.name() == htmlTag) {
+ setInsertionMode(AfterAfterFramesetMode);
+ return;
+ }
+ // Fall through.
+ case AfterAfterFramesetMode:
+ ASSERT(insertionMode() == AfterFramesetMode || insertionMode() == AfterAfterFramesetMode);
+ parseError(token);
+ break;
+ case InSelectInTableMode:
+ ASSERT(insertionMode() == InSelectInTableMode);
+ 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())) {
+ AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
+ processEndTag(endSelect);
+ reprocessEndTag(token);
+ }
+ return;
+ }
+ // Fall through.
+ case InSelectMode:
+ ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode);
+ if (token.name() == optgroupTag) {
+ if (m_tree.currentElement()->hasTagName(optionTag) && m_tree.oneBelowTop()->hasTagName(optgroupTag))
+ processFakeEndTag(optionTag);
+ if (m_tree.currentElement()->hasTagName(optgroupTag)) {
+ m_tree.openElements()->pop();
+ return;
+ }
+ parseError(token);
+ return;
+ }
+ if (token.name() == optionTag) {
+ if (m_tree.currentElement()->hasTagName(optionTag)) {
+ m_tree.openElements()->pop();
+ return;
+ }
+ parseError(token);
+ return;
+ }
+ if (token.name() == selectTag) {
+ if (!m_tree.openElements()->inSelectScope(token.name())) {
+ ASSERT(isParsingFragment());
+ parseError(token);
+ return;
+ }
+ m_tree.openElements()->popUntilPopped(selectTag.localName());
+ resetInsertionModeAppropriately();
+ return;
+ }
+ break;
+ case InTableTextMode:
+ defaultForInTableText();
+ processEndTag(token);
+ break;
+ case InForeignContentMode:
+ if (token.name() == SVGNames::scriptTag && m_tree.currentElement()->hasTagName(SVGNames::scriptTag)) {
+ notImplemented();
+ return;
+ }
+ if (m_tree.currentElement()->namespaceURI() != xhtmlNamespaceURI) {
+ // FIXME: This code just wants an Element* iterator, instead of an ElementRecord*
+ HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
+ if (!nodeRecord->element()->hasLocalName(token.name()))
+ parseError(token);
+ while (1) {
+ if (nodeRecord->element()->hasLocalName(token.name())) {
+ m_tree.openElements()->popUntilPopped(nodeRecord->element());
+ resetForeignInsertionMode();
+ return;
+ }
+ nodeRecord = nodeRecord->next();
+ if (nodeRecord->element()->namespaceURI() == xhtmlNamespaceURI)
+ break;
+ }
+ }
+ // Any other end tag (also the last two steps of "An end tag, if the current node is not an element in the HTML namespace."
+ processForeignContentUsingInBodyModeAndResetMode(token);
+ break;
+ }
+}
+
+void HTMLTreeBuilder::prepareToReprocessToken()
+{
+ if (m_hasPendingForeignInsertionModeSteps) {
+ resetForeignInsertionMode();
+ m_hasPendingForeignInsertionModeSteps = false;
+ }
+}
+
+void HTMLTreeBuilder::reprocessStartTag(AtomicHTMLToken& token)
+{
+ prepareToReprocessToken();
+ processStartTag(token);
+}
+
+void HTMLTreeBuilder::reprocessEndTag(AtomicHTMLToken& token)
+{
+ prepareToReprocessToken();
+ processEndTag(token);
+}
+
+class HTMLTreeBuilder::FakeInsertionMode : public Noncopyable {
+public:
+ FakeInsertionMode(HTMLTreeBuilder* treeBuilder, InsertionMode mode)
+ : m_treeBuilder(treeBuilder)
+ , m_originalMode(treeBuilder->insertionMode())
+ {
+ m_treeBuilder->setFakeInsertionMode(mode);
+ }
+
+ ~FakeInsertionMode()
+ {
+ if (m_treeBuilder->isFakeInsertionMode())
+ m_treeBuilder->setInsertionMode(m_originalMode);
+ }
+
+private:
+ HTMLTreeBuilder* m_treeBuilder;
+ InsertionMode m_originalMode;
+};
+
+void HTMLTreeBuilder::processForeignContentUsingInBodyModeAndResetMode(AtomicHTMLToken& token)
+{
+ m_hasPendingForeignInsertionModeSteps = true;
+ {
+ FakeInsertionMode fakeMode(this, InBodyMode);
+ processToken(token);
+ }
+ if (m_hasPendingForeignInsertionModeSteps)
+ resetForeignInsertionMode();
+}
+
+void HTMLTreeBuilder::resetForeignInsertionMode()
+{
+ if (insertionMode() == InForeignContentMode)
+ resetInsertionModeAppropriately();
+}
+
+void HTMLTreeBuilder::processComment(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::Comment);
+ if (m_insertionMode == InitialMode
+ || m_insertionMode == BeforeHTMLMode
+ || m_insertionMode == AfterAfterBodyMode
+ || m_insertionMode == AfterAfterFramesetMode) {
+ m_tree.insertCommentOnDocument(token);
+ return;
+ }
+ if (m_insertionMode == AfterBodyMode) {
+ m_tree.insertCommentOnHTMLHtmlElement(token);
+ return;
+ }
+ if (m_insertionMode == InTableTextMode) {
+ defaultForInTableText();
+ processComment(token);
+ return;
+ }
+ m_tree.insertComment(token);
+}
+
+void HTMLTreeBuilder::processCharacter(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::Character);
+ ExternalCharacterTokenBuffer buffer(token);
+ processCharacterBuffer(buffer);
+}
+
+void HTMLTreeBuilder::processCharacterBuffer(ExternalCharacterTokenBuffer& buffer)
+{
+ReprocessBuffer:
+ switch (insertionMode()) {
+ case InitialMode: {
+ ASSERT(insertionMode() == InitialMode);
+ buffer.skipLeadingWhitespace();
+ if (buffer.isEmpty())
+ return;
+ defaultForInitial();
+ // Fall through.
+ }
+ case BeforeHTMLMode: {
+ ASSERT(insertionMode() == BeforeHTMLMode);
+ buffer.skipLeadingWhitespace();
+ if (buffer.isEmpty())
+ return;
+ defaultForBeforeHTML();
+ // Fall through.
+ }
+ case BeforeHeadMode: {
+ ASSERT(insertionMode() == BeforeHeadMode);
+ buffer.skipLeadingWhitespace();
+ if (buffer.isEmpty())
+ return;
+ defaultForBeforeHead();
+ // Fall through.
+ }
+ case InHeadMode: {
+ ASSERT(insertionMode() == InHeadMode);
+ String leadingWhitespace = buffer.takeLeadingWhitespace();
+ if (!leadingWhitespace.isEmpty())
+ m_tree.insertTextNode(leadingWhitespace);
+ if (buffer.isEmpty())
+ return;
+ defaultForInHead();
+ // Fall through.
+ }
+ case AfterHeadMode: {
+ ASSERT(insertionMode() == AfterHeadMode);
+ String leadingWhitespace = buffer.takeLeadingWhitespace();
+ if (!leadingWhitespace.isEmpty())
+ m_tree.insertTextNode(leadingWhitespace);
+ if (buffer.isEmpty())
+ return;
+ defaultForAfterHead();
+ // Fall through.
+ }
+ case InBodyMode:
+ case InCaptionMode:
+ case InCellMode: {
+ ASSERT(insertionMode() == InBodyMode || insertionMode() == InCaptionMode || insertionMode() == InCellMode);
+ m_tree.reconstructTheActiveFormattingElements();
+ String characters = buffer.takeRemaining();
+ m_tree.insertTextNode(characters);
+ if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters))
+ m_framesetOk = false;
+ break;
+ }
+ case InTableMode:
+ case InTableBodyMode:
+ case InRowMode: {
+ ASSERT(insertionMode() == InTableMode || insertionMode() == InTableBodyMode || insertionMode() == InRowMode);
+ ASSERT(m_pendingTableCharacters.isEmpty());
+ m_originalInsertionMode = m_insertionMode;
+ setInsertionMode(InTableTextMode);
+ prepareToReprocessToken();
+ // Fall through.
+ }
+ case InTableTextMode: {
+ buffer.giveRemainingTo(m_pendingTableCharacters);
+ break;
+ }
+ case InColumnGroupMode: {
+ ASSERT(insertionMode() == InColumnGroupMode);
+ String leadingWhitespace = buffer.takeLeadingWhitespace();
+ if (!leadingWhitespace.isEmpty())
+ m_tree.insertTextNode(leadingWhitespace);
+ if (buffer.isEmpty())
+ return;
+ if (!processColgroupEndTagForInColumnGroup()) {
+ ASSERT(isParsingFragment());
+ // The spec tells us to drop these characters on the floor.
+ buffer.takeLeadingNonWhitespace();
+ if (buffer.isEmpty())
+ return;
+ }
+ prepareToReprocessToken();
+ goto ReprocessBuffer;
+ }
+ case AfterBodyMode:
+ case AfterAfterBodyMode: {
+ ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
+ // FIXME: parse error
+ setInsertionMode(InBodyMode);
+ prepareToReprocessToken();
+ goto ReprocessBuffer;
+ break;
+ }
+ case TextMode: {
+ ASSERT(insertionMode() == TextMode);
+ m_tree.insertTextNode(buffer.takeRemaining());
+ break;
+ }
+ case InHeadNoscriptMode: {
+ ASSERT(insertionMode() == InHeadNoscriptMode);
+ String leadingWhitespace = buffer.takeLeadingWhitespace();
+ if (!leadingWhitespace.isEmpty())
+ m_tree.insertTextNode(leadingWhitespace);
+ if (buffer.isEmpty())
+ return;
+ defaultForInHeadNoscript();
+ goto ReprocessBuffer;
+ break;
+ }
+ case InFramesetMode:
+ case AfterFramesetMode: {
+ ASSERT(insertionMode() == InFramesetMode || insertionMode() == AfterFramesetMode || insertionMode() == AfterAfterFramesetMode);
+ String leadingWhitespace = buffer.takeRemainingWhitespace();
+ if (!leadingWhitespace.isEmpty())
+ m_tree.insertTextNode(leadingWhitespace);
+ // FIXME: We should generate a parse error if we skipped over any
+ // non-whitespace characters.
+ break;
+ }
+ case InSelectInTableMode:
+ case InSelectMode: {
+ ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode);
+ m_tree.insertTextNode(buffer.takeRemaining());
+ break;
+ }
+ case InForeignContentMode: {
+ ASSERT(insertionMode() == InForeignContentMode);
+ String characters = buffer.takeRemaining();
+ m_tree.insertTextNode(characters);
+ if (m_framesetOk && !isAllWhitespace(characters))
+ m_framesetOk = false;
+ break;
+ }
+ case AfterAfterFramesetMode: {
+ String leadingWhitespace = buffer.takeRemainingWhitespace();
+ if (!leadingWhitespace.isEmpty()) {
+ m_tree.reconstructTheActiveFormattingElements();
+ m_tree.insertTextNode(leadingWhitespace);
+ }
+ // FIXME: We should generate a parse error if we skipped over any
+ // non-whitespace characters.
+ break;
+ }
+ }
+}
+
+void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::EndOfFile);
+ switch (insertionMode()) {
+ case InitialMode:
+ ASSERT(insertionMode() == InitialMode);
+ defaultForInitial();
+ // Fall through.
+ case BeforeHTMLMode:
+ ASSERT(insertionMode() == BeforeHTMLMode);
+ defaultForBeforeHTML();
+ // Fall through.
+ case BeforeHeadMode:
+ ASSERT(insertionMode() == BeforeHeadMode);
+ defaultForBeforeHead();
+ // Fall through.
+ case InHeadMode:
+ ASSERT(insertionMode() == InHeadMode);
+ defaultForInHead();
+ // Fall through.
+ case AfterHeadMode:
+ ASSERT(insertionMode() == AfterHeadMode);
+ defaultForAfterHead();
+ // Fall through
+ case InBodyMode:
+ case InCellMode:
+ case InCaptionMode:
+ case InRowMode:
+ ASSERT(insertionMode() == InBodyMode || insertionMode() == InCellMode || insertionMode() == InCaptionMode || insertionMode() == InRowMode);
+ notImplemented(); // Emit parse error based on what elements are still open.
+ break;
+ case AfterBodyMode:
+ case AfterAfterBodyMode:
+ ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
+ break;
+ case InHeadNoscriptMode:
+ ASSERT(insertionMode() == InHeadNoscriptMode);
+ defaultForInHeadNoscript();
+ processEndOfFile(token);
+ return;
+ case AfterFramesetMode:
+ case AfterAfterFramesetMode:
+ ASSERT(insertionMode() == AfterFramesetMode || insertionMode() == AfterAfterFramesetMode);
+ break;
+ case InFramesetMode:
+ case InTableMode:
+ case InTableBodyMode:
+ case InSelectInTableMode:
+ case InSelectMode:
+ ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode || insertionMode() == InTableMode || insertionMode() == InFramesetMode || insertionMode() == InTableBodyMode);
+ if (m_tree.currentElement() != m_tree.openElements()->htmlElement())
+ parseError(token);
+ break;
+ case InColumnGroupMode:
+ if (m_tree.currentElement() == m_tree.openElements()->htmlElement()) {
+ ASSERT(isParsingFragment());
+ return; // FIXME: Should we break here instead of returning?
+ }
+ if (!processColgroupEndTagForInColumnGroup()) {
+ ASSERT(isParsingFragment());
+ return; // FIXME: Should we break here instead of returning?
+ }
+ prepareToReprocessToken();
+ processEndOfFile(token);
+ return;
+ case InForeignContentMode:
+ setInsertionMode(InBodyMode);
+ processEndOfFile(token);
+ return;
+ case InTableTextMode:
+ defaultForInTableText();
+ processEndOfFile(token);
+ return;
+ case TextMode:
+ parseError(token);
+ if (m_tree.currentElement()->hasTagName(scriptTag))
+ notImplemented(); // mark the script element as "already started".
+ m_tree.openElements()->pop();
+ setInsertionMode(m_originalInsertionMode);
+ prepareToReprocessToken();
+ processEndOfFile(token);
+ return;
+ }
+ ASSERT(m_tree.openElements()->top());
+ m_tree.openElements()->popAll();
+}
+
+void HTMLTreeBuilder::defaultForInitial()
+{
+ notImplemented();
+ if (!m_fragmentContext.fragment())
+ m_document->setCompatibilityMode(Document::QuirksMode);
+ // FIXME: parse error
+ setInsertionMode(BeforeHTMLMode);
+ prepareToReprocessToken();
+}
+
+void HTMLTreeBuilder::defaultForBeforeHTML()
+{
+ AtomicHTMLToken startHTML(HTMLToken::StartTag, htmlTag.localName());
+ m_tree.insertHTMLHtmlStartTagBeforeHTML(startHTML);
+ setInsertionMode(BeforeHeadMode);
+ prepareToReprocessToken();
+}
+
+void HTMLTreeBuilder::defaultForBeforeHead()
+{
+ AtomicHTMLToken startHead(HTMLToken::StartTag, headTag.localName());
+ processStartTag(startHead);
+ prepareToReprocessToken();
+}
+
+void HTMLTreeBuilder::defaultForInHead()
+{
+ AtomicHTMLToken endHead(HTMLToken::EndTag, headTag.localName());
+ processEndTag(endHead);
+ prepareToReprocessToken();
+}
+
+void HTMLTreeBuilder::defaultForInHeadNoscript()
+{
+ AtomicHTMLToken endNoscript(HTMLToken::EndTag, noscriptTag.localName());
+ processEndTag(endNoscript);
+ prepareToReprocessToken();
+}
+
+void HTMLTreeBuilder::defaultForAfterHead()
+{
+ AtomicHTMLToken startBody(HTMLToken::StartTag, bodyTag.localName());
+ processStartTag(startBody);
+ m_framesetOk = true;
+ prepareToReprocessToken();
+}
+
+void HTMLTreeBuilder::defaultForInTableText()
+{
+ String characters = String::adopt(m_pendingTableCharacters);
+ if (!isAllWhitespace(characters)) {
+ // FIXME: parse error
+ HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree);
+ m_tree.reconstructTheActiveFormattingElements();
+ m_tree.insertTextNode(characters);
+ m_framesetOk = false;
+ setInsertionMode(m_originalInsertionMode);
+ prepareToReprocessToken();
+ return;
+ }
+ m_tree.insertTextNode(characters);
+ setInsertionMode(m_originalInsertionMode);
+ prepareToReprocessToken();
+}
+
+bool HTMLTreeBuilder::processStartTagForInHead(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::StartTag);
+ if (token.name() == htmlTag) {
+ m_tree.insertHTMLHtmlStartTagInBody(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);
+ // Note: The custom processing for the <meta> tag is done in HTMLMetaElement::process().
+ return true;
+ }
+ if (token.name() == titleTag) {
+ processGenericRCDATAStartTag(token);
+ return true;
+ }
+ if (token.name() == noscriptTag) {
+ if (scriptEnabled(m_document->frame())) {
+ processGenericRawTextStartTag(token);
+ return true;
+ }
+ m_tree.insertHTMLElement(token);
+ setInsertionMode(InHeadNoscriptMode);
+ return true;
+ }
+ if (token.name() == noframesTag || token.name() == styleTag) {
+ processGenericRawTextStartTag(token);
+ return true;
+ }
+ if (token.name() == scriptTag) {
+ processScriptStartTag(token);
+ if (m_usePreHTML5ParserQuirks && token.selfClosing())
+ processFakeEndTag(scriptTag);
+ return true;
+ }
+ if (token.name() == headTag) {
+ parseError(token);
+ return true;
+ }
+ return false;
+}
+
+void HTMLTreeBuilder::processGenericRCDATAStartTag(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::StartTag);
+ m_tree.insertHTMLElement(token);
+ m_parser->tokenizer()->setState(HTMLTokenizer::RCDATAState);
+ m_originalInsertionMode = m_insertionMode;
+ setInsertionMode(TextMode);
+}
+
+void HTMLTreeBuilder::processGenericRawTextStartTag(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::StartTag);
+ m_tree.insertHTMLElement(token);
+ m_parser->tokenizer()->setState(HTMLTokenizer::RAWTEXTState);
+ m_originalInsertionMode = m_insertionMode;
+ setInsertionMode(TextMode);
+}
+
+void HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken& token)
+{
+ ASSERT(token.type() == HTMLToken::StartTag);
+ m_tree.insertScriptElement(token);
+ m_parser->tokenizer()->setState(HTMLTokenizer::ScriptDataState);
+ m_originalInsertionMode = m_insertionMode;
+
+ TextPosition0 position = m_parser->textPosition();
+
+ ASSERT(position.m_line.zeroBasedInt() == m_parser->tokenizer()->lineNumber());
+
+ m_lastScriptElementStartPosition = position;
+
+ setInsertionMode(TextMode);
+}
+
+void HTMLTreeBuilder::finished()
+{
+ ASSERT(m_document);
+ if (isParsingFragment()) {
+ m_fragmentContext.finished();
+ return;
+ }
+
+ // Warning, this may detach the parser. Do not do anything else after this.
+ m_document->finishedParsing();
+}
+
+bool HTMLTreeBuilder::scriptEnabled(Frame* frame)
+{
+ if (!frame)
+ return false;
+ return frame->script()->canExecuteScripts(NotAboutToExecuteScript);
+}
+
+bool HTMLTreeBuilder::pluginsEnabled(Frame* frame)
+{
+ if (!frame)
+ return false;
+ return frame->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin);
+}
+
+}
diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.h b/Source/WebCore/html/parser/HTMLTreeBuilder.h
new file mode 100644
index 0000000..17b77b7
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLTreeBuilder.h
@@ -0,0 +1,267 @@
+/*
+ * 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 GOOGLE 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 GOOGLE 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 HTMLTreeBuilder_h
+#define HTMLTreeBuilder_h
+
+#include "Element.h"
+#include "FragmentScriptingPermission.h"
+#include "HTMLConstructionSite.h"
+#include "HTMLElementStack.h"
+#include "HTMLFormattingElementList.h"
+#include "HTMLTokenizer.h"
+#include <wtf/text/TextPosition.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/unicode/Unicode.h>
+
+namespace WebCore {
+
+class AtomicHTMLToken;
+class Document;
+class DocumentFragment;
+class Frame;
+class HTMLToken;
+class HTMLDocument;
+class Node;
+class HTMLDocumentParser;
+
+class HTMLTreeBuilder : public Noncopyable {
+public:
+ static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, HTMLDocument* document, bool reportErrors, bool usePreHTML5ParserQuirks)
+ {
+ return adoptPtr(new HTMLTreeBuilder(parser, document, reportErrors, usePreHTML5ParserQuirks));
+ }
+ static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission, bool usePreHTML5ParserQuirks)
+ {
+ return adoptPtr(new HTMLTreeBuilder(parser, fragment, contextElement, scriptingPermission, usePreHTML5ParserQuirks));
+ }
+ ~HTMLTreeBuilder();
+
+ bool isParsingFragment() const { return !!m_fragmentContext.fragment(); }
+
+ void detach();
+
+ void setPaused(bool paused) { m_isPaused = paused; }
+ bool isPaused() const { return m_isPaused; }
+
+ // The token really should be passed as a const& since it's never modified.
+ void constructTreeFromToken(HTMLToken&);
+ void constructTreeFromAtomicToken(AtomicHTMLToken&);
+
+ // Must be called when parser is paused before calling the parser again.
+ PassRefPtr<Element> takeScriptToProcess(TextPosition1& scriptStartPosition);
+
+ // Done, close any open tags, etc.
+ void finished();
+
+ static bool scriptEnabled(Frame*);
+ static bool pluginsEnabled(Frame*);
+
+private:
+ class FakeInsertionMode;
+ class ExternalCharacterTokenBuffer;
+ // Represents HTML5 "insertion mode"
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode
+ enum InsertionMode {
+ InitialMode,
+ BeforeHTMLMode,
+ BeforeHeadMode,
+ InHeadMode,
+ InHeadNoscriptMode,
+ AfterHeadMode,
+ InBodyMode,
+ TextMode,
+ InTableMode,
+ InTableTextMode,
+ InCaptionMode,
+ InColumnGroupMode,
+ InTableBodyMode,
+ InRowMode,
+ InCellMode,
+ InSelectMode,
+ InSelectInTableMode,
+ InForeignContentMode,
+ AfterBodyMode,
+ InFramesetMode,
+ AfterFramesetMode,
+ AfterAfterBodyMode,
+ AfterAfterFramesetMode,
+ };
+
+ HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument*, bool reportErrors, bool usePreHTML5ParserQuirks);
+ HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment*, Element* contextElement, FragmentScriptingPermission, bool usePreHTML5ParserQuirks);
+
+ 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&);
+ bool processBodyEndTagForInBody(AtomicHTMLToken&);
+ bool processTableEndTagForInTable();
+ bool processCaptionEndTagForInCaption();
+ bool processColgroupEndTagForInColumnGroup();
+ bool processTrEndTagForInRow();
+ // 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&);
+
+ void processFakeStartTag(const QualifiedName&, PassRefPtr<NamedNodeMap> attributes = 0);
+ void processFakeEndTag(const QualifiedName&);
+ void processFakeCharacters(const String&);
+ void processFakePEndTagIfPInButtonScope();
+
+ void processGenericRCDATAStartTag(AtomicHTMLToken&);
+ void processGenericRawTextStartTag(AtomicHTMLToken&);
+ void processScriptStartTag(AtomicHTMLToken&);
+
+ // Default processing for the different insertion modes.
+ void defaultForInitial();
+ void defaultForBeforeHTML();
+ void defaultForBeforeHead();
+ void defaultForInHead();
+ void defaultForInHeadNoscript();
+ void defaultForAfterHead();
+ void defaultForInTableText();
+
+ void prepareToReprocessToken();
+
+ void reprocessStartTag(AtomicHTMLToken&);
+ void reprocessEndTag(AtomicHTMLToken&);
+
+ PassRefPtr<NamedNodeMap> attributesForIsindexInput(AtomicHTMLToken&);
+
+ HTMLElementStack::ElementRecord* furthestBlockForFormattingElement(Element*);
+ void callTheAdoptionAgency(AtomicHTMLToken&);
+
+ void closeTheCell();
+
+ template <bool shouldClose(const Element*)>
+ void processCloseWhenNestedTag(AtomicHTMLToken&);
+
+ bool m_framesetOk;
+
+ // FIXME: Implement error reporting.
+ void parseError(AtomicHTMLToken&) { }
+
+ InsertionMode insertionMode() const { return m_insertionMode; }
+ void setInsertionMode(InsertionMode mode)
+ {
+ m_insertionMode = mode;
+ m_isFakeInsertionMode = false;
+ }
+
+ bool isFakeInsertionMode() { return m_isFakeInsertionMode; }
+ void setFakeInsertionMode(InsertionMode mode)
+ {
+ m_insertionMode = mode;
+ m_isFakeInsertionMode = true;
+ }
+
+ void resetInsertionModeAppropriately();
+
+ void processForeignContentUsingInBodyModeAndResetMode(AtomicHTMLToken& token);
+ void resetForeignInsertionMode();
+
+ class FragmentParsingContext : public Noncopyable {
+ public:
+ FragmentParsingContext();
+ FragmentParsingContext(DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
+ ~FragmentParsingContext();
+
+ Document* document() const;
+ DocumentFragment* fragment() const { return m_fragment; }
+ Element* contextElement() const { ASSERT(m_fragment); return m_contextElement; }
+ FragmentScriptingPermission scriptingPermission() const { ASSERT(m_fragment); return m_scriptingPermission; }
+
+ void finished();
+
+ private:
+ RefPtr<Document> m_dummyDocumentForFragmentParsing;
+ DocumentFragment* m_fragment;
+ Element* m_contextElement;
+
+ // FragmentScriptingNotAllowed causes the Parser to remove children
+ // from <script> tags (so javascript doesn't show up in pastes).
+ FragmentScriptingPermission m_scriptingPermission;
+ };
+
+ FragmentParsingContext m_fragmentContext;
+
+ Document* m_document;
+ HTMLConstructionSite m_tree;
+
+ bool m_reportErrors;
+ bool m_isPaused;
+ bool m_isFakeInsertionMode;
+
+ // FIXME: InsertionModes should be a separate object to prevent direct
+ // manipulation of these variables. For now, be careful to always use
+ // setInsertionMode and never set m_insertionMode directly.
+ InsertionMode m_insertionMode;
+ InsertionMode m_originalInsertionMode;
+
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#pending-table-character-tokens
+ Vector<UChar> m_pendingTableCharacters;
+
+ // 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;
+
+ RefPtr<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser.
+ TextPosition1 m_scriptToProcessStartPosition; // Starting line number of the script tag needing processing.
+
+ // FIXME: We probably want to remove this member. Originally, it was
+ // created to service the legacy tree builder, but it seems to be used for
+ // some other things now.
+ TextPosition0 m_lastScriptElementStartPosition;
+
+ bool m_usePreHTML5ParserQuirks;
+
+ bool m_hasPendingForeignInsertionModeSteps;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/HTMLViewSourceParser.cpp b/Source/WebCore/html/parser/HTMLViewSourceParser.cpp
new file mode 100644
index 0000000..ace8590
--- /dev/null
+++ b/Source/WebCore/html/parser/HTMLViewSourceParser.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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"
+#include "HTMLViewSourceDocument.h"
+
+namespace WebCore {
+
+HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument* document)
+ : DecodedDataDocumentParser(document)
+ , m_tokenizer(HTMLTokenizer::create(HTMLDocumentParser::usePreHTML5ParserQuirks(document)))
+{
+}
+
+HTMLViewSourceParser::~HTMLViewSourceParser()
+{
+}
+
+void HTMLViewSourceParser::insert(const SegmentedString&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void HTMLViewSourceParser::pumpTokenizer()
+{
+ while (m_tokenizer->nextToken(m_input.current(), m_token)) {
+ m_token.end(m_input.current().numberOfCharactersConsumed());
+ document()->addSource(sourceForToken(), m_token);
+ updateTokenizerState();
+ m_token.clear(m_input.current().numberOfCharactersConsumed());
+ }
+}
+
+void HTMLViewSourceParser::append(const SegmentedString& input)
+{
+ m_input.appendToEnd(input);
+ m_source.append(input);
+ pumpTokenizer();
+}
+
+String HTMLViewSourceParser::sourceForToken()
+{
+ if (m_token.type() == HTMLToken::EndOfFile)
+ return String();
+
+ ASSERT(m_source.numberOfCharactersConsumed() == m_token.startIndex());
+ UChar* data = 0;
+ int length = m_token.endIndex() - m_token.startIndex();
+ String source = String::createUninitialized(length, data);
+ for (int i = 0; i < length; ++i) {
+ data[i] = *m_source;
+ m_source.advance();
+ }
+ return source;
+}
+
+void HTMLViewSourceParser::updateTokenizerState()
+{
+ // FIXME: The tokenizer should do this work for us.
+ if (m_token.type() != HTMLToken::StartTag)
+ return;
+
+ AtomicString tagName(m_token.name().data(), m_token.name().size());
+ m_tokenizer->updateStateFor(tagName, document()->frame());
+}
+
+void HTMLViewSourceParser::finish()
+{
+ if (!m_input.haveSeenEndOfFile())
+ m_input.markEndOfFile();
+ pumpTokenizer();
+ document()->finishedParsing();
+}
+
+bool HTMLViewSourceParser::finishWasCalled()
+{
+ return m_input.haveSeenEndOfFile();
+}
+
+}
diff --git a/Source/WebCore/html/parser/HTMLViewSourceParser.h b/Source/WebCore/html/parser/HTMLViewSourceParser.h
new file mode 100644
index 0000000..abe55b4
--- /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 "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&);
+ virtual void append(const SegmentedString&);
+ virtual void finish();
+ virtual bool finishWasCalled();
+
+ HTMLViewSourceDocument* document() const { return static_cast<HTMLViewSourceDocument*>(DecodedDataDocumentParser::document()); }
+
+ void pumpTokenizer();
+ String sourceForToken();
+ void updateTokenizerState();
+
+ HTMLInputStream m_input;
+ SegmentedString m_source;
+ HTMLToken m_token;
+ OwnPtr<HTMLTokenizer> m_tokenizer;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/NestingLevelIncrementer.h b/Source/WebCore/html/parser/NestingLevelIncrementer.h
new file mode 100644
index 0000000..c597876
--- /dev/null
+++ b/Source/WebCore/html/parser/NestingLevelIncrementer.h
@@ -0,0 +1,50 @@
+/*
+ * 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 NestingLevelIncrementer_h
+#define NestingLevelIncrementer_h
+
+namespace WebCore {
+
+class NestingLevelIncrementer : public Noncopyable {
+public:
+ explicit NestingLevelIncrementer(unsigned& nestingLevel)
+ : m_nestingLevel(&nestingLevel)
+ {
+ ++(*m_nestingLevel);
+ }
+
+ ~NestingLevelIncrementer()
+ {
+ --(*m_nestingLevel);
+ }
+
+private:
+ unsigned* m_nestingLevel;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/TextDocumentParser.cpp b/Source/WebCore/html/parser/TextDocumentParser.cpp
new file mode 100644
index 0000000..d03b744
--- /dev/null
+++ b/Source/WebCore/html/parser/TextDocumentParser.cpp
@@ -0,0 +1,72 @@
+/*
+ * 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 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 "TextDocumentParser.h"
+
+#include "HTMLDocument.h"
+#include "HTMLNames.h"
+#include "HTMLTokenizer.h"
+#include "HTMLTreeBuilder.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+TextDocumentParser::TextDocumentParser(HTMLDocument* document)
+ : HTMLDocumentParser(document, false)
+ , m_haveInsertedFakePreElement(false)
+{
+ tokenizer()->setState(HTMLTokenizer::PLAINTEXTState);
+}
+
+TextDocumentParser::~TextDocumentParser()
+{
+}
+
+void TextDocumentParser::append(const SegmentedString& text)
+{
+ if (!m_haveInsertedFakePreElement)
+ insertFakePreElement();
+ HTMLDocumentParser::append(text);
+}
+
+void TextDocumentParser::insertFakePreElement()
+{
+ // In principle, we should create a specialized tree builder for
+ // TextDocuments, but instead we re-use the existing HTMLTreeBuilder.
+ // We create a fake token and give it to the tree builder rather than
+ // sending fake bytes through the front-end of the parser to avoid
+ // distrubing the line/column number calculations.
+
+ RefPtr<Attribute> styleAttribute = Attribute::createMapped("style", "word-wrap: break-word; white-space: pre-wrap;");
+ RefPtr<NamedNodeMap> attributes = NamedNodeMap::create();
+ attributes->insertAttribute(styleAttribute.release(), false);
+ AtomicHTMLToken fakePre(HTMLToken::StartTag, preTag.localName(), attributes.release());
+
+ treeBuilder()->constructTreeFromAtomicToken(fakePre);
+ m_haveInsertedFakePreElement = true;
+}
+
+}
diff --git a/Source/WebCore/html/parser/TextDocumentParser.h b/Source/WebCore/html/parser/TextDocumentParser.h
new file mode 100644
index 0000000..1cccc5b
--- /dev/null
+++ b/Source/WebCore/html/parser/TextDocumentParser.h
@@ -0,0 +1,52 @@
+/*
+ * 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 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 TextDocumentParser_h
+#define TextDocumentParser_h
+
+#include "HTMLDocumentParser.h"
+
+namespace WebCore {
+
+class TextDocumentParser : public HTMLDocumentParser {
+public:
+ static PassRefPtr<TextDocumentParser> create(HTMLDocument* document)
+ {
+ return adoptRef(new TextDocumentParser(document));
+ }
+ virtual ~TextDocumentParser();
+
+private:
+ explicit TextDocumentParser(HTMLDocument*);
+
+ virtual void append(const SegmentedString&);
+ void insertFakePreElement();
+
+ bool m_haveInsertedFakePreElement;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/TextViewSourceParser.cpp b/Source/WebCore/html/parser/TextViewSourceParser.cpp
new file mode 100644
index 0000000..d7e6e3d
--- /dev/null
+++ b/Source/WebCore/html/parser/TextViewSourceParser.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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 "TextViewSourceParser.h"
+
+#include "HTMLTokenizer.h"
+
+namespace WebCore {
+
+TextViewSourceParser::TextViewSourceParser(HTMLViewSourceDocument* document)
+ : HTMLViewSourceParser(document)
+{
+ tokenizer()->setState(HTMLTokenizer::PLAINTEXTState);
+}
+
+TextViewSourceParser::~TextViewSourceParser()
+{
+}
+
+}
diff --git a/Source/WebCore/html/parser/TextViewSourceParser.h b/Source/WebCore/html/parser/TextViewSourceParser.h
new file mode 100644
index 0000000..e4170ed
--- /dev/null
+++ b/Source/WebCore/html/parser/TextViewSourceParser.h
@@ -0,0 +1,47 @@
+/*
+ * 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 TextViewSourceParser_h
+#define TextViewSourceParser_h
+
+#include "HTMLViewSourceParser.h"
+
+namespace WebCore {
+
+class TextViewSourceParser : public HTMLViewSourceParser {
+public:
+ static PassRefPtr<TextViewSourceParser> create(HTMLViewSourceDocument* document)
+ {
+ return adoptRef(new TextViewSourceParser(document));
+ }
+ virtual ~TextViewSourceParser();
+
+private:
+ explicit TextViewSourceParser(HTMLViewSourceDocument*);
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/parser/create-html-entity-table b/Source/WebCore/html/parser/create-html-entity-table
new file mode 100755
index 0000000..e6132bc
--- /dev/null
+++ b/Source/WebCore/html/parser/create-html-entity-table
@@ -0,0 +1,178 @@
+#!/usr/bin/env python
+# 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:
+#
+# * 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.
+
+import csv
+import os.path
+import string
+import sys
+
+ENTITY = 0
+VALUE = 1
+
+def convert_entity_to_cpp_name(entity):
+ postfix = "EntityName"
+ if entity[-1] == ";":
+ return "%sSemicolon%s" % (entity[:-1], postfix)
+ return "%s%s" % (entity, postfix)
+
+
+def convert_entity_to_uchar_array(entity):
+ return "{'%s'}" % "', '".join(entity)
+
+
+def convert_value_to_int(value):
+ assert(value[0] == "U")
+ assert(value[1] == "+")
+ return "0x" + value[2:]
+
+
+def offset_table_entry(offset):
+ return " &staticEntityTable[%s]," % offset
+
+
+program_name = os.path.basename(__file__)
+if len(sys.argv) < 4 or sys.argv[1] != "-o":
+ print >> sys.stderr, "Usage: %s -o OUTPUT_FILE INPUT_FILE" % program_name
+ exit(1)
+
+output_path = sys.argv[2]
+input_path = sys.argv[3]
+
+html_entity_names_file = open(input_path)
+entries = list(csv.reader(html_entity_names_file))
+html_entity_names_file.close()
+
+entries.sort(lambda a, b: cmp(a[ENTITY], b[ENTITY]))
+entity_count = len(entries)
+
+output_file = open(output_path, "w")
+
+print >> output_file, """/*
+ * 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.
+ */
+
+// THIS FILE IS GENERATED BY WebCore/html/parser/create-html-entity-table
+// DO NOT EDIT (unless you are a ninja)!
+
+#include "config.h"
+#include "HTMLEntityTable.h"
+
+namespace WebCore {
+
+namespace {
+"""
+
+for entry in entries:
+ print >> output_file, "const UChar %sEntityName[] = %s;" % (
+ convert_entity_to_cpp_name(entry[ENTITY]),
+ convert_entity_to_uchar_array(entry[ENTITY]))
+
+print >> output_file, """
+HTMLEntityTableEntry staticEntityTable[%s] = {""" % entity_count
+
+index = {}
+offset = 0
+for entry in entries:
+ letter = entry[ENTITY][0]
+ if not index.get(letter):
+ index[letter] = offset
+ print >> output_file, ' { %sEntityName, %s, %s },' % (
+ convert_entity_to_cpp_name(entry[ENTITY]),
+ len(entry[ENTITY]),
+ convert_value_to_int(entry[VALUE]))
+ offset += 1
+
+print >> output_file, """};
+"""
+
+print >> output_file, "const HTMLEntityTableEntry* uppercaseOffset[] = {"
+for letter in string.uppercase:
+ print >> output_file, offset_table_entry(index[letter])
+print >> output_file, offset_table_entry(index['a'])
+print >> output_file, """};
+
+const HTMLEntityTableEntry* lowercaseOffset[] = {"""
+for letter in string.lowercase:
+ print >> output_file, offset_table_entry(index[letter])
+print >> output_file, offset_table_entry(entity_count)
+print >> output_file, """};
+
+}
+
+const HTMLEntityTableEntry* HTMLEntityTable::firstEntryStartingWith(UChar c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return uppercaseOffset[c - 'A'];
+ if (c >= 'a' && c <= 'z')
+ return lowercaseOffset[c - 'a'];
+ return 0;
+}
+
+const HTMLEntityTableEntry* HTMLEntityTable::lastEntryStartingWith(UChar c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return uppercaseOffset[c - 'A' + 1] - 1;
+ if (c >= 'a' && c <= 'z')
+ return lowercaseOffset[c - 'a' + 1] - 1;
+ return 0;
+}
+
+const HTMLEntityTableEntry* HTMLEntityTable::firstEntry()
+{
+ return &staticEntityTable[0];
+}
+
+const HTMLEntityTableEntry* HTMLEntityTable::lastEntry()
+{
+ return &staticEntityTable[%s - 1];
+}
+
+}
+""" % entity_count
diff --git a/Source/WebCore/html/shadow/SliderThumbElement.cpp b/Source/WebCore/html/shadow/SliderThumbElement.cpp
new file mode 100644
index 0000000..d29d257
--- /dev/null
+++ b/Source/WebCore/html/shadow/SliderThumbElement.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 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 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 "SliderThumbElement.h"
+
+#include "Event.h"
+#include "Frame.h"
+#include "MouseEvent.h"
+#include "RenderSlider.h"
+
+#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
+#include "TouchEvent.h"
+#endif
+
+namespace WebCore {
+
+void SliderThumbElement::defaultEventHandler(Event* event)
+{
+ if (!event->isMouseEvent()
+#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
+ && !event->isTouchEvent()
+#endif
+ ) {
+ ShadowBlockElement::defaultEventHandler(event);
+ return;
+ }
+
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ bool isLeftButton = mouseEvent->button() == LeftButton;
+ const AtomicString& eventType = event->type();
+
+ if (eventType == eventNames().mousedownEvent && isLeftButton
+#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
+ || eventType == eventNames().touchstartEvent
+#endif
+ ) {
+ if (document()->frame() && renderer()) {
+ RenderSlider* slider = toRenderSlider(renderer()->parent());
+ if (slider) {
+ if (slider->mouseEventIsInThumb(mouseEvent)) {
+ // We selected the thumb, we want the cursor to always stay at
+ // the same position relative to the thumb.
+ m_offsetToThumb = slider->mouseEventOffsetToThumb(mouseEvent);
+ } else {
+ // We are outside the thumb, move the thumb to the point were
+ // we clicked. We'll be exactly at the center of the thumb.
+ m_offsetToThumb.setX(0);
+ m_offsetToThumb.setY(0);
+ }
+
+ m_inDragMode = true;
+ document()->frame()->eventHandler()->setCapturingMouseEventsNode(shadowHost());
+ event->setDefaultHandled();
+ return;
+ }
+ }
+ } else if (eventType == eventNames().mouseupEvent && isLeftButton
+#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
+ || eventType == eventNames().touchendEvent
+#endif
+ ) {
+ if (m_inDragMode) {
+ if (Frame* frame = document()->frame())
+ frame->eventHandler()->setCapturingMouseEventsNode(0);
+ m_inDragMode = false;
+ event->setDefaultHandled();
+ return;
+ }
+ } else if (eventType == eventNames().mousemoveEvent
+#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
+ || eventType == eventNames().touchmoveEvent
+#endif
+ ) {
+ if (m_inDragMode && renderer() && renderer()->parent()) {
+ RenderSlider* slider = toRenderSlider(renderer()->parent());
+ if (slider) {
+ FloatPoint curPoint = slider->absoluteToLocal(mouseEvent->absoluteLocation(), false, true);
+#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
+ // Update the position when it is a touch event
+ if (event->isTouchEvent()) {
+ TouchEvent* touchEvent = static_cast<TouchEvent*>(event);
+ if (touchEvent && touchEvent->touches() && touchEvent->touches()->item(0)) {
+ curPoint.setX(touchEvent->touches()->item(0)->pageX());
+ curPoint.setY(touchEvent->touches()->item(0)->pageY());
+ curPoint = slider->absoluteToLocal(curPoint, false, true);
+ }
+ }
+ // Tell the webview that webkit will handle the following move events
+ event->setDefaultPrevented(true);
+#endif
+ IntPoint eventOffset(curPoint.x() + m_offsetToThumb.x(), curPoint.y() + m_offsetToThumb.y());
+ slider->setValueForPosition(slider->positionForOffset(eventOffset));
+ event->setDefaultHandled();
+ return;
+ }
+ }
+ }
+
+ ShadowBlockElement::defaultEventHandler(event);
+}
+
+void SliderThumbElement::detach()
+{
+ if (m_inDragMode) {
+ if (Frame* frame = document()->frame())
+ frame->eventHandler()->setCapturingMouseEventsNode(0);
+ }
+ ShadowBlockElement::detach();
+}
+
+}
+
diff --git a/Source/WebCore/html/shadow/SliderThumbElement.h b/Source/WebCore/html/shadow/SliderThumbElement.h
new file mode 100644
index 0000000..8205746
--- /dev/null
+++ b/Source/WebCore/html/shadow/SliderThumbElement.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 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 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 SliderThumbElement_h
+#define SliderThumbElement_h
+
+#include "FloatPoint.h"
+#include "ShadowElement.h"
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class HTMLElement;
+class Event;
+class FloatPoint;
+
+class SliderThumbElement : public ShadowBlockElement {
+public:
+ static PassRefPtr<SliderThumbElement> create(HTMLElement* shadowParent);
+
+ bool inDragMode() const { return m_inDragMode; }
+
+ virtual void defaultEventHandler(Event*);
+ virtual void detach();
+
+private:
+ SliderThumbElement(HTMLElement* shadowParent);
+
+ FloatPoint m_offsetToThumb;
+ bool m_inDragMode;
+};
+
+inline SliderThumbElement::SliderThumbElement(HTMLElement* shadowParent)
+ : ShadowBlockElement(shadowParent)
+ , m_inDragMode(false)
+{
+}
+
+inline PassRefPtr<SliderThumbElement> SliderThumbElement::create(HTMLElement* shadowParent)
+{
+ return adoptRef(new SliderThumbElement(shadowParent));
+}
+
+}
+
+
+#endif